diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 11ac703311..f352bae30e 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -495,7 +495,7 @@ class StockController(AccountsController): "voucher_no": self.name, "company": self.company }) - if check_if_future_sle_exists(args): + if future_sle_exists(args): create_repost_item_valuation_entry(args) elif not is_reposting_pending(): check_if_stock_and_account_balance_synced(self.posting_date, @@ -506,37 +506,42 @@ def is_reposting_pending(): {'docstatus': 1, 'status': ['in', ['Queued','In Progress']]}) -def check_if_future_sle_exists(args): - sl_entries = frappe.db.get_all("Stock Ledger Entry", +def future_sle_exists(args): + sl_entries = frappe.get_all("Stock Ledger Entry", filters={"voucher_type": args.voucher_type, "voucher_no": args.voucher_no}, fields=["item_code", "warehouse"], order_by="creation asc") - distinct_item_warehouses = list(set([(d.item_code, d.warehouse) for d in sl_entries])) + if not sl_entries: + return - sle_exists = False - for item_code, warehouse in distinct_item_warehouses: - args.update({ - "item_code": item_code, - "warehouse": warehouse - }) - if get_sle(args): - sle_exists = True - break - return sle_exists + warehouse_items_map = {} + for entry in sl_entries: + if entry.warehouse not in warehouse_items_map: + warehouse_items_map[entry.warehouse] = set() + + warehouse_items_map[entry.warehouse].add(entry.item_code) + + or_conditions = [] + for warehouse, items in warehouse_items_map.items(): + or_conditions.append( + "warehouse = '{}' and item_code in ({})".format( + warehouse, + ", ".join(frappe.db.escape(item) for item in items) + ) + ) -def get_sle(args): return frappe.db.sql(""" select name from `tabStock Ledger Entry` where - item_code=%(item_code)s - and warehouse=%(warehouse)s - and timestamp(posting_date, posting_time) >= timestamp(%(posting_date)s, %(posting_time)s) + ({}) + and timestamp(posting_date, posting_time) + >= timestamp(%(posting_date)s, %(posting_time)s) and voucher_no != %(voucher_no)s and is_cancelled = 0 limit 1 - """, args) + """.format(" or ".join(or_conditions)), args) def create_repost_item_valuation_entry(args): args = frappe._dict(args) @@ -554,4 +559,4 @@ def create_repost_item_valuation_entry(args): repost_entry.allow_zero_rate = args.allow_zero_rate repost_entry.flags.ignore_links = True repost_entry.save() - repost_entry.submit() \ No newline at end of file + repost_entry.submit() diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index f54b3c1bb2..121c51cf6a 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -207,11 +207,11 @@ class update_entries_after(object): def build(self): - from erpnext.controllers.stock_controller import check_if_future_sle_exists + from erpnext.controllers.stock_controller import future_sle_exists if self.args.get("sle_id"): self.process_sle_against_current_timestamp() - if not check_if_future_sle_exists(self.args): + if not future_sle_exists(self.args): self.update_bin() else: entries_to_fix = self.get_future_entries_to_fix() @@ -856,4 +856,4 @@ def get_future_sle_with_negative_qty(args): and qty_after_transaction < 0 order by timestamp(posting_date, posting_time) asc limit 1 - """, args, as_dict=1) \ No newline at end of file + """, args, as_dict=1)