mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-15 11:09:17 +00:00
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:
@@ -634,6 +634,7 @@ class BOM(WebsiteGenerator):
|
|||||||
base_total_rm_cost = 0
|
base_total_rm_cost = 0
|
||||||
|
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
|
old_rate = d.rate
|
||||||
d.rate = self.get_rm_rate(
|
d.rate = self.get_rm_rate(
|
||||||
{
|
{
|
||||||
"company": self.company,
|
"company": self.company,
|
||||||
@@ -646,6 +647,7 @@ class BOM(WebsiteGenerator):
|
|||||||
"sourced_by_supplier": d.sourced_by_supplier,
|
"sourced_by_supplier": d.sourced_by_supplier,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
d.base_rate = flt(d.rate) * flt(self.conversion_rate)
|
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.amount = flt(d.rate, d.precision("rate")) * flt(d.qty, d.precision("qty"))
|
||||||
d.base_amount = d.amount * flt(self.conversion_rate)
|
d.base_amount = d.amount * flt(self.conversion_rate)
|
||||||
@@ -655,7 +657,7 @@ class BOM(WebsiteGenerator):
|
|||||||
|
|
||||||
total_rm_cost += d.amount
|
total_rm_cost += d.amount
|
||||||
base_total_rm_cost += d.base_amount
|
base_total_rm_cost += d.base_amount
|
||||||
if save:
|
if save and (old_rate != d.rate):
|
||||||
d.db_update()
|
d.db_update()
|
||||||
|
|
||||||
self.raw_material_cost = total_rm_cost
|
self.raw_material_cost = total_rm_cost
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ class BOMUpdateLog(Document):
|
|||||||
self.validate_boms_are_specified()
|
self.validate_boms_are_specified()
|
||||||
self.validate_same_bom()
|
self.validate_same_bom()
|
||||||
self.validate_bom_items()
|
self.validate_bom_items()
|
||||||
|
else:
|
||||||
|
self.validate_bom_cost_update_in_progress()
|
||||||
|
|
||||||
self.status = "Queued"
|
self.status = "Queued"
|
||||||
|
|
||||||
@@ -48,6 +50,21 @@ class BOMUpdateLog(Document):
|
|||||||
if current_bom_item != new_bom_item:
|
if current_bom_item != new_bom_item:
|
||||||
frappe.throw(_("The selected BOMs are not for the same 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):
|
def on_submit(self):
|
||||||
if frappe.flags.in_test:
|
if frappe.flags.in_test:
|
||||||
return
|
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]
|
current_boms_list = [bom for bom in current_boms]
|
||||||
|
|
||||||
while current_boms_list:
|
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
|
# 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(
|
frappe.enqueue(
|
||||||
method="erpnext.manufacturing.doctype.bom_update_log.bom_updation_utils.update_cost_in_level",
|
method="erpnext.manufacturing.doctype.bom_update_log.bom_updation_utils.update_cost_in_level",
|
||||||
doc=update_doc,
|
doc=update_doc,
|
||||||
|
|||||||
@@ -40,7 +40,13 @@ def enqueue_update_cost() -> "BOMUpdateLog":
|
|||||||
def auto_update_latest_price_in_all_boms() -> None:
|
def auto_update_latest_price_in_all_boms() -> None:
|
||||||
"""Called via hooks.py."""
|
"""Called via hooks.py."""
|
||||||
if frappe.db.get_single_value("Manufacturing Settings", "update_bom_costs_automatically"):
|
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(
|
def create_bom_update_log(
|
||||||
|
|||||||
Reference in New Issue
Block a user