var StockModule = angular.module("StockModule", []);

StockModule.config([
	"$routeProvider",
	function ($routeProvider) {
		$routeProvider.when("/stock/", {
			controller: "StockMainCtrl",
			templateUrl: "stock/overview.html"
		});

		$routeProvider.when("/stock/new/", {
			controller: "StockNewCtrl",
			templateUrl: "stock/new.html"
		});

		$routeProvider.when("/stock/edit/:stockId", {
			controller: "StockNewCtrl",
			templateUrl: "stock/new.html"
		});

		$routeProvider.when("/stock/browse/", {
			controller: "StockBrowseCtrl",
			templateUrl: "stock/browse.html"
		});

		$routeProvider.when("/stock/categories/", {
			controller: "StockCategoriesCtrl",
			templateUrl: "stock/categories.html"
		});

		$routeProvider.when("/stock/categories/:categoryId", {
			controller: "StockCategoriesCtrl",
			templateUrl: "stock/categories.html"
		});

		$routeProvider.when("/stock/suppliers/", {
			controller: "StockSuppliersCtrl",
			templateUrl: "stock/suppliers.html"
		});

		$routeProvider.when("/stock/suppliers/:supplierId", {
			controller: "StockSuppliersCtrl",
			templateUrl: "stock/suppliers.html"
		});

		$routeProvider.when("/stock/order-summary/:orderId", {
			controller: "PurchaseOrderCtrl",
			templateUrl: "stock/order.html"
		});

		$routeProvider.when("/stock/orders/", {
			controller: "StockOrdersCtrl",
			templateUrl: "stock/orders.html"
		});

		$routeProvider.when("/stock/new_order/", {
			controller: "StockNewOrderCtrl",
			templateUrl: "stock/new_order.html"
		});

		$routeProvider.when("/stock/parts_on_order/", {
			controller: "PartsOnOrderCtrl",
			templateUrl: "stock/parts_on_order.html"
		});

		$routeProvider.when("/stock/staff_allocated/", {
			controller: "StaffAllocatedCtrl",
			templateUrl: "stock/staff_allocated.html"
		});

		$routeProvider.when("/stock/stock_takes/", {
			templateUrl: "stock/stock_takes.html"
		});

		$routeProvider.when("/stock/stock_reports/", {
			controller: "StockReportsCtrl",
			templateUrl: "stock/stock_reports.html"
		});

		$routeProvider.when("/stock/order_list/", {
			templateUrl: "stock/order_list.html",
			controller: "StockOrderListCtrl",
			controllerAs: "vm"
		});
	}
]);

// ------------------------------------------------------------------------
//
//	RESOURCES BELOW -->
//
// ------------------------------------------------------------------------

StockModule.factory("Stock", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var Stock = $resource(
			apiUrl("stock/:stockId"),
			{ stockId: "@id" },
			methods
		);
		Stock.getSearchUrl = function () {
			return apiUrl("stock?query=");
		};
		angular.extend(Stock.prototype, _prototype);
		return Stock;
	}
]);

StockModule.factory("StockItem", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var StockItem = $resource(
			apiUrl("stockitems/:stockItemId"),
			{ stockItemId: "@id" },
			methods
		);
		StockItem.getSearchUrl = function () {
			return apiUrl("stockitems?query=");
		};
		angular.extend(StockItem.prototype, _prototype);
		return StockItem;
	}
]);

StockModule.factory("StockGroup", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var StockGroup = $resource(
			apiUrl("stockgroups/:stockGroupId"),
			{ stockGroupId: "@id" },
			methods
		);
		angular.extend(StockGroup.prototype, _prototype);
		return StockGroup;
	}
]);

StockModule.factory("Supplier", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var Supplier = $resource(
			apiUrl("suppliers/:supplierId"),
			{ supplierId: "@id" },
			methods
		);
		angular.extend(Supplier.prototype, _prototype);
		return Supplier;
	}
]);
StockModule.factory("Payment", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var Payment = $resource(
			apiUrl("payments/:PaymentId"),
			{ PaymentId: "@id" },
			methods
		);
		angular.extend(Payment.prototype, _prototype);
		return Payment;
	}
]);

StockModule.factory("PurchaseOrder", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var PurchaseOrder = $resource(
			apiUrl("orders/:orderId"),
			{ orderId: "@id" },
			methods
		);
		angular.extend(PurchaseOrder.prototype, _prototype);
		return PurchaseOrder;
	}
]);

StockModule.factory("PurchaseOrderItem", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var PurchaseOrderItem = $resource(
			apiUrl("orders/items/:itemId"),
			{ itemId: "@id" },
			methods
		);
		angular.extend(PurchaseOrderItem.prototype, _prototype);
		return PurchaseOrderItem;
	}
]);

StockModule.factory("StockTransaction", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var StockTransaction = $resource(
			apiUrl("transactions/:transactionId"),
			{ transactionId: "@id" },
			methods
		);
		angular.extend(StockTransaction.prototype, _prototype);
		return StockTransaction;
	}
]);

StockModule.factory("StockReport", [
	"apiUrl",
	"$resource",
	"ResourceMethods",
	"ResourcePrototype",
	function (apiUrl, $resource, methods, _prototype) {
		var StockReport = $resource(
			apiUrl("stock_reports/:stockReportId"),
			{ stockReportId: "@id" },
			methods
		);
		angular.extend(StockReport.prototype, _prototype);
		return StockReport;
	}
]);

StockModule.controller('ItemOrdersCtrl', ['$scope', 'PurchaseOrderItem', 'ErrorsHandler', '$uibModalInstance', 'suppliers', 'stockItem', '$paginator', function ($scope, PurchaseOrderItem, ErrorsHandler, $uibModalInstance, suppliers, stockItem, $paginator) {

	$scope.product = stockItem;

	$scope.suppliers = suppliers;

	$scope.previousOrders = [];

	$scope.filters = {
		supplier_id: null
	};



	//Pagination variables
	$scope.paginator = $paginator;
	$paginator = angular.copy($paginator);
	$scope.paginator = $paginator;
	$paginator.setLimit(10);

	$scope.$watch('filters.supplier_id', function (newValue, oldValue) {
		if (newValue !== oldValue)
			$scope.loadPreviousOrders();
	});


	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$paginator.setOnPageChange(function (page) {

		$scope.loadPreviousOrders(page);

	});


	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW -->
	//
	// ------------------------------------------------------------------------


	$scope.cancel = function () {
		$uibModalInstance.dismiss('cancel');
	};

	$scope.loadPreviousOrders = function (page) {

		var parameters = {
			page: page,
			limit: 10,
			stock_id: $scope.product.id,
			supplier_id: $scope.filters.supplier_id
		};

		PurchaseOrderItem.get(parameters, function (response) {
			$scope.previousOrders = response.data;
			$paginator.setFromResponse(response);
		});
	};
	$scope.loadPreviousOrders();


}]);
StockModule.controller('ItemTransactionsCtrl', ['$scope', 'StockTransaction', 'ErrorsHandler', '$uibModalInstance', 'stockItem', '$paginator', 'User', 'related_type', 'related_id', function ($scope, StockTransaction, ErrorsHandler, $uibModalInstance, stockItem, $paginator, User, related_type, related_id) {

	$scope.product = stockItem;


	$scope.fixedRelatedType = related_type ? true : false;

	$scope.transaction_types = [
		{ name: 'Task', value: 'task' },
		{ name: 'Invoice', value: 'invoice' },
		{ name: 'Sale', value: 'sale' },
		{ name: 'Purchase Order', value: 'purchase_order' },
		{ name: 'Custom', value: 'custom' },
		{ name: 'User', value: 'user' }
	];

	$scope.transactions = [];

	$scope.filters = {
		transaction_type: null
	};

	User.get({ active: true, limit: 50 }, function (response) {
		$scope.users = response.data;
	});

	User.get({}, function (response) {
		$scope.users = response.data;
	});


	//Pagination variables
	$scope.paginator = $paginator;
	$paginator = angular.copy($paginator);
	$scope.paginator = $paginator;
	$paginator.setLimit(10);

	$scope.$watch('filters.transaction_type', function (newValue, oldValue) {
		if (newValue !== oldValue)
			$scope.loadTransactions();
	});


	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$paginator.setOnPageChange(function (page) {

		$scope.loadTransactions(page);

	});


	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.getTransactionType = function (value) {
		var type = _.find($scope.transaction_types, function (item) {
			return item.value === value;
		});

		return type ? type.name : '';
	};

	$scope.getUserName = function (id) {
		var user = _.find($scope.users, function (item) {
			return item.id === id;
		});

		return user ? user.name : '';
	};

	$scope.cancel = function () {
		$uibModalInstance.dismiss('cancel');
	};

	$scope.loadTransactions = function (page) {

		var parameters = {
			page: page,
			limit: 10,
			stock_id: $scope.product.id,
			related_type: related_type ? related_type : $scope.filters.transaction_type,
			related_id: related_id ? related_id : null
		};

		StockTransaction.get(parameters, function (response) {
			$scope.transactions = response.data;
			$paginator.setFromResponse(response);
		});
	};

	$scope.loadTransactions();


}]);
StockModule.controller('ManualUpdateStockTransactionModalCtrl', ['$scope', 'StockTransaction', 'ErrorsHandler', '$uibModalInstance', 'product', 'User', function ($scope, StockTransaction, ErrorsHandler, $uibModalInstance, product, User) {

	$scope.loading = false;

	$scope.product = product;
	$scope.transaction = {
		quantity: 1,
		reason: null,
		stock_id: $scope.product.id,
		related_type: "custom",
		related_id: null,
		type: "1"
	};

	$scope.save = function () {

		if ($scope.transaction.quantity < 1) {
			alert("The quantity has to be at least 1.");
			return;
		}

		$scope.loading = true;

		var params = {
			quantity: $scope.transaction.quantity * $scope.transaction.type,
			reason: $scope.transaction.reason,
			stock_id: $scope.transaction.stock_id,
			related_type: $scope.transaction.related_type,
			related_id: null,
		};

		StockTransaction.save(params, function (response) {
			$scope.loading = false;
			$uibModalInstance.close(params.quantity);
		}, function (a, b) {
			$scope.loading = false;
			ErrorsHandler(a, b);
		});

	};

	$scope.cancel = function () {
		$uibModalInstance.dismiss('cancel');
	};


}]);
/**
 * Stock Suppliers Controller
 */
