Allow zero rate while reposting
This commit is contained in:
		
							parent
							
								
									fb6e434315
								
							
						
					
					
						commit
						f1a07ff105
					
				| @ -7,7 +7,7 @@ import frappe.defaults | ||||
| from frappe.utils import cint, cstr, flt | ||||
| from frappe import _, msgprint, throw | ||||
| from erpnext.accounts.party import get_party_account, get_due_date | ||||
| from erpnext.controllers.stock_controller import update_gl_entries_after, block_negative_stock | ||||
| from erpnext.controllers.stock_controller import update_gl_entries_after | ||||
| from frappe.model.mapper import get_mapped_doc | ||||
| 
 | ||||
| from erpnext.controllers.selling_controller import SellingController | ||||
| @ -456,8 +456,8 @@ class SalesInvoice(SellingController): | ||||
| 
 | ||||
| 		self.make_sl_entries(sl_entries) | ||||
| 
 | ||||
| 	def make_gl_entries(self, repost_future_gle=True, allow_negative_stock=False): | ||||
| 		gl_entries = self.get_gl_entries(allow_negative_stock=allow_negative_stock) | ||||
| 	def make_gl_entries(self, repost_future_gle=True): | ||||
| 		gl_entries = self.get_gl_entries() | ||||
| 
 | ||||
| 		if gl_entries: | ||||
| 			from erpnext.accounts.general_ledger import make_gl_entries | ||||
| @ -476,7 +476,7 @@ class SalesInvoice(SellingController): | ||||
| 					items, warehouses = self.get_items_and_warehouses() | ||||
| 					update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items) | ||||
| 
 | ||||
| 	def get_gl_entries(self, warehouse_account=None, allow_negative_stock=False): | ||||
| 	def get_gl_entries(self, warehouse_account=None): | ||||
| 		from erpnext.accounts.general_ledger import merge_similar_entries | ||||
| 
 | ||||
| 		gl_entries = [] | ||||
| @ -485,7 +485,7 @@ class SalesInvoice(SellingController): | ||||
| 
 | ||||
| 		self.make_tax_gl_entries(gl_entries) | ||||
| 
 | ||||
| 		self.make_item_gl_entries(gl_entries, allow_negative_stock) | ||||
| 		self.make_item_gl_entries(gl_entries) | ||||
| 
 | ||||
| 		# merge gl entries before adding pos entries | ||||
| 		gl_entries = merge_similar_entries(gl_entries) | ||||
| @ -520,7 +520,7 @@ class SalesInvoice(SellingController): | ||||
| 					}) | ||||
| 				) | ||||
| 
 | ||||
| 	def make_item_gl_entries(self, gl_entries, allow_negative_stock=False): | ||||
| 	def make_item_gl_entries(self, gl_entries): | ||||
| 		# income account gl entries | ||||
| 		for item in self.get("entries"): | ||||
| 			if flt(item.base_amount): | ||||
| @ -537,7 +537,7 @@ class SalesInvoice(SellingController): | ||||
| 		# expense account gl entries | ||||
| 		if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \ | ||||
| 				and cint(self.update_stock): | ||||
| 			gl_entries += super(SalesInvoice, self).get_gl_entries(allow_negative_stock=allow_negative_stock) | ||||
| 			gl_entries += super(SalesInvoice, self).get_gl_entries() | ||||
| 
 | ||||
| 	def make_pos_gl_entries(self, gl_entries): | ||||
| 		if cint(self.is_pos) and self.cash_bank_account and self.paid_amount: | ||||
|  | ||||
| @ -11,7 +11,7 @@ from erpnext.controllers.accounts_controller import AccountsController | ||||
| from erpnext.accounts.general_ledger import make_gl_entries, delete_gl_entries, process_gl_map | ||||
| 
 | ||||
| class StockController(AccountsController): | ||||
| 	def make_gl_entries(self, repost_future_gle=True, allow_negative_stock=False): | ||||
| 	def make_gl_entries(self, repost_future_gle=True): | ||||
| 		if self.docstatus == 2: | ||||
| 			delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name) | ||||
| 
 | ||||
| @ -19,18 +19,16 @@ class StockController(AccountsController): | ||||
| 			warehouse_account = get_warehouse_account() | ||||
| 
 | ||||
