From 67d828dab36d6f64fdb41e5f2cd203d508d2998c Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Sat, 27 Jan 2024 12:00:06 +0530 Subject: [PATCH] fix: not able to save subcontracting purchase receipt (old flow) (#39590) --- .../controllers/subcontracting_controller.py | 4 +- erpnext/stock/utils.py | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index 9555902a74..65d087261f 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -881,7 +881,9 @@ class SubcontractingController(StockController): "posting_time": self.posting_time, "qty": -1 * item.consumed_qty, "voucher_detail_no": item.name, - "serial_and_batch_bundle": item.serial_and_batch_bundle, + "serial_and_batch_bundle": item.get("serial_and_batch_bundle"), + "serial_no": item.get("serial_no"), + "batch_no": item.get("batch_no"), } ) diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index f29e7ea6a1..76af5d7e3e 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -289,6 +289,21 @@ def get_incoming_rate(args, raise_error_if_no_rate=True): in_rate = batch_obj.get_incoming_rate() + elif (args.get("serial_no") or "").strip() and not args.get("serial_and_batch_bundle"): + in_rate = get_avg_purchase_rate(args.get("serial_no")) + elif ( + args.get("batch_no") + and frappe.db.get_value("Batch", args.get("batch_no"), "use_batchwise_valuation", cache=True) + and not args.get("serial_and_batch_bundle") + ): + in_rate = get_batch_incoming_rate( + item_code=args.get("item_code"), + warehouse=args.get("warehouse"), + batch_no=args.get("batch_no"), + posting_date=args.get("posting_date"), + posting_time=args.get("posting_time"), + ) + else: valuation_method = get_valuation_method(args.get("item_code")) previous_sle = get_previous_sle(args) @@ -319,6 +334,38 @@ def get_incoming_rate(args, raise_error_if_no_rate=True): return flt(in_rate) +def get_batch_incoming_rate( + item_code, warehouse, batch_no, posting_date, posting_time, creation=None +): + + sle = frappe.qb.DocType("Stock Ledger Entry") + + timestamp_condition = CombineDatetime(sle.posting_date, sle.posting_time) < CombineDatetime( + posting_date, posting_time + ) + if creation: + timestamp_condition |= ( + CombineDatetime(sle.posting_date, sle.posting_time) + == CombineDatetime(posting_date, posting_time) + ) & (sle.creation < creation) + + batch_details = ( + frappe.qb.from_(sle) + .select(Sum(sle.stock_value_difference).as_("batch_value"), Sum(sle.actual_qty).as_("batch_qty")) + .where( + (sle.item_code == item_code) + & (sle.warehouse == warehouse) + & (sle.batch_no == batch_no) + & (sle.serial_and_batch_bundle.isnull()) + & (sle.is_cancelled == 0) + ) + .where(timestamp_condition) + ).run(as_dict=True) + + if batch_details and batch_details[0].batch_qty: + return batch_details[0].batch_value / batch_details[0].batch_qty + + def get_avg_purchase_rate(serial_nos): """get average value of serial numbers"""