StockModule.controller('PartsOnOrderCtrl', ['$scope', '$paginator', 'ErrorsHandler', 'Messenger', '$timeout', 'Part', 'Build', 'User', function ($scope, $paginator, ErrorsHandler, Messenger, $timeout, Part, Build, User) {


	var search_timeout = 200;
	var searchTimer;

	// ------------------------------------------------------------------------
	//
	//	SCOPE VARIABLES BELOW -->
	//
	// ------------------------------------------------------------------------


	$scope.parts = [];
	$scope.loading = true;

	$scope.paginator = $paginator;
	$paginator = angular.copy($paginator);
	$scope.paginator = $paginator;
	$paginator.setLimit(50);

	console.info('Limit: ', $paginator.getLimit());

	$scope.partsFilters = {
		search: null,
		status: null
	};

	$scope.buildsFilters = {
		search: null,
		status: null
	};

	User.get({ active: true }, function (response) {
		$scope.users = response.data;
	});

	// Used when creating the url to the task
	$scope.resources = {
		'repair': 'repairs',
		'support': 'suport',
		'onsite': 'onsites',
		'order': 'orders',
	};

	$scope.statuses = [
		{ value: null, text: 'All statuses' },
		{ value: 1, text: 'In Stock' },
		{ value: 0, text: 'Non in Stock' },
	];

	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		$scope.initData();
	});

	$scope.initData = function () {
		$scope.loadParts();
		$scope.loadBuilds();
	};


	$scope.$watch('partsFilters.search', function (newValue, oldValue) {
		if (newValue === oldValue)
			return;

		$timeout.cancel(searchTimer);

		searchTimer = $timeout(function () {
			$scope.loadParts();
		}, search_timeout);
	});

	$scope.$watch('buildsFilters.search', function (newValue, oldValue) {
		if (newValue === oldValue)
			return;

		$timeout.cancel(searchTimer);

		searchTimer = $timeout(function () {
			$scope.loadBuilds();
		}, search_timeout);
	});

	$scope.relatedTo = function (item) {
		switch (item.related_type) {
			case 'task':
				return "<a href='/tasks/" + $scope.resources[item.related.type] + "/" + item.related_id + "'>" + item.related_id + "</a>";

			case 'user':
				return item.related.name;

			case 'client':
				return item.related.name;
		}

	};

	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	$scope.loadParts = function () {
		$scope.loading = true;

		Part.get({ query: $scope.partsFilters.search, limit: $paginator.getLimit(), on_order: true, related: true }, function (res) {
			$scope.parts = res.data;
			$scope.loading = false;
		}, ErrorsHandler);
	};

	$scope.loadBuilds = function () {
		$scope.loading = true;

		Build.get({ query: $scope.buildsFilters.search, on_order: true, related: true }, function (res) {
			$scope.builds = res.data;
			$scope.loading = false;
		}, ErrorsHandler);
	};

	$scope.getUserName = function (userId) {
		var user = _.find($scope.users, function (el) { return el.id == userId; });
		return user ? user.name : 'No one';
	};

	// Update the quantity received of a part
	$scope.assignStockToPart = function (part, quantity) {

		if (part.stock.unlimited == 0 && (quantity > part.stock.quantity || quantity > part.quantity_on_order))
			return;

		var parameters = {
			id: part.id,
			stock_id: part.stock_id,
			quantity_received: quantity
		};

		Part.received(parameters, function (response) {
			Messenger("The part has been marked as received.");
			$scope.loadParts();
		}, ErrorsHandler);
	}

	//Update the quantity received of a composite part item.
	$scope.assignStockToComponent = function (stockItem, quantity) {


		if (stockItem.unlimited == 0 && (quantity > stockItem.quantity || quantity > stockItem.pivot.quantity))
			return;

		var parameters = {
			id: stockItem.pivot.build_id,
			stock_id: stockItem.id,
			quantity_received: quantity
		};

		Build.received(parameters, function (response) {
			Messenger("The component has been marked as received.");
			$scope.loadBuilds();
		}, ErrorsHandler);
	}

}]);

StockModule.controller("PaymentModalCtrl", [
	"$scope",
	"Payment",
	"ErrorsHandler",
	"$uibModalInstance",
	"item",
	function ($scope, Payment, ErrorsHandler, $uibModalInstance, item) {
		$scope.data = item;

		$scope.save = function () {
			if (item.id) {
				Payment.update(
					$scope.data,
					function (response) {
						$uibModalInstance.close(response);
					},
					ErrorsHandler
				);
			} else {
				Payment.save(
					$scope.data,
					function (response) {
						$uibModalInstance.close(response);
					},
					ErrorsHandler
				);
			}
		};

		$scope.cancel = function () {
			$uibModalInstance.dismiss("cancel");
		};
	}
]);

