perf: stock ageing and batch-wise balance history report

This commit is contained in:
Rohit Waghchaure
2024-04-23 06:56:41 +05:30
parent d5784cc629
commit 6017e7ac3e
4 changed files with 61 additions and 17 deletions

View File

@@ -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 }),
},
};
},

View File

@@ -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))

View File

@@ -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 }),
},
};

View File

@@ -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")