chore: Limit Update Cost jobs & db_update only if changed values

- If `Update Cost` job is ongoing, then block creation of new ones since all BOMs are updated
- `db_update` in `calculate_rm_cost` only if changed values to reduce redundant row updates
- Misc: Use variable for batch size
This commit is contained in:
marination 2022-05-31 15:53:34 +05:30
parent 978ba5238f
commit a62bc9b6c9
3 changed files with 30 additions and 4 deletions

View File

@ -644,6 +644,7 @@ class BOM(WebsiteGenerator):
base_total_rm_cost = 0
for d in self.get("items"):
old_rate = d.rate
d.rate = self.get_rm_rate(
{
"company": self.company,
@ -656,6 +657,7 @@ class BOM(WebsiteGenerator):
"sourced_by_supplier": d.sourced_by_supplier,
}
)
d.base_rate = flt(d.rate) * flt(self.conversion_rate)
d.amount = flt(d.rate, d.precision("rate")) * flt(d.qty, d.precision("qty"))
d.base_amount = d.amount * flt(self.conversion_rate)
@ -665,7 +667,7 @@ class BOM(WebsiteGenerator):
total_rm_cost += d.amount
base_total_rm_cost += d.base_amount
if save:
if save and (old_rate != d.rate):
d.db_update()
self.raw_material_cost = total_rm_cost

View File

@ -26,6 +26,8 @@ class BOMUpdateLog(Document):
self.validate_boms_are_specified()
self.validate_same_bom()
self.validate_bom_items()
else:
self.validate_bom_cost_update_in_progress()
self.status = "Queued"
@ -48,6 +50,21 @@ class BOMUpdateLog(Document):
if current_bom_item != new_bom_item:
frappe.throw(_("The selected BOMs are not for the same item"))
def validate_bom_cost_update_in_progress(self):
"If another Cost Updation Log is still in progress, dont make new ones."
wip_log = frappe.get_all(
"BOM Update Log",
{"update_type": "Update Cost", "status": ["in", ["Queued", "In Progress", "Paused"]]},
limit_page_length=1,
)
if wip_log:
log_link = frappe.utils.get_link_to_form("BOM Update Log", wip_log[0].name)
frappe.throw(
_("BOM Updation already in progress. Please wait until {0} is complete.").format(log_link),
title=_("Note"),
)
def on_submit(self):
if frappe.flags.in_test:
return
@ -124,10 +141,11 @@ def queue_bom_cost_jobs(current_boms: Dict, update_doc: "BOMUpdateLog") -> None:
current_boms_list = [bom for bom in current_boms]
while current_boms_list:
boms_to_process = current_boms_list[:20000] # slice out batch of 20k BOMs
batch_size = 20_000
boms_to_process = current_boms_list[:batch_size] # slice out batch of 20k BOMs
# update list to exclude 20K (queued) BOMs
current_boms_list = current_boms_list[20000:] if len(current_boms_list) > 20000 else []
current_boms_list = current_boms_list[batch_size:] if len(current_boms_list) > batch_size else []
frappe.enqueue(
method="erpnext.manufacturing.doctype.bom_update_log.bom_updation_utils.update_cost_in_level",
doc=update_doc,

View File

@ -38,7 +38,13 @@ def enqueue_update_cost() -> "BOMUpdateLog":
def auto_update_latest_price_in_all_boms() -> None:
"""Called via hooks.py."""
if frappe.db.get_single_value("Manufacturing Settings", "update_bom_costs_automatically"):
create_bom_update_log(update_type="Update Cost")
wip_log = frappe.get_all(
"BOM Update Log",
{"update_type": "Update Cost", "status": ["in", ["Queued", "In Progress", "Paused"]]},
limit_page_length=1,
)
if not wip_log:
create_bom_update_log(update_type="Update Cost")
def create_bom_update_log(