StockModule.controller('PurchaseOrderCtrl', ['$scope', 'Supplier', 'Stock', '$paginator', '$routeParams', 'ErrorsHandler', '$uibModal', '$location', 'PurchaseOrder', '$routeParams', 'PurchaseOrderItem', '$uibModal', 'Messenger', 'Status', function ($scope, Supplier, Stock, $paginator, $routeParams, ErrorsHandler, $moda, $location, PurchaseOrder, $routeParams, PurchaseOrderItem, $uibModal, Messenger, Status) {


	//Init paginator and limit variables
	$paginator = angular.copy($paginator);
	$scope.paginator = $paginator;
	$scope.limit = 10; $paginator.setLimit(10);
	$scope.loading = true;

	$scope.order = {};

	Supplier.get(null, function (response) {
		$scope.suppliers = response.data;
	});
	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		$scope.loadOrder();
	});

	$paginator.setOnPageChange(function (page) {
		$scope.loadOrder(page);
	});

	$paginator.setOnLimitChange(function (page, limit) {
		$scope.loadOrder(page);
	});

	Status.get({ for: 'orders' }, function (response) {
		$scope.statuses = response;
	});

	$scope.loadOrder = function (page) {
		PurchaseOrder.get({ orderId: $routeParams.orderId, limit: $scope.limit, page: page }, function (response) {
			$scope.order = response;
			angular.forEach($scope.order.items, function (item) {
				item.received = item.received_quantity;
				item.refused = item.refused_quantity;
			});

			$scope.loading = false;
		});
	}


	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ----------------------------------------------------------------------

	// Get the item modified. If the recevied items number has been modified, ask for serial numbers.
	//Don't let to reduce number or received items or refused items.
	$scope.receive = function (item) {
		$scope.errorMessage = null;

		if (item.received < item.received_quantity) {
			item.received = item.received_quantity;
			$scope.errorMessage = 'It is not possible to reduce the number of received items for product ' + item.stock.name + '.';
			return;
		}

		if (item.received + item.refused_quantity > item.quantity) {
			item.received = item.received_quantity;
			$scope.errorMessage = 'The received items and refused items can not be higher than the total items ordered for product ' + item.stock.name + '.';
			return;
		}

		//Open a pop up to ask for serial numbers
		var modalInstance = $uibModal.open(
			{
				templateUrl: 'stock/order_items_serials.html',
				controller: 'PurchaseOrderItemModalCtrl',
				resolve: {
					item: function () {
						return item;
					}
				}
			});

		modalInstance.result.then(function (_item) {
			item.received_quantity = _item.received_quantity;
			item.received = item.received_quantity;
			Messenger("Item serials saved successfully!");

		}, function () {

			item.received = item.received_quantity;
		});

	};

	$scope.refuse = function (item) {

		$scope.errorMessage = null;

		if (item.refused < item.refused_quantity) {
			item.refused = item.refused_quantity;
			$scope.errorMessage = 'It is not possible to reduce the number of refused items for product ' + item.stock.name + '.';
			return;
		}

		if (item.refused + item.received_quantity > item.quantity) {
			item.received = item.received_quantity;
			$scope.errorMessage = 'The received items and refused items can not be higher than the total items ordered for product ' + item.stock.name + '.';
			return;
		}

		$scope.kashflow_loading = true;
		PurchaseOrderItem.update({ id: item.id, refused_quantity: item.refused }, function (response) {

			$scope.kashflow_loading = false;
			Messenger("The item has been updated successfully!");
			$scope.loadOrder();

		}, function (error) {
			$scope.kashflow_loading = false;
			item.refused = item.refused_quantity;
			ErrorsHandler(error);
		});


	};


	$scope.updateOrder = function (order) {
		angular.extend($scope.order, order);

		PurchaseOrder.update($scope.order, function (response) {
			$scope.order = response;
			angular.forEach($scope.order.items, function (item) {
				item.received = item.received_quantity;
				item.refused = item.refused_quantity;
			});

			$scope.loading = false;
		});
	};

	$scope.updateItem = function (item) {
		PurchaseOrderItem.update(item, function (response) {
			$scope.loadOrder();
		});
	};

}]);
StockModule.controller('PurchaseOrderItemModalCtrl', ['$scope', 'ErrorsHandler', '$uibModalInstance', 'PurchaseOrderItem', 'item', function ($scope, ErrorsHandler, $uibModalInstance, PurchaseOrderItem, item) {

	$scope.loading = false;
	$scope.item = item;
	$scope.serials = [];
	$scope.errorMessage = false;
	$scope.data = {
		sn_na: true
	};
	// $scope.order = {};

	for (var i = 0; i < $scope.item.received - $scope.item.received_quantity; i++) {
		$scope.serials.push({ purchase_order_item_id: item.id, serial_number: null, added: false });
	}

	$scope.save = function () {
		$scope.loading = true;
		var serials = $scope.pendingSerials();

		PurchaseOrderItem.update({ id: item.id, serials: serials, sn_na: $scope.data.sn_na, received_quantity: $scope.item.received }, function (response) {
			$scope.item.received_quantity = response['item'].received_quantity;
			$scope.loading = false;
			if (response['added_all'])
				$uibModalInstance.close(response['item']);
			else {
				$scope.errorMessage = true;
				$scope.serials = response['serials'];
			}

		}, ErrorsHandler);
	};

	$scope.cancel = function () {
		$uibModalInstance.dismiss('cancel');
	};

	$scope.valid = function () {
		if ($scope.data.sn_na)
			return true;

		var valid = true;
		angular.forEach($scope.serials, function (serial) {
			if (!serial.serial_number)
				valid = false;

		});
		return valid;
	}

	// Return an array with the serials that have not been added to the DB yet.
	$scope.pendingSerials = function () {
		var serials = [];

		angular.forEach($scope.serials, function (item) {

			if (!item.added)
				serials.push(item);

		});

		return serials;
	}
}]);
StockModule.controller('StaffAllocatedCtrl', ['$scope', '$paginator', 'User', '$uibModal', function ($scope, $paginator, User, $uibModal) {

	$scope.loading = true;
	// ------------------------------------------------------------------------
	//
	//	SCOPE VARIABLES BELOW -->
	//
	// ------------------------------------------------------------------------

	$paginator = angular.copy($paginator);
	$scope.paginator = $paginator;

	User.get({ active: true, parts: true, limit: 50 }, function (response) {
		$scope.users = response.data;
		$scope.loading = false;
	});

	$scope.selectUser = function (user) {
		$scope.selectedUser = user;
	};
}]);
/**
 * Stock Browse Controller
 */

StockModule.controller('StockBrowseCtrl', ['$scope', 'Stock', '$timeout', '$paginator', 'ErrorsHandler', 'StockItem', 'Messenger', function ($scope, Stock, $timeout, $paginator, ErrorsHandler, StockItem, Messenger) {


	// ------------------------------------------------------------------------
	//
	//	SCOPE VARIABLES BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.products = [];
	$scope.search = '';
	$scope.paginator = $paginator;
	$scope.limit = 10; $paginator.setLimit(10);
	$scope.groups = [];
	$scope.types = [];
	$scope.suppliers = [];

	var search_timeout;
	var prod_timeouts = {};

	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		$scope.loadProducts();
	});

	$paginator.setOnPageChange(function (page) {
		$scope.loadProducts($scope.search, page);
	});

	$paginator.setOnLimitChange(function (page, limit) {
		$scope.loadProducts($scope.search, page);
	});

	$scope.$watch('limit', function (newValue, oldValue) {
		if (newValue !== oldValue)
			$paginator.setLimit($scope.limit);
	});

	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	$scope.loadProducts = function (query, page) {
		StockItem.get({ supplier: true, limit: $scope.limit, query: query, page: page }, function (res) {
			$scope.products = res.data;
			$paginator.setFromResponse(res);
		});
	};

	$scope.searchCallback = function (query) {
		$scope.search = query;
		$scope.loadProducts(query);
	};

	$scope.updateProduct = function (product) {
		if (prod_timeouts[product.id]) $timeout.cancel(prod_timeouts[product.id]);

		prod_timeouts[product.id] = $timeout(function () {
			StockItem.update(product, function (res) {
				Stock.update(product.stock, function (res) {
					Messenger('Item "' + product.stock.name + '" successfully updated!');
				}, ErrorsHandler);
			}, ErrorsHandler);
		}, 1500); // 1.5 seconds before the product is saved
	};

}]);
/**
 * Stock Categories Controller
 */

StockModule.controller('StockCategoriesCtrl', ['$scope', 'StockGroup', '$paginator', '$routeParams', 'ErrorsHandler', '$uibModal', '$http', 'apiUrl', 'Messenger', function ($scope, StockGroup, $paginator, $routeParams, ErrorsHandler, $uibModal, $http, apiUrl, Messenger) {


	// ------------------------------------------------------------------------
	//
	//	SCOPE VARIABLES BELOW -->
	//
	// ------------------------------------------------------------------------

	$paginator = angular.copy($paginator);
	$scope.categories = [];
	$scope.paginator = $paginator;

	// Removed unnecessary API call to kashflow/nominalcodesextended/Turnover
	// Removed unnecessary API call to kashflow/nominalcodesextended/Cost of Sale



	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		$scope.loadCategories();
	});

	$paginator.setOnPageChange(function (page) {
		$scope.loadCategories(page);
	});

	$paginator.setOnLimitChange(function (page, limit) {
		$scope.loadCategories(page);
	});


	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	$scope.loadCategories = function (page) {
		if (!page) page = 1;
		StockGroup.get({ page: page, limit: $paginator.getLimit() }, function (res) {
			$scope.categories = res.data;
			$paginator.setFromResponse(res);
		}, ErrorsHandler);
	};

	$scope.showModal = function (item) {
		var modalInstance = $uibModal.open({
			templateUrl: 'stock/categories/modal.html',
			controller: 'StockCategoryModalCtrl',
			resolve: {
				item: function () {
					return item || {};
				},
				kashflow_categories: function () {
					return []; // Removed kashflow categories API call
				},
				kashflow_purchase_categories: function () {
					return []; // Removed kashflow purchase categories API call
				}
			}
		});

		modalInstance.result.then(function (_item) {
			if (!item) {
				$scope.categories.push(_item);
			} else {
				angular.extend(item, _item || {});
			}

			Messenger("Changes made successfully!")
		});
	};

	$scope.delete = function (id) {
		StockGroup.remove({ stockGroupId: id }, function () {
			$scope.categories = _.reject($scope.categories, function (el) { return el.id == id; });
			Messenger("Category deleted successfully!");
		}, ErrorsHandler);
	};

	$scope.getKashflowCategoryName = function (id) {
		// Removed kashflow_categories API call, returning empty string
		return '';
	};

}]);
StockModule.controller('StockCategoryModalCtrl', ['$scope', 'StockGroup', 'ErrorsHandler', '$uibModalInstance', 'item', 'kashflow_categories', 'kashflow_purchase_categories', function ($scope, StockGroup, ErrorsHandler, $uibModalInstance, item, kashflow_categories, kashflow_purchase_categories) {

	$scope.data = item;
	$scope.kashflow_categories = kashflow_categories;
	$scope.kashflow_purchase_categories = kashflow_purchase_categories;

	$scope.save = function () {
		if (item.id) {
			StockGroup.update($scope.data, function (response) {
				$uibModalInstance.close(response);
			}, ErrorsHandler);
		}
		else {
			StockGroup.save($scope.data, function (response) {
				$uibModalInstance.close(response);
			}, ErrorsHandler);
		}
	};

	$scope.cancel = function () {
		$uibModalInstance.dismiss('cancel');
	};
}]);