| 			if self.docstatus==1: | ||||
| 				gl_entries = self.get_gl_entries(warehouse_account, allow_negative_stock=allow_negative_stock) | ||||
| 				gl_entries = self.get_gl_entries(warehouse_account) | ||||
| 				make_gl_entries(gl_entries) | ||||
| 
 | ||||
| 			if repost_future_gle: | ||||
| 				items, warehouses = self.get_items_and_warehouses() | ||||
| 				update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items, | ||||
| 					warehouse_account, allow_negative_stock) | ||||
| 					warehouse_account) | ||||
| 
 | ||||
| 	def get_gl_entries(self, warehouse_account=None, default_expense_account=None, | ||||
| 			default_cost_center=None, allow_negative_stock=False): | ||||
| 
 | ||||
| 		# block_negative_stock(allow_negative_stock) | ||||
| 			default_cost_center=None): | ||||
| 
 | ||||
| 		if not warehouse_account: | ||||
| 			warehouse_account = get_warehouse_account() | ||||
| @ -219,7 +217,7 @@ class StockController(AccountsController): | ||||
| 		return serialized_items | ||||
| 
 | ||||
| def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None, | ||||
| 		warehouse_account=None, allow_negative_stock=False): | ||||
| 		warehouse_account=None): | ||||
| 	def _delete_gl_entries(voucher_type, voucher_no): | ||||
| 		frappe.db.sql("""delete from `tabGL Entry` | ||||
| 			where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no)) | ||||
| @ -233,12 +231,12 @@ def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for | ||||
| 	for voucher_type, voucher_no in future_stock_vouchers: | ||||
| 		existing_gle = gle.get((voucher_type, voucher_no), []) | ||||
| 		voucher_obj = frappe.get_doc(voucher_type, voucher_no) | ||||
| 		expected_gle = voucher_obj.get_gl_entries(warehouse_account, allow_negative_stock=allow_negative_stock) | ||||
| 		expected_gle = voucher_obj.get_gl_entries(warehouse_account) | ||||
| 		if expected_gle: | ||||
| 			if not existing_gle or not compare_existing_and_expected_gle(existing_gle, | ||||
| 				expected_gle): | ||||
| 					_delete_gl_entries(voucher_type, voucher_no) | ||||
| 					voucher_obj.make_gl_entries(repost_future_gle=False, allow_negative_stock=allow_negative_stock) | ||||
| 					voucher_obj.make_gl_entries(repost_future_gle=False) | ||||
| 		else: | ||||
| 			_delete_gl_entries(voucher_type, voucher_no) | ||||
| 
 | ||||
| @ -290,8 +288,3 @@ def get_warehouse_account(): | ||||
| 	warehouse_account = dict(frappe.db.sql("""select master_name, name from tabAccount | ||||
| 		where account_type = 'Warehouse' and ifnull(master_name, '') != ''""")) | ||||
| 	return warehouse_account | ||||
| 
 | ||||
| def block_negative_stock(allow_negative_stock=False): | ||||
| 	if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) and not allow_negative_stock: | ||||
| 		if cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock")): | ||||
| 			frappe.throw(_("Negative stock is not allowed in case of Perpetual Inventory, please disable it from Stock Settings")) | ||||
|  | ||||
| @ -7,7 +7,7 @@ from frappe.utils import flt | ||||
| 
 | ||||
| def execute(): | ||||
| 	from erpnext.utilities.repost_stock import repost | ||||
| 	repost() | ||||
| 	repost(allow_zero_rate=True) | ||||
| 
 | ||||
| 	warehouse_account = frappe.db.sql("""select name, master_name from tabAccount | ||||
| 		where ifnull(account_type, '') = 'Warehouse'""") | ||||
| @ -40,7 +40,7 @@ def execute(): | ||||
| 					where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no)) | ||||
| 
 | ||||
| 				voucher = frappe.get_doc(voucher_type, voucher_no) | ||||
| 				voucher.make_gl_entries(repost_future_gle=False, allow_negative_stock=True) | ||||
| 				voucher.make_gl_entries(repost_future_gle=False) | ||||
| 				frappe.db.commit() | ||||
| 			except Exception, e: | ||||
| 				print frappe.get_traceback() | ||||
|  | ||||
| @ -283,11 +283,8 @@ class PurchaseReceipt(BuyingController): | ||||
| 	def get_rate(self,arg): | ||||
| 		return frappe.get_doc('Purchase Common').get_rate(arg,self) | ||||
| 
 | ||||
| 	def get_gl_entries(self, warehouse_account=None, allow_negative_stock=False): | ||||
| 	def get_gl_entries(self, warehouse_account=None): | ||||
| 		from erpnext.accounts.general_ledger import process_gl_map | ||||
| 		from erpnext.controllers.stock_controller import block_negative_stock | ||||
| 
 | ||||
| 		# block_negative_stock(allow_negative_stock) | ||||
| 
 | ||||
| 		stock_rbnb = self.get_company_default("stock_received_but_not_billed") | ||||
| 		expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation") | ||||
|  | ||||
| @ -198,12 +198,12 @@ class StockReconciliation(StockController): | ||||
| 				"posting_time": self.posting_time | ||||
| 			}) | ||||
| 
 | ||||
| 	def get_gl_entries(self, warehouse_account=None, allow_negative_stock=False): | ||||
| 	def get_gl_entries(self, warehouse_account=None): | ||||
| 		if not self.cost_center: | ||||
| 			msgprint(_("Please enter Cost Center"), raise_exception=1) | ||||
| 
 | ||||
| 		return super(StockReconciliation, self).get_gl_entries(warehouse_account, | ||||
| 			self.expense_account, self.cost_center, allow_negative_stock=allow_negative_stock) | ||||
| 			self.expense_account, self.cost_center) | ||||
| 
 | ||||
| 	def validate_expense_account(self): | ||||
| 		if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")): | ||||
|  | ||||
| @ -58,7 +58,7 @@ def delete_cancelled_entry(voucher_type, voucher_no): | ||||
| 	frappe.db.sql("""delete from `tabStock Ledger Entry` | ||||
| 		where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no)) | ||||
| 
 | ||||
