feat: Only update exploded items rate and amount
- Generate RM-Rate map from Items table (will include subassembly items with rate) - Function to reset exploded item rate from above map - `db_update` exploded item rate only if rate is changed - Via Update Cost, only update exploded items rate, do not regenerate table again - Exploded Items are regenerated on Save and Replace BOM job - `calculate_exploded_cost` is run only via non doc events (Update Cost button, Update BOMs Cost Job)
This commit is contained in:
parent
9f5f18e94d
commit
eabd8290d4
@ -5,7 +5,7 @@ import functools
|
|||||||
import re
|
import re
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from typing import List
|
from typing import Dict, List
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
@ -185,6 +185,7 @@ class BOM(WebsiteGenerator):
|
|||||||
self.validate_transfer_against()
|
self.validate_transfer_against()
|
||||||
self.set_routing_operations()
|
self.set_routing_operations()
|
||||||
self.validate_operations()
|
self.validate_operations()
|
||||||
|
self.update_exploded_items(save=False)
|
||||||
self.calculate_cost()
|
self.calculate_cost()
|
||||||
self.update_stock_qty()
|
self.update_stock_qty()
|
||||||
self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate=False, save=False)
|
self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate=False, save=False)
|
||||||
@ -391,8 +392,6 @@ class BOM(WebsiteGenerator):
|
|||||||
if save:
|
if save:
|
||||||
self.db_update()
|
self.db_update()
|
||||||
|
|
||||||
self.update_exploded_items(save=save)
|
|
||||||
|
|
||||||
# update parent BOMs
|
# update parent BOMs
|
||||||
if self.total_cost != existing_bom_cost and update_parent:
|
if self.total_cost != existing_bom_cost and update_parent:
|
||||||
parent_boms = frappe.db.sql_list(
|
parent_boms = frappe.db.sql_list(
|
||||||
@ -594,6 +593,10 @@ class BOM(WebsiteGenerator):
|
|||||||
self.calculate_op_cost(update_hour_rate)
|
self.calculate_op_cost(update_hour_rate)
|
||||||
self.calculate_rm_cost(save=save_updates)
|
self.calculate_rm_cost(save=save_updates)
|
||||||
self.calculate_sm_cost(save=save_updates)
|
self.calculate_sm_cost(save=save_updates)
|
||||||
|
if save_updates:
|
||||||
|
# not via doc event, table is not regenerated and needs updation
|
||||||
|
self.calculate_exploded_cost()
|
||||||
|
|
||||||
self.total_cost = self.operating_cost + self.raw_material_cost - self.scrap_material_cost
|
self.total_cost = self.operating_cost + self.raw_material_cost - self.scrap_material_cost
|
||||||
self.base_total_cost = (
|
self.base_total_cost = (
|
||||||
self.base_operating_cost + self.base_raw_material_cost - self.base_scrap_material_cost
|
self.base_operating_cost + self.base_raw_material_cost - self.base_scrap_material_cost
|
||||||
@ -689,6 +692,36 @@ class BOM(WebsiteGenerator):
|
|||||||
self.scrap_material_cost = total_sm_cost
|
self.scrap_material_cost = total_sm_cost
|
||||||
self.base_scrap_material_cost = base_total_sm_cost
|
self.base_scrap_material_cost = base_total_sm_cost
|
||||||
|
|
||||||
|
def calculate_exploded_cost(self):
|
||||||
|
"Set exploded row cost from it's parent BOM."
|
||||||
|
rm_rate_map = self.get_rm_rate_map()
|
||||||
|
|
||||||
|
for row in self.get("exploded_items"):
|
||||||
|
old_rate = flt(row.rate)
|
||||||
|
row.rate = rm_rate_map.get(row.item_code)
|
||||||
|
row.amount = flt(row.stock_qty) * row.rate
|
||||||
|
|
||||||
|
if old_rate != row.rate:
|
||||||
|
# Only db_update if unchanged
|
||||||
|
row.db_update()
|
||||||
|
|
||||||
|
def get_rm_rate_map(self) -> Dict[str, float]:
|
||||||
|
"Create Raw Material-Rate map for Exploded Items. Fetch rate from Items table or Subassembly BOM."
|
||||||
|
rm_rate_map = {}
|
||||||
|
|
||||||
|
for item in self.get("items"):
|
||||||
|
if item.bom_no:
|
||||||
|
# Get Item-Rate from Subassembly BOM
|
||||||
|
explosion_items = frappe.db.get_all(
|
||||||
|
"BOM Explosion Item", filters={"parent": item.bom_no}, fields=["item_code", "rate"]
|
||||||
|
)
|
||||||
|
explosion_item_rate = {item.item_code: flt(item.rate) for item in explosion_items}
|
||||||
|
rm_rate_map.update(explosion_item_rate)
|
||||||
|
else:
|
||||||
|
rm_rate_map[item.item_code] = flt(item.base_rate) / flt(item.conversion_factor or 1.0)
|
||||||
|
|
||||||
|
return rm_rate_map
|
||||||
|
|
||||||
def update_exploded_items(self, save=True):
|
def update_exploded_items(self, save=True):
|
||||||
"""Update Flat BOM, following will be correct data"""
|
"""Update Flat BOM, following will be correct data"""
|
||||||
self.get_exploded_items()
|
self.get_exploded_items()
|
||||||
|
@ -169,13 +169,15 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-10-08 16:21:29.386212",
|
"modified": "2022-05-27 13:42:23.305455",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "BOM Explosion Item",
|
"name": "BOM Explosion Item",
|
||||||
|
"naming_rule": "Random",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
@ -120,7 +120,6 @@ def update_cost_in_boms(bom_list: List[str], docname: str) -> Dict[str, Dict]:
|
|||||||
for bom in bom_list:
|
for bom in bom_list:
|
||||||
bom_doc = frappe.get_cached_doc("BOM", bom)
|
bom_doc = frappe.get_cached_doc("BOM", bom)
|
||||||
bom_doc.calculate_cost(save_updates=True, update_hour_rate=True)
|
bom_doc.calculate_cost(save_updates=True, update_hour_rate=True)
|
||||||
# bom_doc.update_exploded_items(save=True) #TODO: edit exploded items rate
|
|
||||||
bom_doc.db_update()
|
bom_doc.db_update()
|
||||||
updated_boms[bom] = True
|
updated_boms[bom] = True
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user