/**
 * Main controller for Stock Module
 */

StockModule.controller('StockMainCtrl', ['$scope', '$location', 'apiUrl', '$http', 'StockGroup', 'ErrorsHandler', function ($scope, $location, apiUrl, $http, StockGroup, ErrorsHandler) {

	// ------------------------------------------------------------------------
	//
	//	SCOPE VARIABLES BELOW -->
	//
	// ------------------------------------------------------------------------


	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------


	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	// Shared filters across all stock tabs
	$scope.sharedFilters = {
		limit: 10,
		search: null,
		type: null,
		under_buffer: 0,
		in_stock: null,
		ordered: 0,
		discontinued: null
	};

	$scope.loadCategories = function () {
		StockGroup.get({ limit: 100 }, function (response) {
			$scope.categories = response.data;
		},
			ErrorsHandler
		);
	};

	$scope.loadCategories();

}]);
StockModule.controller('StockModalCtrl', ['$scope', 'Stock', 'ErrorsHandler', '$uibModalInstance', 'categories', 'product_types', 'item', '$http', 'apiUrl', 'Severity', '$timeout', 'Build', 'quick_mode', function ($scope, Stock, ErrorsHandler, $uibModalInstance, categories, product_types, item, $http, apiUrl, Severity, $timeout, Build, quick_mode) {
	$scope.quick_mode = quick_mode;
	$scope.errors = null;
	$scope.categories = categories;
	$scope.product_types = product_types;
	$scope.product = item;
	$scope.loading = false;
	$scope.search = {
		stock: null
	};

	var stockSearchTimeout;

	Severity.get(null, function (resposense) {

		$scope.severities = resposense.data;
	});

	// Removed unnecessary API call to kashflow/nominalcodesextended/Turnover
	// Removed unnecessary API call to kashflow/nominalcodesextended/Cost of Sale
	//If it is a new item, initialize some values
	if (!item.id) {
		$scope.product = {
			unlimited: 0,
			severity_id: 2,
			approval_required: 0,
			quantity_to_order: 0,
			type: 'stock',
			quantity: 0,
			buffer: 0,
			builds: [],
			discontinued: 0, // nadeem
		};
	}

	// Initialize default values when opening the view in quick mode
	if ($scope.quick_mode) {
		$scope.product.composite = false;
	}


	Build.get({ stock_id: item.id, status: 'in_progress' }, function (response) {
		$scope.product.builds = response.data;
	});

	$scope.$watch('product.type', function (value, oldValue) {
		if (value != oldValue && value == 'service')
			$scope.product.unlimited = 1;
	});

	$scope.$watch('search.stock', function (value, oldValue) {
		if (value !== oldValue) {
			$timeout.cancel(stockSearchTimeout);
			stockSearchTimeout = $timeout(function () {
				Stock.get({ query: value }, function (response) {
					$scope.stock = response.data;
				});
			}, 250);
		}
	});

	$scope.save = function () {

		$scope.loading = true;

		if (item.id) {

			Stock.update($scope.product, function (response) {
				angular.extend(item, response || {});
				$uibModalInstance.close(response);
			}, function (a, b) {
				ErrorsHandler(a, b);
				$scope.loading = false;
			});
		}
		else {
			Stock.save($scope.product, function (response) {
				$uibModalInstance.close(response);
			}, function (response) {

				$scope.errors = "<strong><i class='fa fa-warning'></i>Correct the following errors:</strong><br><ul>";

				response.data.errors.forEach(function (error) {
					$scope.errors += "<li>" + error + "</li>";
				});

				$scope.errors += "</ul>";

				$scope.loading = false;
			});
		}
	};

	$scope.addCompositeItem = function (ev, item) {

		if (!$scope.product.composite_items) {
			$scope.product.composite_items = [];
		}
		else {

			// Check to see if the item already exists
			var existingItem = _.findWhere($scope.product.composite_items, { id: item.id });

			if (existingItem) {
				existingItem.pivot.quantity++;
				return;
			}
		}

		item.pivot = {
			quantity: 1
		};

		$scope.product.composite_items.push(item);
	};

	$scope.approveProduct = function () {
		$scope.product.approval_required = false;
		Stock.save({ id: $scope.product.id, approval_required: 0 }, function () {
			Message("The task has been approved.");
		});
	};

	$scope.generateRandomEAN = function () {
		var max = 199999999999;
		var min = 100000000000;
		var ean = Math.floor(Math.random() * (max - min + 1) + min).toString();

		// Calculate checksum, which is the last digit
		// http://stackoverflow.com/questions/1136642/ean-8-how-to-calculate-checksum-digit
		var val = 0;
		var digits = ean.split('');

		_.each(digits, function (digit, i) {
			val += parseInt(digit, 10) * ((i % 2 == 0) ? 1 : 3);
		});

		var checksum_digit = 10 - (val % 10);
		if (checksum_digit == 10) checksum_digit = 0;

		// Append the checksum to the ean number
		ean += checksum_digit;

		$scope.product.model_number = ean;
	};

	$scope.cancel = function () {
		$uibModalInstance.dismiss('cancel');
	};

}]);
/**
 * Stock Suppliers Controller
 */