| def update_entries_after(args, verbose=1): | ||||
| def update_entries_after(args, allow_zero_rate=False, verbose=1): | ||||
| 	""" | ||||
| 		update valution rate and qty after transaction | ||||
| 		from the current time-bucket onwards | ||||
| @ -106,9 +106,9 @@ def update_entries_after(args, verbose=1): | ||||
| 				stock_queue = [[qty_after_transaction, valuation_rate]] | ||||
| 			else: | ||||
| 				if valuation_method == "Moving Average": | ||||
| 					valuation_rate = get_moving_average_values(qty_after_transaction, sle, valuation_rate) | ||||
| 					valuation_rate = get_moving_average_values(qty_after_transaction, sle, valuation_rate, allow_zero_rate) | ||||
| 				else: | ||||
| 					valuation_rate = get_fifo_values(qty_after_transaction, sle, stock_queue) | ||||
| 					valuation_rate = get_fifo_values(qty_after_transaction, sle, stock_queue, allow_zero_rate) | ||||
| 
 | ||||
| 
 | ||||
| 				qty_after_transaction += flt(sle.actual_qty) | ||||
| @ -251,7 +251,7 @@ def get_serialized_values(qty_after_transaction, sle, valuation_rate): | ||||
| 
 | ||||
| 	return valuation_rate | ||||
| 
 | ||||
| def get_moving_average_values(qty_after_transaction, sle, valuation_rate): | ||||
| def get_moving_average_values(qty_after_transaction, sle, valuation_rate, allow_zero_rate): | ||||
| 	incoming_rate = flt(sle.incoming_rate) | ||||
| 	actual_qty = flt(sle.actual_qty) | ||||
| 
 | ||||
| @ -266,11 +266,11 @@ def get_moving_average_values(qty_after_transaction, sle, valuation_rate): | ||||
| 		if new_stock_qty: | ||||
| 			valuation_rate = new_stock_value / flt(new_stock_qty) | ||||
| 	elif not valuation_rate and qty_after_transaction <= 0: | ||||
| 		valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse) | ||||
| 		valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse, allow_zero_rate) | ||||
| 
 | ||||
| 	return abs(flt(valuation_rate)) | ||||
| 
 | ||||
| def get_fifo_values(qty_after_transaction, sle, stock_queue): | ||||
| def get_fifo_values(qty_after_transaction, sle, stock_queue, allow_zero_rate): | ||||
| 	incoming_rate = flt(sle.incoming_rate) | ||||
| 	actual_qty = flt(sle.actual_qty) | ||||
| 
 | ||||
| @ -290,7 +290,7 @@ def get_fifo_values(qty_after_transaction, sle, stock_queue): | ||||
| 		qty_to_pop = abs(actual_qty) | ||||
| 		while qty_to_pop: | ||||
| 			if not stock_queue: | ||||
| 				stock_queue.append([0, get_valuation_rate(sle.item_code, sle.warehouse) | ||||
| 				stock_queue.append([0, get_valuation_rate(sle.item_code, sle.warehouse, allow_zero_rate) | ||||
| 					if qty_after_transaction <= 0 else 0]) | ||||
| 
 | ||||
| 			batch = stock_queue[0] | ||||
| @ -349,7 +349,7 @@ def get_previous_sle(args, for_update=False): | ||||
| 		"desc", "limit 1", for_update=for_update) | ||||
| 	return sle and sle[0] or {} | ||||
| 
 | ||||
| def get_valuation_rate(item_code, warehouse): | ||||
| def get_valuation_rate(item_code, warehouse, allow_zero_rate=False): | ||||
| 	last_valuation_rate = frappe.db.sql("""select valuation_rate | ||||
| 		from `tabStock Ledger Entry` | ||||
| 		where item_code = %s and warehouse = %s | ||||
| @ -367,7 +367,7 @@ def get_valuation_rate(item_code, warehouse): | ||||
| 	if not valuation_rate: | ||||
| 		valuation_rate = frappe.db.get_value("Item Price", {"item_code": item_code, "buying": 1}, "price_list_rate") | ||||
| 
 | ||||
