From 6c48ef781b2e5647bdfa8fc0d7e7c476633f9b87 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 8 Oct 2014 11:00:38 +0530 Subject: [PATCH] Utility: Repost stock ledger entries and gl entries for all stock transactions --- erpnext/controllers/stock_controller.py | 13 ++++----- .../landed_cost_voucher.py | 4 +-- .../purchase_receipt/purchase_receipt.py | 11 +++++--- .../stock/doctype/stock_entry/stock_entry.py | 2 +- .../stock_reconciliation.py | 8 +++--- .../stock/page/stock_balance/stock_balance.js | 6 +++-- erpnext/utilities/repost_stock.py | 27 +++++++++++++++++++ 7 files changed, 52 insertions(+), 19 deletions(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 304ded2390..8c5bcac407 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -19,7 +19,7 @@ class StockController(AccountsController): warehouse_account = get_warehouse_account() if self.docstatus==1: - gl_entries = self.get_gl_entries(warehouse_account, allow_negative_stock) + gl_entries = self.get_gl_entries(warehouse_account, allow_negative_stock=allow_negative_stock) make_gl_entries(gl_entries) if repost_future_gle: @@ -30,7 +30,7 @@ class StockController(AccountsController): 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) + # block_negative_stock(allow_negative_stock) if not warehouse_account: warehouse_account = get_warehouse_account() @@ -52,7 +52,7 @@ class StockController(AccountsController): stock_value_difference = flt(sle.stock_value_difference, 2) if not stock_value_difference: valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse, sle.posting_date) - stock_value_difference = flt(sle.qty)*flt(valuation_rate) + stock_value_difference = flt(sle.actual_qty)*flt(valuation_rate) gl_list.append(self.get_gl_dict({ "account": warehouse_account[sle.warehouse], @@ -126,7 +126,8 @@ class StockController(AccountsController): def get_stock_ledger_details(self): stock_ledger = {} - for sle in frappe.db.sql("""select warehouse, stock_value_difference, voucher_detail_no + for sle in frappe.db.sql("""select warehouse, stock_value_difference, + voucher_detail_no, item_code, posting_date, actual_qty from `tabStock Ledger Entry` where voucher_type=%s and voucher_no=%s""", (self.doctype, self.name), as_dict=True): stock_ledger.setdefault(sle.voucher_detail_no, []).append(sle) @@ -237,7 +238,7 @@ 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) + expected_gle = voucher_obj.get_gl_entries(warehouse_account, allow_negative_stock=allow_negative_stock) if expected_gle: if not existing_gle or not compare_existing_and_expected_gle(existing_gle, expected_gle): @@ -310,6 +311,6 @@ def get_valuation_rate(item_code, warehouse, posting_date): valuation_rate = flt(last_valuation_rate[0][0]) if last_valuation_rate else 0 if not valuation_rate: - valuation_rate = frappe.db.get_value("Item Price", {"item_code": item_code, "buying": 1}, "price") + valuation_rate = frappe.db.get_value("Item Price", {"item_code": item_code, "buying": 1}, "price_list_rate") return valuation_rate diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index b4fa9712f9..3046c5e921 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -97,10 +97,10 @@ class LandedCostVoucher(Document): # update stock & gl entries for cancelled state of PR pr.docstatus = 2 - pr.update_stock() + pr.update_stock_ledger() pr.make_gl_entries_on_cancel() # update stock & gl entries for submit state of PR pr.docstatus = 1 - pr.update_stock() + pr.update_stock_ledger() pr.make_gl_entries() diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index a7fa6bb88e..fc35222bb0 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -130,7 +130,7 @@ class PurchaseReceipt(BuyingController): if not d.prevdoc_docname: frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code)) - def update_stock(self): + def update_stock_ledger(self): sl_entries = [] stock_items = self.get_stock_items() @@ -234,7 +234,7 @@ class PurchaseReceipt(BuyingController): self.update_ordered_qty() - self.update_stock() + self.update_stock_ledger() from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit update_serial_nos_after_submit(self, "purchase_receipt_details") @@ -267,7 +267,7 @@ class PurchaseReceipt(BuyingController): self.update_ordered_qty() - self.update_stock() + self.update_stock_ledger() self.update_prevdoc_status() pc_obj.update_last_purchase_rate(self, 0) @@ -283,8 +283,11 @@ 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): + def get_gl_entries(self, warehouse_account=None, allow_negative_stock=False): 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") diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 4f3480c0bb..4cc96bfec7 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -527,7 +527,7 @@ class StockEntry(StockController): } }, bom_no=self.bom_no) - self.get_stock_and_rate() + self.e() def get_bom_raw_materials(self, qty): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 8e837e275c..6c3c395d88 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -22,7 +22,7 @@ class StockReconciliation(StockController): self.validate_expense_account() def on_submit(self): - self.insert_stock_ledger_entries() + self.update_stock_ledger() self.make_gl_entries() def on_cancel(self): @@ -126,7 +126,7 @@ class StockReconciliation(StockController): except Exception, e: self.validation_messages.append(_("Row # ") + ("%d: " % (row_num)) + cstr(e)) - def insert_stock_ledger_entries(self): + def update_stock_ledger(self): """ find difference between current and expected entries and create stock ledger entries based on the difference""" from erpnext.stock.stock_ledger import get_previous_sle @@ -155,8 +155,8 @@ class StockReconciliation(StockController): if row.valuation_rate in ("", None): row.valuation_rate = previous_sle.get("valuation_rate") - if row.qty and not row.valuation_rate: - frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code)) + # if row.qty and not row.valuation_rate: + # frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code)) self.insert_entries(row) diff --git a/erpnext/stock/page/stock_balance/stock_balance.js b/erpnext/stock/page/stock_balance/stock_balance.js index c2ffc3701b..7405227116 100644 --- a/erpnext/stock/page/stock_balance/stock_balance.js +++ b/erpnext/stock/page/stock_balance/stock_balance.js @@ -105,12 +105,14 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({ var is_fifo = valuation_method == "FIFO"; if(sl.voucher_type=="Stock Reconciliation") { - var qty_diff = sl.qty_after_trasaction - item.closing_qty; - var value_diff = (sl.valuation_rate * sl.qty_after_trasaction) - item.closing_value; + var qty_diff = sl.qty_after_transaction - (item.temp_closing_qty || 0.0); + var value_diff = (sl.valuation_rate * sl.qty_after_transaction) - (item.temp_closing_value || 0.0); } else { var qty_diff = sl.qty; var value_diff = me.get_value_diff(wh, sl, is_fifo); } + item.temp_closing_qty += qty_diff; + item.temp_closing_value += value_diff; if(sl_posting_date < from_date) { item.opening_qty += qty_diff; diff --git a/erpnext/utilities/repost_stock.py b/erpnext/utilities/repost_stock.py index 4c145487d8..9c3bf1d0e9 100644 --- a/erpnext/utilities/repost_stock.py +++ b/erpnext/utilities/repost_stock.py @@ -209,3 +209,30 @@ def reset_serial_no_status_and_warehouse(serial_nos=None): frappe.db.sql("""update `tabSerial No` set warehouse='' where status in ('Delivered', 'Purchase Returned')""") +def repost_all_stock_vouchers(): + vouchers = frappe.db.sql("""select distinct voucher_type, voucher_no + from `tabStock Ledger Entry` order by posting_date, posting_time, name""") + + rejected = [] + i = 0 + for voucher_type, voucher_no in vouchers: + i += 1 + print voucher_type, voucher_no + try: + for dt in ["Stock Ledger Entry", "GL Entry"]: + frappe.db.sql("""delete from `tab%s` where voucher_type=%s and voucher_no=%s"""% + (dt, '%s', '%s'), (voucher_type, voucher_no)) + + doc = frappe.get_doc(voucher_type, voucher_no) + if voucher_type=="Stock Entry" and doc.purpose in ["Manufacture", "Repack"]: + doc.get_stock_and_rate(force=1) + doc.update_stock_ledger() + doc.make_gl_entries() + if i%100 == 0: + frappe.db.commit() + except: + rejected.append([voucher_type, voucher_no]) + pass + + print rejected +