StockModule.controller("StockNewOrderCtrl", [
	"$scope",
	"Supplier",
	"Payment",
	"Stock",
	"$paginator",
	"$routeParams",
	"ErrorsHandler",
	"$uibModal",
	"$timeout",
	"$location",
	"PurchaseOrder",
	"$paginator",
	function (
		$scope,
		Supplier,
		Payment,
		Stock,
		$paginator,
		$routeParams,
		ErrorsHandler,
		$uibModal,
		$timeout,
		$location,
		PurchaseOrder,
		$paginator
	) {
		// ------------------------------------------------------------------------
		//
		//	SCOPE VARIABLES BELOW -->
		//
		// ------------------------------------------------------------------------

		var search_timeout = 200;
		var searchTimer;

		//Pagination variables

		$scope.paginator = $paginator;
		$paginator = angular.copy($paginator);
		$scope.paginator = $paginator;
		$paginator.setLimit(20);

		//All suppliers
		$scope.suppliers = [];
		$scope.payments = [{ id: 0, test: "name" }];
		//Products to show on the list to add
		$scope.products = [];

		//Products with stock under buffer
		$scope.underBufferProducts = [];

		//Products matching the search parameters
		$scope.searchedProducts = [];

		$scope.vat = 0.2;

		$scope.loading = false;

		//Product types
		$scope.product_types = ["stock", "non_stock", "service"];

		$scope.data = {
			search_type: "requested",
			search: "",
			limit: 20
		};

		$scope.order = {
			reference_number: null,
			supplier_id: null,
			payment_id: null,
			delivery_cost: 0,
			delivery_vat_included: 0,
			discount_amount: 0,
			discount_vat_included: 0,
			items_vat_included: 0,
			products: []
		};

		// ------------------------------------------------------------------------
		//
		//	INITIALIZER FUNCTIONS BELOW -->
		//
		// ------------------------------------------------------------------------
		$scope.loadSuppliers = function (page) {
			Supplier.get(
				{ all: 1 },
				function (res) {
					$scope.suppliers = res.data;
				},
				ErrorsHandler
			);
		};
		$scope.loadSuppliers();

		$scope.loadPayments = function (page) {
			Payment.get(
				{ all: 1 },
				function (res) {
					$scope.payments = res.data;
				},
				ErrorsHandler
			);
		};
		$scope.loadPayments();
		// ------------------------------------------------------------------------
		//
		//	WATCHERS AND EVENT LISTENERS BELOW -->
		//
		// ------------------------------------------------------------------------

		$scope.$watch("data.search_type", function (value) {
			$scope.data.search = "";
			if (value == "under_buffer") $scope.loadUnderBufferProducts();

			if (value == "requested") $scope.loadRequestedProducts();

			if (value == "all") $scope.searchProducts();
		});

		$scope.$watch("data.search", function (newValue, oldValue) {
			// Clear the timeout
			$timeout.cancel(searchTimer);

			// Load the products using a timer
			searchTimer = $timeout(function () {
				if ($scope.data.search_type == "under_buffer")
					$scope.loadUnderBufferProducts(newValue);

				if ($scope.data.search_type == "requested")
					$scope.loadRequestedProducts(newValue);

				if ($scope.data.search_type == "all") $scope.searchProducts(newValue);
			}, search_timeout);
		});

		$paginator.setOnPageChange(function (page) {
			if ($scope.data.search_type == "under_buffer")
				$scope.loadUnderBufferProducts($scope.data.search, page);

			if ($scope.data.search_type == "requested")
				$scope.loadRequestedProducts($scope.data.search, page);

			if ($scope.data.search_type == "all")
				$scope.searchProducts($scope.data.search, page);
		});

		$scope.$watch("data.limit", function (newValue, oldValue) {
			if (newValue !== oldValue) $paginator.setLimit($scope.data.limit);
		});

		// ------------------------------------------------------------------------
		//
		//	FUNCTIONS BELOW THIS LINE -->
		//
		// ------------------------------------------------------------------------

		$scope.loadUnderBufferProducts = function (query, page) {
			var parameters = {
				under_buffer: 1,
				query: query,
				page: page
			};

			Stock.get(
				parameters,
				function (response) {
					$scope.updateTemporalValues(response.data);

					$scope.underBufferProducts = response.data;
					$scope.products = $scope.underBufferProducts;
					$paginator.setFromResponse(response);
				},
				ErrorsHandler
			);
		};

		$scope.loadRequestedProducts = function (query, page) {
			var parameters = {
				requested: 1,
				query: query,
				page: page
			};

			Stock.get(
				parameters,
				function (response) {
					$scope.updateTemporalValues(response.data);

					$scope.products = response.data;
					$paginator.setFromResponse(response);
				},
				ErrorsHandler
			);
		};

		$scope.searchProducts = function (query, page) {
			$scope.loading = true;

			var parameters = {
				limit: $scope.data.limit,
				query: query,
				page: page
			};

			Stock.get(
				parameters,
				function (response) {
					$scope.updateTemporalValues(response.data);

					$scope.products = response.data;
					$scope.searchedProducts = response.data;
					$paginator.setFromResponse(response);
					$scope.loading = false;
				},
				ErrorsHandler
			);
		};

		$scope.addToOrderProducts = function (item) {
			if (item.approval_required == 1) {
				alert("This product needs approval before add it to the order.");
				return;
			}

			var product = _.find($scope.order.products, function (el) {
				return el.id == item.id;
			});

			if (!product) {
				item.original_quantity_to_order = item.quantity_to_order;
				item.units = item.quantity_to_order != 0 ? item.quantity_to_order : 1;
				item.unit_cost = 0;
				item.quantity_to_order =
					item.quantity_to_order - item.units < 0
						? 0
						: item.quantity_to_order - item.units;
				$scope.order.products.push(item);
			} else {
				item.units++;
				item.quantity_to_order =
					item.quantity_to_order - 1 > 0 ? item.quantity_to_order - 1 : 0;
			}
		};

		//If the product has been added to the order products list, add to stock the quantity
		// of products to orders and substract to the products to order the same quantity
		$scope.updateTemporalValues = function (productsList) {
			angular.forEach(productsList, function (responseProduct, index) {
				angular.forEach($scope.order.products, function (
					orderedProduct,
					orderedIndex
				) {
					if (orderedProduct.id == responseProduct.id) {
						productsList[index] = orderedProduct;
					}
				});
			});
		};

		$scope.removeFromOrderProducts = function (item) {
			angular.forEach($scope.order.products, function (value, index) {
				if (value.id == item.id) {
					$scope.order.products.splice(index, 1);
					item.quantity_to_order = item.original_quantity_to_order;
					item.units = 0;
					item.unit_cost = 0;
				}
			});
		};

		$scope.updateValues = function (item) {
			item.quantity_to_order =
				item.original_quantity_to_order - item.units < 0
					? 0
					: item.original_quantity_to_order - item.units;
		};

		$scope.containsObject = function (obj, list) {
			return (
				_.filter(list, function (listItem) {
					return angular.equals(listItem, obj);
				}).length > 0
			);
		};

		$scope.validateOrder = function () {
			if ($scope.order.products.length == 0) return true;
			if (!$scope.order.reference_number) return true;
			if (!$scope.order.supplier_id) return true;
			if (!$scope.order.payment_id) return true;

			var incomplete = false;
			angular.forEach($scope.order.products, function (value, index) {
				if (value.unit_cost == 0 || value.units == 0) incomplete = true;
			});

			return incomplete;
		};

		$scope.saveOrder = function () {
			$scope.kashflow_loading = false;

			PurchaseOrder.save(
				$scope.order,
				function (response) {
					$location.path("/stock/orders/");
				},
				function (response) {
					$scope.errors =
						"<strong><i class='fa fa-warning'></i>Correct the following errors:</strong><br><ul>";
					$scope.kashflow_loading = false;

					response.data.errors.forEach(function (error) {
						$scope.errors += "<li>" + error + "</li>";
					});

					$scope.errors += "</ul>";
				},
				function (a, b) {
					$scope.kashflow_loading = false;
					ErrorsHandler(a, b);
				}
			);
		};

		$scope.addNewProduct = function () {
			var modalInstance = $uibModal.open({
				templateUrl: "stock/stock-form.html",
				controller: "StockModalCtrl",
				size: "lg",
				resolve: {
					categories: function () {
						return $scope.categories;
					},
					product_types: function () {
						return $scope.product_types;
					},
					item: function () {
						return {};
					},
					quick_mode: function () {
						return false;
					}
				}
			});

			modalInstance.result.then(function (_item) {
				$scope.addToOrderProducts(_item.data);
			});
		};

		$scope.addSupplier = function () {
			var modalInstance = $uibModal.open({
				templateUrl: "stock/suppliers/modal.html",
				controller: "StockSupplierModalCtrl",
				resolve: {
					item: function () {
						return {};
					}
				}
			});

			modalInstance.result.then(function (_item) {
				$scope.suppliers.push(_item);
			});
		};
		$scope.addPayment = function () {
			var modalInstance = $uibModal.open({
				templateUrl: "stock/payment/modal.html",
				controller: "PaymentModalCtrl",
				resolve: {
					item: function () {
						return {};
					}
				}
			});

			modalInstance.result.then(function (_item) {
				$scope.suppliers.push(_item);
			});
		};
		// Open a modal form to edir or create a new stock item.
		$scope.edit = function (product) {
			//Price include VAT to true
			product.price_vat_included = false;

			var modalInstance = $uibModal.open({
				templateUrl: "stock/stock-form.html",
				controller: "StockModalCtrl",
				size: "lg",
				resolve: {
					categories: function () {
						return $scope.categories;
					},
					product_types: function () {
						return $scope.product_types;
					},
					item: function () {
						return product;
					},
					quick_mode: function () {
						return false;
					}
				}
			});

			//Price include VAT to true
			modalInstance.result.then(function (response) {
				$scope.data.search_type = $scope.data.search_type;
			});
		};

		$scope.itemOrders = function (item) {
			var modalInstance = $uibModal.open({
				templateUrl: "stock/item_orders.html",
				controller: "ItemOrdersCtrl",
				resolve: {
					suppliers: function () {
						return $scope.suppliers;
					},
					stockItem: function () {
						return item;
					}
				}
			});

			// modalInstance.result.then(function() {

			// });
		};

		$scope.total = function () {
			var total = 0;

			if ($scope.order.delivery_vat_included)
				total += $scope.order.delivery_cost;
			else
				total +=
					$scope.order.delivery_cost + $scope.order.delivery_cost * $scope.vat;

			if ($scope.order.discount_vat_included)
				total -= $scope.order.discount_amount;
			else
				total -=
					$scope.order.discount_amount +
					$scope.order.discount_amount * $scope.vat;

			var cost = 0;
			angular.forEach($scope.order.products, function (product) {
				cost += product.unit_cost * product.units;
			});

			if ($scope.order.items_vat_included == "1") {
				total += cost;
			} else {
				total += cost + cost * $scope.vat;
			}

			return total.toFixed(2);
		};
	}
]);

(function () {
	'use strict';

	StockModule.controller('StockOrderListCtrl', StockOrderListCtrl);

	StockOrderListCtrl.$inject = ['$scope', '$paginator', 'Stock', 'ErrorsHandler'];

	function StockOrderListCtrl($scope, $paginator, Stock, ErrorsHandler) {
		/* jshint validthis: true */
		var vm = this;

		vm.query = '';
		vm.products = [];
		vm.paginator = angular.copy($paginator);
		vm.loadProducts = loadProducts;

		vm.paginator.setOnPageChange(function (page) {
			vm.loadProducts(page);
		});

		$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
			vm.loadProducts();
		});

		$scope.$watch('vm.query', function (newValue, oldValue) {
			if (newValue !== oldValue) {
				vm.loadProducts();
			}
		});


		//////////////


		/**
		 * Loads the products from the server.
		 */
		function loadProducts(page) {
			if (!page) page = 1;

			var parameters = {
				page: page,
				query: vm.query,
				requested: true,
				related: true
			};

			// under buffer query for 2nd table
			var parameters_ub = {
				page: page,
				query: vm.query,
				requested: false,
				related: false,
				under_buffer: true
			};

			Stock.get(parameters, function (response) {
				//  console.log('norm', parameters, response);
				vm.loading = false;

				_.each(response.data, function (el) {
					if (el.group) el.category_name = el.group.name;
					el.price_vat_included = 0;
				});

				vm.products = response.data;
				vm.paginator.setFromResponse(response);

			}, ErrorsHandler);

			Stock.get(parameters_ub, function (response) {
				//  console.log('ub', parameters, response);
				vm.loading = false;

				_.each(response.data, function (el) {
					if (el.group) el.category_name = el.group.name;
					el.price_vat_included = 0;
				});

				vm.products_ub = response.data;
				vm.paginator.setFromResponse(response);

			}, ErrorsHandler);
		}
	}

})();

