From ca9f93cdc23d6ab5732cff26bf309c88a3618110 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 20 Mar 2019 02:06:39 +0530 Subject: [PATCH] feat: Stock ageing warehouse wise --- .../stock/report/stock_ageing/stock_ageing.js | 8 +++- .../stock/report/stock_ageing/stock_ageing.py | 45 ++++++++++++++----- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.js b/erpnext/stock/report/stock_ageing/stock_ageing.js index 60e64b77f4c..aad8df426a8 100644 --- a/erpnext/stock/report/stock_ageing/stock_ageing.js +++ b/erpnext/stock/report/stock_ageing/stock_ageing.js @@ -13,7 +13,7 @@ frappe.query_reports["Stock Ageing"] = { }, { "fieldname":"to_date", - "label": __("To Date"), + "label": __("As On Date"), "fieldtype": "Date", "default": frappe.datetime.get_today(), "reqd": 1 @@ -35,6 +35,12 @@ frappe.query_reports["Stock Ageing"] = { "label": __("Brand"), "fieldtype": "Link", "options": "Brand" + }, + { + "fieldname":"show_ageing_warehouse_wise", + "label": __("Show Ageing Warehouse-wise"), + "fieldtype": "Check", + "default": 0 } ] } \ No newline at end of file diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py index ae3d72ee4fa..969284598c4 100644 --- a/erpnext/stock/report/stock_ageing/stock_ageing.py +++ b/erpnext/stock/report/stock_ageing/stock_ageing.py @@ -9,7 +9,7 @@ from six import iteritems def execute(filters=None): - columns = get_columns() + columns = get_columns(filters) item_details = get_fifo_queue(filters) to_date = filters["to_date"] data = [] @@ -22,8 +22,16 @@ def execute(filters=None): earliest_age = date_diff(to_date, fifo_queue[0][1]) latest_age = date_diff(to_date, fifo_queue[-1][1]) - data.append([item, details.item_name, details.description, details.item_group, - details.brand, average_age, earliest_age, latest_age, details.stock_uom]) + row = [details.name, details.item_name, + details.description, details.item_group, details.brand] + + if filters.get("show_ageing_warehouse_wise"): + row.append(details.warehouse) + + row.extend([item_dict.get("total_qty"), average_age, + earliest_age, latest_age, details.stock_uom]) + + data.append(row) return columns, data @@ -36,19 +44,27 @@ def get_average_age(fifo_queue, to_date): return (age_qty / total_qty) if total_qty else 0.0 -def get_columns(): - return [_("Item Code") + ":Link/Item:100", _("Item Name") + "::100", _("Description") + "::200", - _("Item Group") + ":Link/Item Group:100", _("Brand") + ":Link/Brand:100", _("Average Age") + ":Float:100", - _("Earliest") + ":Int:80", _("Latest") + ":Int:80", _("UOM") + ":Link/UOM:100"] +def get_columns(filters): + columns = [_("Item Code") + ":Link/Item:100", _("Item Name") + "::100", _("Description") + "::200", + _("Item Group") + ":Link/Item Group:100", _("Brand") + ":Link/Brand:100"] + + if filters.get("show_ageing_warehouse_wise"): + columns.extend([_("Warehouse") + ":Link/Warehouse:100"]) + + columns.extend([_("Available Qty") + ":Float:100", _("Average Age") + ":Float:100", + _("Earliest") + ":Int:80", _("Latest") + ":Int:80", _("UOM") + ":Link/UOM:100"]) + + return columns def get_fifo_queue(filters): item_details = {} for d in get_stock_ledger_entries(filters): - item_details.setdefault(d.name, {"details": d, "fifo_queue": []}) - fifo_queue = item_details[d.name]["fifo_queue"] + key = (d.name, d.warehouse) if filters.get('show_ageing_warehouse_wise') else d.name + item_details.setdefault(key, {"details": d, "fifo_queue": []}) + fifo_queue = item_details[key]["fifo_queue"] if d.voucher_type == "Stock Reconciliation": - d.actual_qty = flt(d.qty_after_transaction) - flt(item_details[d.name].get("qty_after_transaction", 0)) + d.actual_qty = flt(d.qty_after_transaction) - flt(item_details[key].get("qty_after_transaction", 0)) if d.actual_qty > 0: fifo_queue.append([d.actual_qty, d.posting_date]) @@ -66,14 +82,19 @@ def get_fifo_queue(filters): batch[0] -= qty_to_pop qty_to_pop = 0 - item_details[d.name]["qty_after_transaction"] = d.qty_after_transaction + item_details[key]["qty_after_transaction"] = d.qty_after_transaction + + if "total_qty" not in item_details[key]: + item_details[key]["total_qty"] = d.actual_qty + else: + item_details[key]["total_qty"] += d.actual_qty return item_details def get_stock_ledger_entries(filters): return frappe.db.sql("""select item.name, item.item_name, item_group, brand, description, item.stock_uom, - actual_qty, posting_date, voucher_type, qty_after_transaction + actual_qty, posting_date, voucher_type, qty_after_transaction, warehouse from `tabStock Ledger Entry` sle, (select name, item_name, description, stock_uom, brand, item_group from `tabItem` {item_conditions}) item