From 6017e7ac3e876f70e0e696bd24abea5a80756702 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 23 Apr 2024 06:56:41 +0530 Subject: [PATCH] perf: stock ageing and batch-wise balance history report --- .../batch_wise_balance_history.js | 14 +++++- .../batch_wise_balance_history.py | 10 +++++ .../stock/report/stock_ageing/stock_ageing.js | 10 +++++ .../stock/report/stock_ageing/stock_ageing.py | 44 ++++++++++++------- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.js b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.js index 1694abe7c08..401ebe43028 100644 --- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.js +++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.js @@ -40,16 +40,26 @@ frappe.query_reports["Batch-Wise Balance History"] = { }; }, }, + { + fieldname: "warehouse_type", + label: __("Warehouse Type"), + fieldtype: "Link", + width: "80", + options: "Warehouse Type", + }, { fieldname: "warehouse", label: __("Warehouse"), fieldtype: "Link", options: "Warehouse", get_query: function () { - let company = frappe.query_report.get_filter_value("company"); + let warehouse_type = frappe.query_report.get_filter_value("warehouse_type"); + const company = frappe.query_report.get_filter_value("company"); + return { filters: { - company: company, + ...(warehouse_type && { warehouse_type }), + ...(company && { company }), }, }; }, diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py index 50b5efd6a08..c8c26fd66cb 100644 --- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py +++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py @@ -113,6 +113,16 @@ def get_stock_ledger_entries(filters): ) query = apply_warehouse_filter(query, sle, filters) + if filters.warehouse_type and not filters.warehouse: + warehouses = frappe.get_all( + "Warehouse", + filters={"warehouse_type": filters.warehouse_type, "is_group": 0}, + pluck="name", + ) + + if warehouses: + query = query.where(sle.warehouse.isin(warehouses)) + for field in ["item_code", "batch_no", "company"]: if filters.get(field): query = query.where(sle[field] == filters.get(field)) diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.js b/erpnext/stock/report/stock_ageing/stock_ageing.js index 641084149ab..726b507663d 100644 --- a/erpnext/stock/report/stock_ageing/stock_ageing.js +++ b/erpnext/stock/report/stock_ageing/stock_ageing.js @@ -18,15 +18,25 @@ frappe.query_reports["Stock Ageing"] = { default: frappe.datetime.get_today(), reqd: 1, }, + { + fieldname: "warehouse_type", + label: __("Warehouse Type"), + fieldtype: "Link", + width: "80", + options: "Warehouse Type", + }, { fieldname: "warehouse", label: __("Warehouse"), fieldtype: "Link", options: "Warehouse", get_query: () => { + let warehouse_type = frappe.query_report.get_filter_value("warehouse_type"); const company = frappe.query_report.get_filter_value("company"); + return { filters: { + ...(warehouse_type && { warehouse_type }), ...(company && { company }), }, }; diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py index a1aee987cb6..26bf99e1ed7 100644 --- a/erpnext/stock/report/stock_ageing/stock_ageing.py +++ b/erpnext/stock/report/stock_ageing/stock_ageing.py @@ -227,25 +227,30 @@ class FIFOSlots: consumed/updated and maintained via FIFO. ** } """ - if self.sle is None: - self.sle = self.__get_stock_ledger_entries() + stock_ledger_entries = self.sle - for d in self.sle: - key, fifo_queue, transferred_item_key = self.__init_key_stores(d) + with frappe.db.unbuffered_cursor(): + if self.sle is None: + self.sle = self.__get_stock_ledger_entries() - if d.voucher_type == "Stock Reconciliation": - # get difference in qty shift as actual qty - prev_balance_qty = self.item_details[key].get("qty_after_transaction", 0) - d.actual_qty = flt(d.qty_after_transaction) - flt(prev_balance_qty) + for d in self.sle: + key, fifo_queue, transferred_item_key = self.__init_key_stores(d) - serial_nos = get_serial_nos(d.serial_no) if d.serial_no else [] + if d.voucher_type == "Stock Reconciliation": + # get difference in qty shift as actual qty + prev_balance_qty = self.item_details[key].get("qty_after_transaction", 0) + d.actual_qty = flt(d.qty_after_transaction) - flt(prev_balance_qty) - if d.actual_qty > 0: - self.__compute_incoming_stock(d, fifo_queue, transferred_item_key, serial_nos) - else: - self.__compute_outgoing_stock(d, fifo_queue, transferred_item_key, serial_nos) + serial_nos = get_serial_nos(d.serial_no) if d.serial_no else [] - self.__update_balances(d, key) + if d.actual_qty > 0: + self.__compute_incoming_stock(d, fifo_queue, transferred_item_key, serial_nos) + else: + self.__compute_outgoing_stock(d, fifo_queue, transferred_item_key, serial_nos) + + self.__update_balances(d, key) + + del stock_ledger_entries if not self.filters.get("show_warehouse_wise_stock"): # (Item 1, WH 1), (Item 1, WH 2) => (Item 1) @@ -412,10 +417,19 @@ class FIFOSlots: if self.filters.get("warehouse"): sle_query = self.__get_warehouse_conditions(sle, sle_query) + elif self.filters.get("warehouse_type"): + warehouses = frappe.get_all( + "Warehouse", + filters={"warehouse_type": self.filters.get("warehouse_type"), "is_group": 0}, + pluck="name", + ) + + if warehouses: + sle_query = sle_query.where(sle.warehouse.isin(warehouses)) sle_query = sle_query.orderby(sle.posting_date, sle.posting_time, sle.creation, sle.actual_qty) - return sle_query.run(as_dict=True) + return sle_query.run(as_dict=True, as_iterator=True) def __get_item_query(self) -> str: item_table = frappe.qb.DocType("Item")