fix: Made requested changes by mentor and fixed some bugs in Production Plan Summary report
This commit is contained in:
@@ -789,23 +789,10 @@ class ProductionPlan(Document):
|
||||
items_to_remove = defaultdict(list)
|
||||
for supplier, items in subcontracted_po.items():
|
||||
for item in items:
|
||||
table = frappe.qb.DocType("Purchase Order Item")
|
||||
total_received_qty = (
|
||||
frappe.qb.from_(table)
|
||||
.select(
|
||||
Sum(table.received_qty / (table.received_qty / table.fg_item_qty)).as_(
|
||||
"total_received_qty"
|
||||
)
|
||||
)
|
||||
.where(
|
||||
(table.production_plan_sub_assembly_item == item.name) & (table.docstatus == 1)
|
||||
)
|
||||
).run(as_dict=True)[0].total_received_qty or 0
|
||||
|
||||
if item.qty == total_received_qty:
|
||||
if item.qty == item.received_qty:
|
||||
items_to_remove[supplier].append(item)
|
||||
elif total_received_qty:
|
||||
item.qty -= total_received_qty
|
||||
elif item.received_qty:
|
||||
item.qty -= item.received_qty
|
||||
|
||||
subcontracted_po[supplier] = [item for item in items if item not in items_to_remove[supplier]]
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
"purchase_order",
|
||||
"production_plan_item",
|
||||
"column_break_7",
|
||||
"ordered_qty",
|
||||
"received_qty",
|
||||
"indent",
|
||||
"section_break_19",
|
||||
@@ -72,6 +71,7 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "received_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Received Qty",
|
||||
@@ -205,20 +205,12 @@
|
||||
"fieldtype": "Float",
|
||||
"label": "Produced Qty",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ordered_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 1,
|
||||
"label": "Ordered Qty",
|
||||
"non_negative": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-12-20 17:00:15.335880",
|
||||
"modified": "2025-01-01 14:27:52.956484",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Plan Sub Assembly Item",
|
||||
|
||||
@@ -22,7 +22,6 @@ class ProductionPlanSubAssemblyItem(Document):
|
||||
fg_warehouse: DF.Link | None
|
||||
indent: DF.Int
|
||||
item_name: DF.Data | None
|
||||
ordered_qty: DF.Float
|
||||
parent: DF.Data
|
||||
parent_item_code: DF.Link | None
|
||||
parentfield: DF.Data
|
||||
|
||||
@@ -116,7 +116,7 @@ def get_production_plan_sub_assembly_item_details(filters, row, production_plan_
|
||||
"pending_qty": flt(item.qty)
|
||||
- flt(order_details.get((docname, item.production_item), {}).get("produced_qty", 0)),
|
||||
}
|
||||
if data[-1] and data[-1]["indent"] == data_to_append["indent"]:
|
||||
if data[-1] and data[-1]["item_code"] == item.production_item:
|
||||
data_to_append["pending_qty"] = data[-1]["pending_qty"] - data_to_append["produced_qty"]
|
||||
data.append(data_to_append)
|
||||
|
||||
@@ -124,7 +124,7 @@ def get_production_plan_sub_assembly_item_details(filters, row, production_plan_
|
||||
def get_work_order_details(filters, order_details):
|
||||
for row in frappe.get_all(
|
||||
"Work Order",
|
||||
filters={"production_plan": filters.get("production_plan")},
|
||||
filters={"production_plan": filters.get("production_plan"), "docstatus": 1},
|
||||
fields=["name", "produced_qty", "production_plan", "production_item", "sales_order"],
|
||||
):
|
||||
order_details.setdefault((row.name, row.production_item), row)
|
||||
@@ -133,11 +133,11 @@ def get_work_order_details(filters, order_details):
|
||||
def get_purchase_order_details(filters, order_details):
|
||||
for row in frappe.get_all(
|
||||
"Purchase Order Item",
|
||||
filters={"production_plan": filters.get("production_plan")},
|
||||
fields=["parent", "received_qty as produced_qty", "item_code", "fg_item", "fg_item_qty"],
|
||||
filters={"production_plan": filters.get("production_plan"), "docstatus": 1},
|
||||
fields=["parent", "qty", "received_qty as produced_qty", "item_code", "fg_item", "fg_item_qty"],
|
||||
):
|
||||
if row.fg_item:
|
||||
row.produced_qty /= row.produced_qty / row.fg_item_qty or 1
|
||||
row.produced_qty /= row.qty / row.fg_item_qty or 1
|
||||
order_details.setdefault((row.parent, row.fg_item or row.item_code), row)
|
||||
|
||||
|
||||
|
||||
@@ -162,18 +162,23 @@ class MaterialRequest(BuyingController):
|
||||
self.validate_pp_qty()
|
||||
|
||||
def validate_pp_qty(self):
|
||||
for item in self.items:
|
||||
if item.material_request_plan_item:
|
||||
qty_from_pp = frappe.db.get_value(
|
||||
"Material Request Plan Item",
|
||||
item.material_request_plan_item,
|
||||
["quantity", "requested_qty"],
|
||||
as_dict=1,
|
||||
)
|
||||
if item.qty > (qty_from_pp.quantity - qty_from_pp.requested_qty):
|
||||
items_from_pp = [item for item in self.items if item.material_request_plan_item]
|
||||
if items_from_pp:
|
||||
items_mr_plan_items = [item.material_request_plan_item for item in items_from_pp]
|
||||
table = frappe.qb.DocType("Material Request Plan Item")
|
||||
query = (
|
||||
frappe.qb.from_(table)
|
||||
.select(table.name, (table.quantity - table.requested_qty).as_("available_qty"))
|
||||
.where(table.name.isin(items_mr_plan_items))
|
||||
)
|
||||
result = query.run(as_dict=True)
|
||||
|
||||
for item in items_from_pp:
|
||||
row = next(r for r in result if r.name == item.material_request_plan_item)
|
||||
if item.qty > row.available_qty:
|
||||
frappe.throw(
|
||||
_("Quantity cannot be greater than {0} for Item {1}").format(
|
||||
qty_from_pp.quantity - qty_from_pp.requested_qty, item.item_code
|
||||
row.available_qty, item.item_code
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -383,6 +383,42 @@ class PurchaseReceipt(BuyingController):
|
||||
self.repost_future_sle_and_gle()
|
||||
self.set_consumed_qty_in_subcontract_order()
|
||||
self.reserve_stock_for_sales_order()
|
||||
self.update_received_qty_if_from_pp()
|
||||
|
||||
def update_received_qty_if_from_pp(self, cancel=False):
|
||||
from frappe.query_builder.functions import Sum
|
||||
|
||||
items_with_po_item = [item for item in self.items if item.purchase_order_item]
|
||||
if items_with_po_item:
|
||||
po_items = [item.purchase_order_item for item in items_with_po_item]
|
||||
table = frappe.qb.DocType("Purchase Order Item")
|
||||
query = (
|
||||
frappe.qb.from_(table)
|
||||
.select(
|
||||
table.name,
|
||||
(table.qty / table.fg_item_qty).as_("sc_conversion_factor"),
|
||||
table.production_plan_sub_assembly_item,
|
||||
Sum(table.received_qty).as_("received_qty"),
|
||||
)
|
||||
.where(table.name.isin(po_items))
|
||||
.groupby(table.name)
|
||||
)
|
||||
result = query.run(as_dict=True)
|
||||
|
||||
for item in items_with_po_item:
|
||||
row = next(d for d in result if d.name == item.purchase_order_item)
|
||||
if row.production_plan_sub_assembly_item:
|
||||
received_qty = (
|
||||
(row.received_qty + (item.qty / row.sc_conversion_factor))
|
||||
if not cancel
|
||||
else (row.received_qty - (item.qty / row.sc_conversion_factor))
|
||||
)
|
||||
frappe.set_value(
|
||||
"Production Plan Sub Assembly Item",
|
||||
row.production_plan_sub_assembly_item,
|
||||
"received_qty",
|
||||
received_qty,
|
||||
)
|
||||
|
||||
def check_next_docstatus(self):
|
||||
submit_rv = frappe.db.sql(
|
||||
@@ -424,6 +460,7 @@ class PurchaseReceipt(BuyingController):
|
||||
)
|
||||
self.delete_auto_created_batches()
|
||||
self.set_consumed_qty_in_subcontract_order()
|
||||
self.update_received_qty_if_from_pp(cancel=True)
|
||||
|
||||
def get_gl_entries(self, warehouse_account=None, via_landed_cost_voucher=False):
|
||||
from erpnext.accounts.general_ledger import process_gl_map
|
||||
|
||||
Reference in New Issue
Block a user