/**
 * Stock Suppliers Controller
 */

StockModule.controller('StockOrdersCtrl', ['$scope', 'PurchaseOrder', '$paginator', '$routeParams', 'ErrorsHandler', '$uibModal', 'Supplier', 'Status', 'Messenger', '$timeout', function ($scope, PurchaseOrder, $paginator, $routeParams, ErrorsHandler, $uibModal, Supplier, Status, Messenger, $timeout) {


	var search_timeout = 200;
	var searchTimer;

	// ------------------------------------------------------------------------
	//
	//	SCOPE VARIABLES BELOW -->
	//
	// ------------------------------------------------------------------------


	$scope.orders = [];
	$scope.suppliers = [];
	$scope.statuses = [];
	$scope.paginator = $paginator;
	$paginator.setLimit(10);
	$scope.loading = true;
	$scope.stats = {
		'cancelled_orders': 0,
		'delivered_orders': 0,
		'total_orders': 0
	};
	$scope.filters = {
		search: null,
		limit: 10,
		status_id: null,
		serial_number: null
	};

	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		$scope.loadOrders();
	});

	$paginator.setOnPageChange(function (page) {
		$scope.loadOrders(page);
	});

	$paginator.setOnLimitChange(function (page, limit) {
		$scope.loadOrders(page);
	});

	$scope.$watch('filters.search', function (newValue, oldValue) {
		if (newValue === oldValue)
			return;

		$timeout.cancel(searchTimer);

		searchTimer = $timeout(function () {
			$scope.loadOrders();
		}, search_timeout);

	});

	$scope.$watch('filters.limit', function (newValue, oldValue) {
		if (newValue !== oldValue)
			$paginator.setLimit($scope.filters.limit);
	});

	$scope.$watch('filters.status_id', function (newValue, oldValue) {
		if (oldValue !== newValue)
			$scope.loadOrders();
	});

	$scope.$watch('filters.serial_number', function (newValue, oldValue) {
		if (newValue === oldValue)
			return;

		$timeout.cancel(searchTimer);

		searchTimer = $timeout(function () {
			$scope.loadOrders();
		}, search_timeout);

	});

	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	$scope.loadOrders = function (page) {
		$scope.loading = true;
		if (!page) page = 1;
		PurchaseOrder.get({ page: page, limit: $paginator.getLimit(), serial_number: $scope.filters.serial_number, query: $scope.filters.search, status_id: $scope.filters.status_id }, function (res) {
			$scope.orders = res.data;
			$scope.stats = res.stats;
			$paginator.setFromResponse(res);
			$scope.loading = false;

		}, ErrorsHandler);
	};

	$scope.loadSuppliers = function () {
		Supplier.get({ all: 1 }, function (res) {
			$scope.suppliers = res.data;
		}, ErrorsHandler);

	};

	$scope.loadStatuses = function () {
		Status.get({ for: 'orders' }, function (res) {
			$scope.statuses = res.data;
		}, ErrorsHandler);

	};

	$scope.updateOrder = function (parameters) {

		PurchaseOrder.update(parameters, function (res) {
			angular.forEach($scope.orders, function (item) {
				if (item.id == res.id)
					item.status_id = res.status_id;
			}, log);
			$scope.kashflow_loading = false;
			Messenger('The order has been modified successfully!');
		}, function (a, b) {
			$scope.kashflow_loading = false;
			ErrorsHandler(a, b);
		});
	}



	$scope.showModal = function (item) {

	};

	$scope.cancel = function (item) {
		if (item.status.name != 'Ordered')
			return;

		$scope.kashflow_loading = true;
		PurchaseOrder.remove({ orderId: item.id }, function (res) {
			$scope.loadOrders();
			$scope.kashflow_loading = false;
			Messenger('The order has been marked as cancelled');
		}, function (a, b) {
			$scope.kashflow_loading = false;
			ErrorsHandler(a, b);
		});
	};

	$scope.loadSuppliers();
	$scope.loadStatuses();



}]);
StockModule.controller('StockReportsCtrl', ['$scope', 'StockReport', 'ErrorsHandler', 'Messenger', '$paginator', '$timeout', function ($scope, StockReport, ErrorsHandler, Messenger, $paginator, $timeout) {

	var search_timeout = null;
	var currentRequest = null;

	$scope.reports = [];
	$scope.paginator = $paginator;

	//Pagination variables
	$paginator = angular.copy($paginator);
	$scope.paginator = $paginator;
	$paginator.setLimit(10);

	$scope.filters = {
		limit: 10,
		aknowledged: 0,
		type: 'mismatched',
		search: null
	};

	// Only load reports when actually needed
	var initialized = false;
	
	$scope.$watch('activeTab', function (value) {
		if (value == $scope.index && !initialized) {
			initialized = true;
			$scope.loadReports();
		}
	});

	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		if (!initialized) {
			initialized = true;
			$scope.loadReports();
		}
	});

	$paginator.setOnPageChange(function (page) {
		$scope.loadReports(page);
	});

	$paginator.setOnLimitChange(function (page) {
		$scope.loadReports(page);
	});

	$scope.$watch('filters.limit', function (newValue, oldValue) {
		if (newValue !== oldValue) {
			$paginator.setLimit($scope.filters.limit);
		}
	});

	$scope.$watch('filters.search', function (newValue, oldValue) {
		if (newValue === oldValue) return;
		if (search_timeout) $timeout.cancel(search_timeout);

		search_timeout = $timeout(function () {
			$scope.loadReports();
		}, 250);
	});

	$scope.$watch('filters.aknowledged', function (newValue, oldValue) {
		if (newValue !== oldValue) {
			$scope.loadReports();
		}
	});

	$scope.$watch('filters.type', function (newValue, oldValue) {
		if (newValue !== oldValue) {
			$scope.loadReports();
		}
	});

	$scope.loadReports = function (page) {
		// Cancel any existing request
		if (currentRequest && currentRequest.$cancelRequest) {
			currentRequest.$cancelRequest();
		}

		// Prevent multiple concurrent requests
		if ($scope.loading) {
			return;
		}

		$scope.loading = true;

		var data = {
			aknowledged: $scope.filters.aknowledged,
			type: $scope.filters.type,
			query: $scope.filters.search,
			page: page
		};

		currentRequest = StockReport.get(data, function (response) {
			$scope.loading = false;
			$scope.reports = response.data;
			$paginator.setFromResponse(response);
			currentRequest = null;
		}, function(error) {
			$scope.loading = false;
			currentRequest = null;
			ErrorsHandler(error);
		});
	};

	$scope.markAsAknowledged = function (report) {

		var data = {
			id: report.id,
			aknowledged: 1
		};

		StockReport.update(data, function (response) {
			report.aknowledged = 1;
			Messenger('Report marked as aknowledged successfully!');

		});
	};

	// Cleanup on controller destroy
	$scope.$on('$destroy', function() {
		if (currentRequest && currentRequest.$cancelRequest) {
			currentRequest.$cancelRequest();
		}
		if (search_timeout) {
			$timeout.cancel(search_timeout);
		}
	});

	// Initialize if no other triggers will fire
	if (!$scope.activeTab && !$scope.$root.$$phase) {
		initialized = true;
		$scope.loadReports();
	}

}]);
StockModule.controller('StockSupplierModalCtrl', ['$scope', 'Supplier', 'ErrorsHandler', '$uibModalInstance', 'item', function ($scope, Supplier, ErrorsHandler, $uibModalInstance, item) {

	$scope.data = item;

	$scope.save = function () {
		if (item.id) {
			Supplier.update($scope.data, function (response) {
				$uibModalInstance.close(response);
			}, ErrorsHandler);
		}
		else {
			Supplier.save($scope.data, function (response) {
				$uibModalInstance.close(response);
			}, ErrorsHandler);
		}
	};

	$scope.cancel = function () {
		$uibModalInstance.dismiss('cancel');
	};
}]);
/**
 * Stock Suppliers Controller
 */

