fix: (enhance) BOM Operations Report

- Added filters in the Report for BOM ID, Item Code and Workstation
- Converted Raw SQL to frappe.qb and added method to get filtered data
- Changed fieldtype of 'Time in mins' from Int to Float
- Get BOM wise grouped data to  keep order and accurate grouping in report
This commit is contained in:
marination 2022-01-20 13:36:46 +05:30
parent c8489d630b
commit a9ff1fc52e
2 changed files with 89 additions and 24 deletions

View File

@ -4,6 +4,39 @@
frappe.query_reports["BOM Operations Time"] = {
"filters": [
{
"fieldname": "item_code",
"label": __("Item Code"),
"fieldtype": "Link",
"width": "100",
"options": "Item",
"get_query": () =>{
return {
filters: { "disabled": 0, "is_stock_item": 1 }
}
}
},
{
"fieldname": "bom_id",
"label": __("BOM ID"),
"fieldtype": "MultiSelectList",
"width": "80",
"options": "BOM",
"get_data": function(txt) {
return frappe.db.get_link_options("BOM", txt);
},
"get_query": () =>{
return {
filters: { "docstatus": 1, "is_active": 1 }
}
}
},
{
"fieldname": "workstation",
"label": __("Workstation"),
"fieldtype": "Link",
"width": "100",
"options": "Workstation"
},
]
};

View File

@ -4,7 +4,8 @@
import frappe
from frappe import _
from frappe.model.meta import get_field_precision
from frappe.utils import flt
def execute(filters=None):
data = get_data(filters)
@ -12,19 +13,15 @@ def execute(filters=None):
return columns, data
def get_data(filters):
data = []
bom_wise_data = {}
bom_data, report_data = [], []
bom_data = []
for d in frappe.db.sql("""
SELECT
bom.name, bom.item, bom.item_name, bom.uom,
bomps.operation, bomps.workstation, bomps.time_in_mins
FROM `tabBOM` bom, `tabBOM Operation` bomps
WHERE
bom.docstatus = 1 and bom.is_active = 1 and bom.name = bomps.parent
""", as_dict=1):
bom_operation_data = get_filtered_data(filters)
for d in bom_operation_data:
row = get_args()
if d.name not in bom_data:
bom_wise_data[d.name] = []
bom_data.append(d.name)
row.update(d)
else:
@ -34,14 +31,49 @@ def get_data(filters):
"time_in_mins": d.time_in_mins
})
data.append(row)
# maintain BOM wise data for grouping such as:
# {"BOM A": [{Row1}, {Row2}], "BOM B": ...}
bom_wise_data[d.name].append(row)
used_as_subassembly_items = get_bom_count(bom_data)
for d in data:
d.used_as_subassembly_items = used_as_subassembly_items.get(d.name, 0)
for d in bom_wise_data:
for row in bom_wise_data[d]:
row.used_as_subassembly_items = used_as_subassembly_items.get(row.name, 0)
report_data.append(row)
return data
return report_data
def get_filtered_data(filters):
bom = frappe.qb.DocType("BOM")
bom_ops = frappe.qb.DocType("BOM Operation")
bom_ops_query = (
frappe.qb.from_(bom)
.join(bom_ops).on(bom.name == bom_ops.parent)
.select(
bom.name, bom.item, bom.item_name, bom.uom,
bom_ops.operation, bom_ops.workstation, bom_ops.time_in_mins
).where(
(bom.docstatus == 1)
& (bom.is_active == 1)
)
)
if filters.get("item_code"):
bom_ops_query = bom_ops_query.where(bom.item == filters.get("item_code"))
if filters.get("bom_id"):
bom_ops_query = bom_ops_query.where(bom.name.isin(filters.get("bom_id")))
if filters.get("workstation"):
bom_ops_query = bom_ops_query.where(
bom_ops.workstation == filters.get("workstation")
)
bom_operation_data = bom_ops_query.run(as_dict=True)
return bom_operation_data
def get_bom_count(bom_data):
data = frappe.get_all("BOM Item",
@ -68,13 +100,13 @@ def get_columns(filters):
"options": "BOM",
"fieldname": "name",
"fieldtype": "Link",
"width": 140
"width": 220
}, {
"label": _("BOM Item Code"),
"label": _("Item Code"),
"options": "Item",
"fieldname": "item",
"fieldtype": "Link",
"width": 140
"width": 150
}, {
"label": _("Item Name"),
"fieldname": "item_name",
@ -85,13 +117,13 @@ def get_columns(filters):
"options": "UOM",
"fieldname": "uom",
"fieldtype": "Link",
"width": 140
"width": 100
}, {
"label": _("Operation"),
"options": "Operation",
"fieldname": "operation",
"fieldtype": "Link",
"width": 120
"width": 140
}, {
"label": _("Workstation"),
"options": "Workstation",
@ -101,11 +133,11 @@ def get_columns(filters):
}, {
"label": _("Time (In Mins)"),
"fieldname": "time_in_mins",
"fieldtype": "Int",
"width": 140
"fieldtype": "Float",
"width": 120
}, {
"label": _("Sub-assembly BOM Count"),
"fieldname": "used_as_subassembly_items",
"fieldtype": "Int",
"width": 180
"width": 200
}]