diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 3e4c507e815..000ceb6a13c 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -1433,6 +1433,55 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None): }, ) + def get_max_op_qty(): + from frappe.query_builder.functions import Sum + + table = frappe.qb.DocType("Job Card") + query = ( + frappe.qb.from_(table) + .select(Sum(table.total_completed_qty).as_("qty")) + .where( + (table.docstatus == 1) + & (table.work_order == work_order.name) + & (table.is_corrective_job_card == 0) + ) + .groupby(table.operation) + ) + return min([d.qty for d in query.run(as_dict=True)], default=0) + + def get_utilised_cc(): + from frappe.query_builder.functions import Sum + + table = frappe.qb.DocType("Stock Entry") + subquery = ( + frappe.qb.from_(table) + .select(table.name) + .where( + (table.docstatus == 1) + & (table.work_order == work_order.name) + & (table.purpose == "Manufacture") + ) + ) + table = frappe.qb.DocType("Landed Cost Taxes and Charges") + query = ( + frappe.qb.from_(table) + .select(Sum(table.amount).as_("amount")) + .where(table.parent.isin(subquery) & (table.description == "Corrective Operation Cost")) + ) + return query.run(as_dict=True)[0].amount or 0 + + if work_order and work_order.corrective_operation_cost: + max_qty = get_max_op_qty() - work_order.produced_qty + remaining_cc = work_order.corrective_operation_cost - get_utilised_cc() + stock_entry.append( + "additional_costs", + { + "expense_account": expense_account, + "description": "Corrective Operation Cost", + "amount": remaining_cc / max_qty * flt(stock_entry.fg_completed_qty), + }, + ) + @frappe.whitelist() def get_bom_diff(bom1, bom2): diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index b654127f1e2..7ef58e0d456 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -670,7 +670,11 @@ class JobCard(Document): ) ) - if self.get("operation") == d.operation or self.operation_row_id == d.operation_row_id: + if ( + self.get("operation") == d.operation + or self.operation_row_id == d.operation_row_id + or self.is_corrective_job_card + ): self.append( "items", {