StockModule.controller('StockSuppliersCtrl', ['$scope', 'Supplier', '$paginator', '$routeParams', 'ErrorsHandler', '$uibModal', function ($scope, Supplier, $paginator, $routeParams, ErrorsHandler, $uibModal) {


	// ------------------------------------------------------------------------
	//
	//	SCOPE VARIABLES BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.suppliers = [];
	$scope.paginator = $paginator;

	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		$scope.loadSuppliers();
	});

	$paginator.setOnPageChange(function (page) {
		$scope.loadSuppliers(page);
	});

	$paginator.setOnLimitChange(function (page, limit) {
		$scope.loadSuppliers(page);
	});


	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	$scope.loadSuppliers = function (page) {
		if (!page) page = 1;

		Supplier.get({ page: page, limit: $paginator.getLimit() }, function (res) {
			$scope.suppliers = res.data;
			$paginator.setFromResponse(res);
		}, ErrorsHandler);
	};

	$scope.showModal = function (item) {
		var modalInstance = $uibModal.open({
			templateUrl: 'stock/suppliers/modal.html',
			controller: 'StockSupplierModalCtrl',
			resolve: {
				item: function () {
					return item || {};
				}
			}
		});

		modalInstance.result.then(function (_item) {
			if (!item) {
				$scope.suppliers.push(_item);
			} else {
				angular.extend(item, _item || {});
			}
		});
	};

	$scope.delete = function (id) {
		Supplier.remove({ supplierId: id }, function () {
			$scope.suppliers = _.reject($scope.suppliers, function (el) { return el.id == id; });
		}, ErrorsHandler);
	};

}]);
StockModule.controller('StockTableCtrl', ['$scope', '$element', 'StockItem', 'Stock', 'Supplier', 'ErrorsHandler', 'Messenger', '$filter', '$timeout', '$paginator', '$uibModal', '$routeParams', function ($scope, $element, StockItem, Stock, Supplier, ErrorsHandler, Messenger, $filter, $timeout, $paginator, $uibModal, $routeParams) {

	var template = {
		manufacturer_code: 'EAN001',
		group_id: $scope.categoryId,
		type: 'stock',
		buffer: 0,
		margin: 0,
		business_margin: 0,
		cost: 0,
		retail: 0,
		quantity: 0,
		discontinued: 0
	};

	$scope.data = [];
	//$scope.filteredItems = [];
	$scope.products = [];
	$scope.suppliers = [];
	$scope.product_types = ["stock", "non_stock", "service"];
	$scope.paginator = $paginator;

	//Pagination variables
	$paginator = angular.copy($paginator);
	$scope.paginator = $paginator;
	$paginator.setLimit(10);

	// Use shared filters from parent scope or fallback to local filters
	if ($scope.$parent && $scope.$parent.sharedFilters) {
		$scope.filters = $scope.$parent.sharedFilters;
		// Set initial search query from route params if not already set
		if ($routeParams.query && !$scope.filters.search) {
			$scope.filters.search = $routeParams.query;
		}
	} else {
		// Fallback for standalone usage
		$scope.filters = {
			limit: 10,
			search: $routeParams.query,
			type: null,
			under_buffer: 0,
			in_stock: null,
			ordered: 0,
			discontinued: null
		};
	}

	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.$watch('activeTab', function (value) {
		if (value == $scope.index) $scope.loadProducts($scope.filters.search);
	});

	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		$scope.loadProducts($scope.filters.search);
	});

	$paginator.setOnPageChange(function (page) {
		$scope.loadProducts($scope.filters.search, page);
	});

	$paginator.setOnLimitChange(function (page, limit) {
		$scope.loadProducts($scope.filters.search, page);
	});

	$scope.$watchCollection('filters', function (newValue, oldValue) {
		if (newValue !== oldValue) {
			$paginator.setLimit($scope.filters.limit);
			// Reload products when filters change (except for limit changes)
			if (newValue && oldValue && Object.keys(newValue).some(function(key) {
				return key !== 'limit' && newValue[key] !== oldValue[key];
			})) {
				$scope.loadProducts($scope.filters.search, 1);
			}
		}
	});

	$scope.loadProducts = function (query, page) {

		$scope.response = null;
		var cat_id = ($scope.categoryId == 'all') ? false : $scope.categoryId;

		$scope.loading = true;

		var parameters = {
			category: cat_id,
			limit: $scope.filters.limit,
			page: page,
			query: query,
			type: $scope.filters.type,
			under_buffer: $scope.filters.under_buffer,
			in_stock: $scope.filters.in_stock,
			ordered: $scope.filters.ordered,
			show_discontinued: $scope.filters.discontinued
		};


		Stock.get(parameters, function (response) {
			$scope.loading = false;

			//Welcome to the jungle
			_.each(response.data, function (el) {
				// if ( el.supplier ) el.supplier_name = el.supplier.name;
				if (el.group) el.category_name = el.group.name;
				el.price_vat_included = 0;
			});
			$scope.data = response.data;
			$paginator.setFromResponse(response);


		}, ErrorsHandler);

		// Load suppliers
		if (!$scope.suppliersLoaded)
			$scope.loadSuppliers();

	};

	$scope.loadSuppliers = function () {
		Supplier.get(function (response) {
			$scope.suppliers = response.data;
			$scope.suppliersLoaded = true;
		}, ErrorsHandler);
	};


	$scope.$watch('data', function () {
		$scope.products = $scope.data;
	});


	// Open a modal form to edir or create a new stock item.
	$scope.edit = function (product) {

		var modalInstance = $uibModal.open({
			templateUrl: 'stock/stock-form.html',
			controller: 'StockModalCtrl',
			size: "lg",
			resolve: {
				categories: function () {
					return $scope.categories;
				},
				product_types: function () {
					return $scope.product_types;
				},
				item: function () {
					return product;
				},
				quick_mode: function () {
					return false;
				}
			}
		});

		modalInstance.result.then(function (response) {
			response.data.price_vat_included = 0;
			if (!product) {
				$scope.categories.push(response.data);
			} else {

				angular.extend(product, response.data || {});
			}
		});
	};

	$scope.updateStockQuantity = function (item) {
		if (item.unlimited)
			return;

		var modalInstance = $uibModal.open({
			templateUrl: 'stock/stock-update.html',
			controller: 'ManualUpdateStockTransactionModalCtrl',
			resolve: {
				product: function () {
					return item;
				}
			}
		});

		modalInstance.result.then(function (transactionQuantity) {
			item.quantity = item.quantity + transactionQuantity;
		});
	}


	$scope.delete = function (item) {
		Stock.delete({ stockId: item.id }, function (response) {
			$scope.products = _.reject($scope.products, function (el) {
				return el.id == item.id;
			});
		}, ErrorsHandler);
	};


	$scope.update = function (item) {

		Stock.update(item, function (response) {
			Messenger("Item updated successfully!");
			angular.extend(item, response.data || {});
		}, ErrorsHandler);
	};

	$scope.save = function (item) {
		if (item.id) {
			$scope.update(item);
		}
		else {
			_.defaults(item, template || {});
			$scope.create(item);
		}
	};

	$scope.add = function () {

		var modalInstance = $uibModal.open({
			templateUrl: 'stock/stock-form.html',
			controller: 'StockModalCtrl',
			size: "lg",
			resolve: {
				categories: function () {
					return $scope.categories;
				},
				product_types: function () {
					return $scope.product_types;
				},
				item: function () {
					return {};
				},
				quick_mode: function () {
					return false;
				}
			}
		});

		modalInstance.result.then(function (_item) {
			$scope.loadProducts();
		});
	};

	$scope.showHistory = function (item) {

		var modalInstance = $uibModal.open({
			templateUrl: 'stock/item-history.html',
			controller: 'ItemTransactionsCtrl',
			resolve: {
				stockItem: function () {
					return item;
				},
				related_type: function () {
					return null;
				},
				related_id: function () {
					return null;
				}
			}
		});

	};



}]);

StockModule.directive('stockTable', function () {

	return {
		restrict: 'AE',
		scope: {
			categoryId: '@',
			index: '@',
			activeTab: '=',
			categories: '='
		},
		templateUrl: 'stock/stock-table.html',
		controller: 'StockTableCtrl'
	};
});


