Skip to content

Commit

Permalink
feat: Manufacturing : in BOM Operation time can be fix (#27063)
Browse files Browse the repository at this point in the history
* feat: Operation time can be fixed

* better coding without duplicate code

* change modified date foir doctype

* undo change

* fix varmixing

* fix varmixing

* fix: remove f-string that's not required anymore

* refactor: use ORM instead of raw query

* fix: improve description

* test: basic test for fixed time

Co-authored-by: Ankush Menat <ankush@frappe.io>
  • Loading branch information
FHenry and ankush authored Dec 15, 2021
1 parent 66f5165 commit 29f6852
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 14 deletions.
2 changes: 1 addition & 1 deletion erpnext/manufacturing/doctype/bom/bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ def validate_bom_no(item, bom_no):
rm_item_exists = True
if bom.item.lower() == item.lower() or \
bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower():
rm_item_exists = True
rm_item_exists = True
if not rm_item_exists:
frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))

Expand Down
14 changes: 12 additions & 2 deletions erpnext/manufacturing/doctype/bom_operation/bom_operation.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"col_break1",
"workstation",
"time_in_mins",
"fixed_time",
"costing_section",
"hour_rate",
"base_hour_rate",
Expand Down Expand Up @@ -79,6 +80,14 @@
"oldfieldtype": "Currency",
"reqd": 1
},
{
"default": "0",
"description": "Operation time does not depend on quantity to produce",
"fieldname": "fixed_time",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Fixed Time"
},
{
"fieldname": "operating_cost",
"fieldtype": "Currency",
Expand Down Expand Up @@ -177,12 +186,13 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-09-13 16:45:01.092868",
"modified": "2021-12-15 03:00:00.473173",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Operation",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
"sort_order": "DESC",
"states": []
}
39 changes: 39 additions & 0 deletions erpnext/manufacturing/doctype/work_order/test_work_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,45 @@ def test_close_work_order(self):
close_work_order(wo_order, "Closed")
self.assertEqual(wo_order.get('status'), "Closed")

def test_fix_time_operations(self):
bom = frappe.get_doc({
"doctype": "BOM",
"item": "_Test FG Item 2",
"is_active": 1,
"is_default": 1,
"quantity": 1.0,
"with_operations": 1,
"operations": [
{
"operation": "_Test Operation 1",
"description": "_Test",
"workstation": "_Test Workstation 1",
"time_in_mins": 60,
"operating_cost": 140,
"fixed_time": 1
}
],
"items": [
{
"amount": 5000.0,
"doctype": "BOM Item",
"item_code": "_Test Item",
"parentfield": "items",
"qty": 1.0,
"rate": 5000.0,
},
],
})
bom.save()
bom.submit()


wo1 = make_wo_order_test_record(item=bom.item, bom_no=bom.name, qty=1, skip_transfer=1, do_not_submit=1)
wo2 = make_wo_order_test_record(item=bom.item, bom_no=bom.name, qty=2, skip_transfer=1, do_not_submit=1)

self.assertEqual(wo1.operations[0].time_in_mins, wo2.operations[0].time_in_mins)


def update_job_card(job_card):
job_card_doc = frappe.get_doc('Job Card', job_card)
job_card_doc.set('scrap_items', [
Expand Down
26 changes: 15 additions & 11 deletions erpnext/manufacturing/doctype/work_order/work_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,16 +505,19 @@ def set_work_order_operations(self):
"""Fetch operations from BOM and set in 'Work Order'"""

def _get_operations(bom_no, qty=1):
return frappe.db.sql(
f"""select
operation, description, workstation, idx,
base_hour_rate as hour_rate, time_in_mins * {qty} as time_in_mins,
"Pending" as status, parent as bom, batch_size, sequence_id
from
`tabBOM Operation`
where
parent = %s order by idx
""", bom_no, as_dict=1)
data = frappe.get_all("BOM Operation",
filters={"parent": bom_no},
fields=["operation", "description", "workstation", "idx",
"base_hour_rate as hour_rate", "time_in_mins", "parent as bom",
"batch_size", "sequence_id", "fixed_time"],
order_by="idx")

for d in data:
if not d.fixed_time:
d.time_in_mins = flt(d.time_in_mins) * flt(qty)
d.status = "Pending"

return data


self.set('operations', [])
Expand Down Expand Up @@ -542,7 +545,8 @@ def _get_operations(bom_no, qty=1):

def calculate_time(self):
for d in self.get("operations"):
d.time_in_mins = flt(d.time_in_mins) * (flt(self.qty) / flt(d.batch_size))
if not d.fixed_time:
d.time_in_mins = flt(d.time_in_mins) * (flt(self.qty) / flt(d.batch_size))

self.calculate_operating_cost()

Expand Down

0 comments on commit 29f6852

Please sign in to comment.