mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 23:19:20 +00:00
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)
|
items_to_remove = defaultdict(list)
|
||||||
for supplier, items in subcontracted_po.items():
|
for supplier, items in subcontracted_po.items():
|
||||||
for item in items:
|
for item in items:
|
||||||
table = frappe.qb.DocType("Purchase Order Item")
|
if item.qty == item.received_qty:
|
||||||
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:
|
|
||||||
items_to_remove[supplier].append(item)
|
items_to_remove[supplier].append(item)
|
||||||
elif total_received_qty:
|
elif item.received_qty:
|
||||||
item.qty -= total_received_qty
|
item.qty -= item.received_qty
|
||||||
|
|
||||||
subcontracted_po[supplier] = [item for item in items if item not in items_to_remove[supplier]]
|
subcontracted_po[supplier] = [item for item in items if item not in items_to_remove[supplier]]
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
"purchase_order",
|
"purchase_order",
|
||||||
"production_plan_item",
|
"production_plan_item",
|
||||||
"column_break_7",
|
"column_break_7",
|
||||||
"ordered_qty",
|
|
||||||
"received_qty",
|
"received_qty",
|
||||||
"indent",
|
"indent",
|
||||||
"section_break_19",
|
"section_break_19",
|
||||||
@@ -72,6 +71,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fieldname": "received_qty",
|
"fieldname": "received_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Received Qty",
|
"label": "Received Qty",
|
||||||
@@ -205,20 +205,12 @@
|
|||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Produced Qty",
|
"label": "Produced Qty",
|
||||||
"read_only": 1
|
"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,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-12-20 17:00:15.335880",
|
"modified": "2025-01-01 14:27:52.956484",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Production Plan Sub Assembly Item",
|
"name": "Production Plan Sub Assembly Item",
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class ProductionPlanSubAssemblyItem(Document):
|
|||||||
fg_warehouse: DF.Link | None
|
fg_warehouse: DF.Link | None
|
||||||
indent: DF.Int
|
indent: DF.Int
|
||||||
item_name: DF.Data | None
|
item_name: DF.Data | None
|
||||||
ordered_qty: DF.Float
|
|
||||||
parent: DF.Data
|
parent: DF.Data
|
||||||
parent_item_code: DF.Link | None
|
parent_item_code: DF.Link | None
|
||||||
parentfield: DF.Data
|
parentfield: DF.Data
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ def get_production_plan_sub_assembly_item_details(filters, row, production_plan_
|
|||||||
"pending_qty": flt(item.qty)
|
"pending_qty": flt(item.qty)
|
||||||
- flt(order_details.get((docname, item.production_item), {}).get("produced_qty", 0)),
|
- 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_to_append["pending_qty"] = data[-1]["pending_qty"] - data_to_append["produced_qty"]
|
||||||
data.append(data_to_append)
|
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):
|
def get_work_order_details(filters, order_details):
|
||||||
for row in frappe.get_all(
|
for row in frappe.get_all(
|
||||||
"Work Order",
|
"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"],
|
fields=["name", "produced_qty", "production_plan", "production_item", "sales_order"],
|
||||||
):
|
):
|
||||||
order_details.setdefault((row.name, row.production_item), row)
|
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):
|
def get_purchase_order_details(filters, order_details):
|
||||||
for row in frappe.get_all(
|
for row in frappe.get_all(
|
||||||
"Purchase Order Item",
|
"Purchase Order Item",
|
||||||
filters={"production_plan": filters.get("production_plan")},
|
filters={"production_plan": filters.get("production_plan"), "docstatus": 1},
|
||||||
fields=["parent", "received_qty as produced_qty", "item_code", "fg_item", "fg_item_qty"],
|
fields=["parent", "qty", "received_qty as produced_qty", "item_code", "fg_item", "fg_item_qty"],
|
||||||
):
|
):
|
||||||
if row.fg_item:
|
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)
|
order_details.setdefault((row.parent, row.fg_item or row.item_code), row)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -162,18 +162,23 @@ class MaterialRequest(BuyingController):
|
|||||||
self.validate_pp_qty()
|
self.validate_pp_qty()
|
||||||
|
|
||||||
def validate_pp_qty(self):
|
def validate_pp_qty(self):
|
||||||
for item in self.items:
|
items_from_pp = [item for item in self.items if item.material_request_plan_item]
|
||||||
if item.material_request_plan_item:
|
if items_from_pp:
|
||||||
qty_from_pp = frappe.db.get_value(
|
items_mr_plan_items = [item.material_request_plan_item for item in items_from_pp]
|
||||||
"Material Request Plan Item",
|
table = frappe.qb.DocType("Material Request Plan Item")
|
||||||
item.material_request_plan_item,
|
query = (
|
||||||
["quantity", "requested_qty"],
|
frappe.qb.from_(table)
|
||||||
as_dict=1,
|
.select(table.name, (table.quantity - table.requested_qty).as_("available_qty"))
|
||||||
)
|
.where(table.name.isin(items_mr_plan_items))
|
||||||
if item.qty > (qty_from_pp.quantity - qty_from_pp.requested_qty):
|
)
|
||||||
|
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(
|
frappe.throw(
|
||||||
_("Quantity cannot be greater than {0} for Item {1}").format(
|
_("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.repost_future_sle_and_gle()
|
||||||
self.set_consumed_qty_in_subcontract_order()
|
self.set_consumed_qty_in_subcontract_order()
|
||||||
self.reserve_stock_for_sales_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):
|
def check_next_docstatus(self):
|
||||||
submit_rv = frappe.db.sql(
|
submit_rv = frappe.db.sql(
|
||||||
@@ -424,6 +460,7 @@ class PurchaseReceipt(BuyingController):
|
|||||||
)
|
)
|
||||||
self.delete_auto_created_batches()
|
self.delete_auto_created_batches()
|
||||||
self.set_consumed_qty_in_subcontract_order()
|
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):
|
def get_gl_entries(self, warehouse_account=None, via_landed_cost_voucher=False):
|
||||||
from erpnext.accounts.general_ledger import process_gl_map
|
from erpnext.accounts.general_ledger import process_gl_map
|
||||||
|
|||||||
Reference in New Issue
Block a user