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:
parent
c8489d630b
commit
a9ff1fc52e
@ -4,6 +4,39 @@
|
|||||||
|
|
||||||
frappe.query_reports["BOM Operations Time"] = {
|
frappe.query_reports["BOM Operations Time"] = {
|
||||||
"filters": [
|
"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"
|
||||||
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from frappe.model.meta import get_field_precision
|
||||||
|
from frappe.utils import flt
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
data = get_data(filters)
|
data = get_data(filters)
|
||||||
@ -12,19 +13,15 @@ def execute(filters=None):
|
|||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
def get_data(filters):
|
def get_data(filters):
|
||||||
data = []
|
bom_wise_data = {}
|
||||||
|
bom_data, report_data = [], []
|
||||||
|
|
||||||
bom_data = []
|
bom_operation_data = get_filtered_data(filters)
|
||||||
for d in frappe.db.sql("""
|
|
||||||
SELECT
|
for d in bom_operation_data:
|
||||||
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):
|
|
||||||
row = get_args()
|
row = get_args()
|
||||||
if d.name not in bom_data:
|
if d.name not in bom_data:
|
||||||
|
bom_wise_data[d.name] = []
|
||||||
bom_data.append(d.name)
|
bom_data.append(d.name)
|
||||||
row.update(d)
|
row.update(d)
|
||||||
else:
|
else:
|
||||||
@ -34,14 +31,49 @@ def get_data(filters):
|
|||||||
"time_in_mins": d.time_in_mins
|
"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)
|
used_as_subassembly_items = get_bom_count(bom_data)
|
||||||
|
|
||||||
for d in data:
|
for d in bom_wise_data:
|
||||||
d.used_as_subassembly_items = used_as_subassembly_items.get(d.name, 0)
|
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):
|
def get_bom_count(bom_data):
|
||||||
data = frappe.get_all("BOM Item",
|
data = frappe.get_all("BOM Item",
|
||||||
@ -68,13 +100,13 @@ def get_columns(filters):
|
|||||||
"options": "BOM",
|
"options": "BOM",
|
||||||
"fieldname": "name",
|
"fieldname": "name",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"width": 140
|
"width": 220
|
||||||
}, {
|
}, {
|
||||||
"label": _("BOM Item Code"),
|
"label": _("Item Code"),
|
||||||
"options": "Item",
|
"options": "Item",
|
||||||
"fieldname": "item",
|
"fieldname": "item",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"width": 140
|
"width": 150
|
||||||
}, {
|
}, {
|
||||||
"label": _("Item Name"),
|
"label": _("Item Name"),
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
@ -85,13 +117,13 @@ def get_columns(filters):
|
|||||||
"options": "UOM",
|
"options": "UOM",
|
||||||
"fieldname": "uom",
|
"fieldname": "uom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"width": 140
|
"width": 100
|
||||||
}, {
|
}, {
|
||||||
"label": _("Operation"),
|
"label": _("Operation"),
|
||||||
"options": "Operation",
|
"options": "Operation",
|
||||||
"fieldname": "operation",
|
"fieldname": "operation",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"width": 120
|
"width": 140
|
||||||
}, {
|
}, {
|
||||||
"label": _("Workstation"),
|
"label": _("Workstation"),
|
||||||
"options": "Workstation",
|
"options": "Workstation",
|
||||||
@ -101,11 +133,11 @@ def get_columns(filters):
|
|||||||
}, {
|
}, {
|
||||||
"label": _("Time (In Mins)"),
|
"label": _("Time (In Mins)"),
|
||||||
"fieldname": "time_in_mins",
|
"fieldname": "time_in_mins",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Float",
|
||||||
"width": 140
|
"width": 120
|
||||||
}, {
|
}, {
|
||||||
"label": _("Sub-assembly BOM Count"),
|
"label": _("Sub-assembly BOM Count"),
|
||||||
"fieldname": "used_as_subassembly_items",
|
"fieldname": "used_as_subassembly_items",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"width": 180
|
"width": 200
|
||||||
}]
|
}]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user