StockModule.controller('StockTakesTableCtrl', ['$scope', '$element', 'StockItem', 'Stock', 'ErrorsHandler', 'Messenger', '$filter', '$timeout', '$paginator', '$uibModal', '$routeParams', '$q', 'StockReport', function ($scope, $element, StockItem, Stock, ErrorsHandler, Messenger, $filter, $timeout, $paginator, $uibModal, $routeParams, $q, StockReport) {

	var search_timeout = 200;

	$scope.data = [];
	$scope.products = [];
	$scope.paginator = $paginator;

	//Pagination variables
	$paginator = angular.copy($paginator);
	$scope.paginator = $paginator;
	$paginator.setLimit(10);

	$scope.filters = {
		limit: 10,
		search: $routeParams.query,
		last_report_date: 'more_than_two_weeks',
		under_buffer: 0,
	};

	// ------------------------------------------------------------------------
	//
	//	WATCHERS AND EVENT LISTENERS BELOW -->
	//
	// ------------------------------------------------------------------------

	$scope.$watch('activeTab', function (value) {
		if (value == $scope.index) $scope.loadProducts();
	});

	$scope.$on('$routeChangeSuccess', function (ev, currentRoute, previousRoute) {
		$scope.loadProducts();
	});

	$paginator.setOnPageChange(function (page) {
		$scope.loadProducts(page);
	});

	$paginator.setOnLimitChange(function (page, limit) {
		$scope.loadProducts(page);
	});

	$scope.$watch('filters.limit', function (newValue, oldValue) {
		if (newValue !== oldValue)
			$paginator.setLimit($scope.filters.limit);
	});

	$scope.$watch('filters.search', function (newValue, oldValue) {
		if (newValue === oldValue) return;
		if (search_timeout) $timeout.cancel(search_timeout);

		search_timeout = $timeout(function () {
			$scope.products = $scope.loadProducts();
		}, 250);
	});

	$scope.$watch('filters.last_report_date', function (newValue, oldValue) {
		if (newValue === oldValue) return;
		$scope.loadProducts();
	});

	$scope.$watch('filters.under_buffer', function (newValue, oldValue) {
		if (newValue === oldValue) return;
		$scope.loadProducts();
	});

	$scope.loadProducts = function (page) {

		$scope.response = null;
		var cat_id = ($scope.categoryId == 'all') ? false : $scope.categoryId;

		$scope.loading = true;

		var parameters = {
			category: cat_id,
			limit: $scope.filters.limit,
			page: page,
			query: $scope.filters.search,
			type: 'stock',
			under_buffer: $scope.filters.under_buffer
		};

		if ($scope.filters.last_report_date)
			var parameters = $scope.addLasReportDateFilters(parameters);


		Stock.get(parameters, function (response) {
			$scope.loading = false;

			//Welcome to the jungle
			_.each(response.data, function (el) {
				if (el.group) el.category_name = el.group.name;
			});

			$scope.data = response.data;
			$paginator.setFromResponse(response);

		}, ErrorsHandler);

	};

	$scope.$watch('data', function () {
		$scope.products = $scope.data;
	});

	$scope.updateQuantity = function (item) {

		var deferred = $q.defer();
		var data = {
			stock_id: item.id,
			quantity: isNaN(item.new_quantity) ? item.quantity : item.new_quantity
		};

		StockReport.save(data, function (response) {
			item.last_report = response.data;
			item.quantity = response.data.new_quantity;
			item.new_quantity = null;
			Messenger("Report saved successfully!");
			deferred.resolve(true);

		}, function (a, b) {
			deferred.resolve(false);
			ErrorsHandler(a, b);
		});

		return deferred.promise;
	};


	$scope.addLasReportDateFilters = function (parameters) {
		if ($scope.filters.last_report_date == "this_week") {
			parameters.reported_after = moment().subtract(7, 'days').format("YYYY-MM-DD HH:mm:ss");
		}
		else if ($scope.filters.last_report_date == "last_week") {
			parameters.reported_before = moment().subtract(7, 'days').format("YYYY-MM-DD HH:mm:ss");
			parameters.reported_after = moment().subtract(14, 'days').format("YYYY-MM-DD HH:mm:ss");
		}
		if ($scope.filters.last_report_date == "more_than_two_weeks") {
			parameters.reported_before = moment().subtract(14, 'days').format("YYYY-MM-DD HH:mm:ss");
		}

		return parameters;
	};

}]);

StockModule.directive('stockTakesTable', function () {

	return {
		restrict: 'AE',
		scope: {
			categoryId: '@',
			index: '@',
			activeTab: '=',
			categories: '='
		},
		templateUrl: 'stock/stock-takes-table.html',
		controller: 'StockTakesTableCtrl'
	};
});



/**
 * Stock Form Service
 * @return service
 */
StockModule.service('_stockForm', ['$rootScope', 'Stock', 'ErrorsHandler', 'Messenger', '$location', function ($rootScope, Stock, ErrorsHandler, Messenger, $location) {

	// A local reference
	var $this = this;

	// Options
	$this.options = {
		showErrors: true,
		showMessage: true,
		callback: function () {

		},
		message: "I've successfully saved the stock item!"
	};

	// Datastore
	$this.data = {};

	// ------------------------------------------------------------------------
	//
	//	SETTERS AND GETTERS -->
	//
	// ------------------------------------------------------------------------

	$this.getData = function () {
		return $this.data;
	};

	$this.setData = function (new_data) {
		angular.copy(new_data, $this.data);
	};

	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	$this.save = function () {

		// Bind to an error event handler
		errors_handler = ($this.options.showErrors) ? ErrorsHandler : null;

		if ($this.data.id) {
			// Update the existing stock
			Stock.update($this.data, function (res) {
				if ($this.options.showMessage) Messenger($this.options.message);
			}, errors_handler);
		} else {
			// Create the stock first
			Stock.save($this.data, function (res) {
				// Update the stock_id
				$this.data.id = res.id;
				$this.data.stock_id = res.id;

				$this.options.callback('save', res);

				if ($this.options.showMessage) Messenger($this.options.message);
			}, errors_handler);
		}
	};

	$this.clearForm = function () {
		angular.copy({}, $this.data);
	};

}]);

/**
 * Stock Item Form Service
 * @return service
 */
StockModule.service('_stockItemForm', ['$rootScope', 'StockItem', 'ErrorsHandler', 'Messenger', '$location', function ($rootScope, StockItem, ErrorsHandler, Messenger, $location) {

	// A local reference
	var $this = this;

	// Options
	$this.options = {
		showErrors: true,
		showMessage: true,
		callback: function () {
			$location.path('/stock/browse/');
		},
		message: "I've successfully saved the stock item!"
	};

	// Datastore
	$this.data = {};

	// ------------------------------------------------------------------------
	//
	//	SETTERS AND GETTERS -->
	//
	// ------------------------------------------------------------------------

	$this.getData = function () {
		return $this.data;
	};

	$this.setData = function (new_data) {
		angular.copy(new_data, $this.data);
	};

	$this.setStockId = function (id) {
		$this.data.stock_id = id;
	};

	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	$this.save = function () {

		// Bind to an error event handler
		errors_handler = ($this.options.showErrors) ? ErrorsHandler : null;

		if ($this.data.id) {
			$this.update();
			return false;
		}

		// Save the stock item
		StockItem.save($this.data, function (response) {
			if ($this.options.showMessage) Messenger($this.options.message);

			// Execute the callback
			$this.options.callback('save', response);

			// Keep the stock id
			var stock_id = $this.data.stock_id;

			// Clear the form
			$this.clearForm();

			// Set back the same stock_id...
			$this.data.stock_id = stock_id;
		}, errors_handler);

	};

	$this.update = function () {
		// Bind to an error event handler
		errors_handler = ($this.options.showErrors) ? ErrorsHandler : null;

		// Save the stock item
		StockItem.update($this.data, function (response) {
			if ($this.options.showMessage) Messenger($this.options.message);

			// Execute the callback
			$this.options.callback('update', response);

			// Keep the stock id
			var stock_id = $this.data.stock_id;

			// Clear the form
			$this.clearForm();

			// Set back the same stock_id...
			$this.data.stock_id = stock_id;
		}, errors_handler);
	};

	$this.clearForm = function () {
		angular.copy({}, $this.data);
	};

}]);

/**
 * Stock Form Service
 * @return service
 */
StockModule.service('_supplierForm', ['$rootScope', 'Supplier', 'ErrorsHandler', 'Messenger', '$location', function ($rootScope, Supplier, ErrorsHandler, Messenger, $location) {

	// A local reference
	var $this = this;

	// Options
	$this.options = {
		showErrors: true,
		showMessage: true,
		clearForm: true,
		callback: function (res) { },
		updateCallback: function (res) { },
		message: "I've successfully saved the supplier!",
		updateMessage: "I've successfully updated the supplier!"
	};

	// Datastore
	$this.data = {};

	// ------------------------------------------------------------------------
	//
	//	SETTERS AND GETTERS -->
	//
	// ------------------------------------------------------------------------

	$this.getData = function () {
		return $this.data;
	};

	$this.setData = function (new_data) {
		angular.copy(new_data, $this.data);
	};

	// ------------------------------------------------------------------------
	//
	//	FUNCTIONS BELOW THIS LINE -->
	//
	// ------------------------------------------------------------------------

	$this.save = function () {

		// Bind to an error event handler
		errors_handler = ($this.options.showErrors) ? ErrorsHandler : null;

		if ($this.isUpdate()) {
			Supplier.update($this.data, function (res) {
				if ($this.options.showMessage) Messenger($this.options.updateMessage);

				// Execute the callback
				$this.options.updateCallback(res);

			}, errors_handler);
		} else {
			// Create the stock first
			Supplier.save($this.data, function (res) {
				if ($this.options.showMessage) Messenger($this.options.message);

				if ($this.options.clearForm) $this.clearForm();

				// Execute the callback
				$this.options.callback(res);

			}, errors_handler);
		}
	};

	$this.clearForm = function () {
		angular.copy({}, $this.data);
	};

	$this.isUpdate = function () {
		return ($this.data.id) ? true : false;
	};

}]);
/**
 * Accounts Module
 *
 */
