fix: production plan reserved qty incorrect calculation (#37400)
This commit is contained in:
parent
847f774c8b
commit
f3238f9105
@ -8,7 +8,6 @@ import json
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _, msgprint
|
from frappe import _, msgprint
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.query_builder import Case
|
|
||||||
from frappe.query_builder.functions import IfNull, Sum
|
from frappe.query_builder.functions import IfNull, Sum
|
||||||
from frappe.utils import (
|
from frappe.utils import (
|
||||||
add_days,
|
add_days,
|
||||||
@ -1618,21 +1617,13 @@ def get_reserved_qty_for_production_plan(item_code, warehouse):
|
|||||||
table = frappe.qb.DocType("Production Plan")
|
table = frappe.qb.DocType("Production Plan")
|
||||||
child = frappe.qb.DocType("Material Request Plan Item")
|
child = frappe.qb.DocType("Material Request Plan Item")
|
||||||
|
|
||||||
completed_production_plans = get_completed_production_plans()
|
non_completed_production_plans = get_non_completed_production_plans()
|
||||||
|
|
||||||
case = Case()
|
|
||||||
query = (
|
query = (
|
||||||
frappe.qb.from_(table)
|
frappe.qb.from_(table)
|
||||||
.inner_join(child)
|
.inner_join(child)
|
||||||
.on(table.name == child.parent)
|
.on(table.name == child.parent)
|
||||||
.select(
|
.select(Sum(child.required_bom_qty))
|
||||||
Sum(
|
|
||||||
child.quantity
|
|
||||||
* IfNull(
|
|
||||||
case.when(child.material_request_type == "Purchase", child.conversion_factor).else_(1.0), 1.0
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.where(
|
.where(
|
||||||
(table.docstatus == 1)
|
(table.docstatus == 1)
|
||||||
& (child.item_code == item_code)
|
& (child.item_code == item_code)
|
||||||
@ -1641,8 +1632,8 @@ def get_reserved_qty_for_production_plan(item_code, warehouse):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if completed_production_plans:
|
if non_completed_production_plans:
|
||||||
query = query.where(table.name.notin(completed_production_plans))
|
query = query.where(table.name.isin(non_completed_production_plans))
|
||||||
|
|
||||||
query = query.run()
|
query = query.run()
|
||||||
|
|
||||||
@ -1653,7 +1644,7 @@ def get_reserved_qty_for_production_plan(item_code, warehouse):
|
|||||||
|
|
||||||
reserved_qty_for_production = flt(
|
reserved_qty_for_production = flt(
|
||||||
get_reserved_qty_for_production(
|
get_reserved_qty_for_production(
|
||||||
item_code, warehouse, completed_production_plans, check_production_plan=True
|
item_code, warehouse, non_completed_production_plans, check_production_plan=True
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1663,7 +1654,7 @@ def get_reserved_qty_for_production_plan(item_code, warehouse):
|
|||||||
return reserved_qty_for_production_plan - reserved_qty_for_production
|
return reserved_qty_for_production_plan - reserved_qty_for_production
|
||||||
|
|
||||||
|
|
||||||
def get_completed_production_plans():
|
def get_non_completed_production_plans():
|
||||||
table = frappe.qb.DocType("Production Plan")
|
table = frappe.qb.DocType("Production Plan")
|
||||||
child = frappe.qb.DocType("Production Plan Item")
|
child = frappe.qb.DocType("Production Plan Item")
|
||||||
|
|
||||||
@ -1675,7 +1666,7 @@ def get_completed_production_plans():
|
|||||||
.where(
|
.where(
|
||||||
(table.docstatus == 1)
|
(table.docstatus == 1)
|
||||||
& (table.status.notin(["Completed", "Closed"]))
|
& (table.status.notin(["Completed", "Closed"]))
|
||||||
& (child.ordered_qty >= child.planned_qty)
|
& (child.planned_qty > child.ordered_qty)
|
||||||
)
|
)
|
||||||
).run(as_dict=True)
|
).run(as_dict=True)
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,8 @@ from frappe.utils import add_to_date, flt, getdate, now_datetime, nowdate
|
|||||||
|
|
||||||
from erpnext.controllers.item_variant import create_variant
|
from erpnext.controllers.item_variant import create_variant
|
||||||
from erpnext.manufacturing.doctype.production_plan.production_plan import (
|
from erpnext.manufacturing.doctype.production_plan.production_plan import (
|
||||||
get_completed_production_plans,
|
|
||||||
get_items_for_material_requests,
|
get_items_for_material_requests,
|
||||||
|
get_non_completed_production_plans,
|
||||||
get_sales_orders,
|
get_sales_orders,
|
||||||
get_warehouse_list,
|
get_warehouse_list,
|
||||||
)
|
)
|
||||||
@ -1143,9 +1143,9 @@ class TestProductionPlan(FrappeTestCase):
|
|||||||
|
|
||||||
self.assertEqual(after_qty, before_qty)
|
self.assertEqual(after_qty, before_qty)
|
||||||
|
|
||||||
completed_plans = get_completed_production_plans()
|
completed_plans = get_non_completed_production_plans()
|
||||||
for plan in plans:
|
for plan in plans:
|
||||||
self.assertTrue(plan in completed_plans)
|
self.assertFalse(plan in completed_plans)
|
||||||
|
|
||||||
def test_resered_qty_for_production_plan_for_material_requests_with_multi_UOM(self):
|
def test_resered_qty_for_production_plan_for_material_requests_with_multi_UOM(self):
|
||||||
from erpnext.stock.utils import get_or_make_bin
|
from erpnext.stock.utils import get_or_make_bin
|
||||||
|
|||||||
@ -1515,7 +1515,7 @@ def create_pick_list(source_name, target_doc=None, for_qty=None):
|
|||||||
def get_reserved_qty_for_production(
|
def get_reserved_qty_for_production(
|
||||||
item_code: str,
|
item_code: str,
|
||||||
warehouse: str,
|
warehouse: str,
|
||||||
completed_production_plans: list = None,
|
non_completed_production_plans: list = None,
|
||||||
check_production_plan: bool = False,
|
check_production_plan: bool = False,
|
||||||
) -> float:
|
) -> float:
|
||||||
"""Get total reserved quantity for any item in specified warehouse"""
|
"""Get total reserved quantity for any item in specified warehouse"""
|
||||||
@ -1538,19 +1538,22 @@ def get_reserved_qty_for_production(
|
|||||||
& (wo_item.parent == wo.name)
|
& (wo_item.parent == wo.name)
|
||||||
& (wo.docstatus == 1)
|
& (wo.docstatus == 1)
|
||||||
& (wo_item.source_warehouse == warehouse)
|
& (wo_item.source_warehouse == warehouse)
|
||||||
& (wo.status.notin(["Stopped", "Completed", "Closed"]))
|
|
||||||
& (
|
|
||||||
(wo_item.required_qty > wo_item.transferred_qty)
|
|
||||||
| (wo_item.required_qty > wo_item.consumed_qty)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if check_production_plan:
|
if check_production_plan:
|
||||||
query = query.where(wo.production_plan.isnotnull())
|
query = query.where(wo.production_plan.isnotnull())
|
||||||
|
else:
|
||||||
|
query = query.where(
|
||||||
|
(wo.status.notin(["Stopped", "Completed", "Closed"]))
|
||||||
|
& (
|
||||||
|
(wo_item.required_qty > wo_item.transferred_qty)
|
||||||
|
| (wo_item.required_qty > wo_item.consumed_qty)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if completed_production_plans:
|
if non_completed_production_plans:
|
||||||
query = query.where(wo.production_plan.notin(completed_production_plans))
|
query = query.where(wo.production_plan.isin(non_completed_production_plans))
|
||||||
|
|
||||||
return query.run()[0][0] or 0.0
|
return query.run()[0][0] or 0.0
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user