From ff9a6e8e899a8a2e23a9cad0220abf130a5d5ced Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 20 Dec 2021 15:07:41 +0530 Subject: [PATCH] fix: correct bin qty on backdated transactions When making a backdated transactions current balance qty depends on evaluation of whole ledger inbetween, instead of doing that just fetch the last sle's qty_after_transaction when future transactions are detected against SLE fix: don't update bin's actual_qty 1. it's already updated by repost_current_voucher 2. update if future sle exists --- erpnext/stock/doctype/bin/bin.py | 24 +++++++++++++++++------- erpnext/stock/stock_ledger.py | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py index 37b54116a4..0ef7ce2923 100644 --- a/erpnext/stock/doctype/bin/bin.py +++ b/erpnext/stock/doctype/bin/bin.py @@ -130,8 +130,8 @@ def update_stock(bin_name, args, allow_negative_stock=False, via_landed_cost_vou """WARNING: This function is deprecated. Inline this function instead of using it.""" from erpnext.stock.stock_ledger import repost_current_voucher - update_qty(bin_name, args) repost_current_voucher(args, allow_negative_stock, via_landed_cost_voucher) + update_qty(bin_name, args) def get_bin_details(bin_name): return frappe.db.get_value('Bin', bin_name, ['actual_qty', 'ordered_qty', @@ -139,13 +139,23 @@ def get_bin_details(bin_name): 'reserved_qty_for_sub_contract'], as_dict=1) def update_qty(bin_name, args): - bin_details = get_bin_details(bin_name) + from erpnext.controllers.stock_controller import future_sle_exists - # update the stock values (for current quantities) - if args.get("voucher_type")=="Stock Reconciliation": - actual_qty = args.get('qty_after_transaction') - else: - actual_qty = bin_details.actual_qty + flt(args.get("actual_qty")) + bin_details = get_bin_details(bin_name) + # actual qty is already updated by processing current voucher + actual_qty = bin_details.actual_qty + + # actual qty is not up to date in case of backdated transaction + if future_sle_exists(args): + actual_qty = frappe.db.get_value("Stock Ledger Entry", + filters={ + "item_code": args.get("item_code"), + "warehouse": args.get("warehouse"), + "is_cancelled": 0 + }, + fieldname="qty_after_transaction", + order_by="posting_date desc, posting_time desc, creation desc", + ) or 0.0 ordered_qty = flt(bin_details.ordered_qty) + flt(args.get("ordered_qty")) reserved_qty = flt(bin_details.reserved_qty) + flt(args.get("reserved_qty")) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index f45bee1650..107bb23222 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -65,8 +65,8 @@ def make_sl_entries(sl_entries, allow_negative_stock=False, via_landed_cost_vouc is_stock_item = frappe.get_cached_value('Item', args.get("item_code"), 'is_stock_item') if is_stock_item: bin_name = get_or_make_bin(args.get("item_code"), args.get("warehouse")) - update_bin_qty(bin_name, args) repost_current_voucher(args, allow_negative_stock, via_landed_cost_voucher) + update_bin_qty(bin_name, args) else: frappe.msgprint(_("Item {0} ignored since it is not a stock item").format(args.get("item_code")))