| 	if not valuation_rate and cint(frappe.db.get_value("Accounts Settings", None, "auto_accounting_for_stock")): | ||||
| 	if not allow_zero_rate and not valuation_rate and cint(frappe.db.get_value("Accounts Settings", None, "auto_accounting_for_stock")): | ||||
| 		frappe.throw(_("Purchase rate for item: {0} not found, which is required to book accounting entry (expense). Please mention item price against a buying price list.").format(item_code)) | ||||
| 
 | ||||
| 	return valuation_rate | ||||
|  | ||||
| @ -9,7 +9,7 @@ from erpnext.stock.utils import update_bin | ||||
| from erpnext.stock.stock_ledger import update_entries_after | ||||
| from erpnext.accounts.utils import get_fiscal_year | ||||
| 
 | ||||
| def repost(allow_negative_stock=False): | ||||
| def repost(allow_negative_stock=False, allow_zero_rate=False): | ||||
| 	""" | ||||
| 	Repost everything! | ||||
| 	""" | ||||
| @ -23,7 +23,7 @@ def repost(allow_negative_stock=False): | ||||
| 		union | ||||
| 		select item_code, warehouse from `tabStock Ledger Entry`) a"""): | ||||
| 			try: | ||||
| 				repost_stock(d[0], d[1]) | ||||
| 				repost_stock(d[0], d[1], allow_zero_rate) | ||||
| 				frappe.db.commit() | ||||
| 			except: | ||||
| 				frappe.db.rollback() | ||||
| @ -33,8 +33,8 @@ def repost(allow_negative_stock=False): | ||||
| 			frappe.db.get_value("Stock Settings", None, "allow_negative_stock")) | ||||
| 	frappe.db.auto_commit_on_many_writes = 0 | ||||
| 
 | ||||
| def repost_stock(item_code, warehouse): | ||||
| 	repost_actual_qty(item_code, warehouse) | ||||
| def repost_stock(item_code, warehouse, allow_zero_rate=False): | ||||
| 	repost_actual_qty(item_code, warehouse, allow_zero_rate) | ||||
| 
 | ||||
| 	if item_code and warehouse: | ||||
| 		update_bin_qty(item_code, warehouse, { | ||||
| @ -44,9 +44,9 @@ def repost_stock(item_code, warehouse): | ||||
| 			"planned_qty": get_planned_qty(item_code, warehouse) | ||||
| 		}) | ||||
| 
 | ||||
| def repost_actual_qty(item_code, warehouse): | ||||
| def repost_actual_qty(item_code, warehouse, allow_zero_rate=False): | ||||
| 	try: | ||||
| 		update_entries_after({ "item_code": item_code, "warehouse": warehouse }) | ||||
| 		update_entries_after({ "item_code": item_code, "warehouse": warehouse }, allow_zero_rate) | ||||
| 	except: | ||||
| 		pass | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user