feat: [production_plan -> fetching item description] Fetch item description from Material Request or Sales Order (#19541)
* Change packed item * Remove description field on update_packed_items * add possibility to modify description on packed items * Fetch description from Material Request or Sales Order in production plan, add the possibility to modify the description un production plan * sync with fork * Fetch description from Material Request or Sales Order in production plan, Add the possibility to modify description in production plan * code cleaning syncing fork * code cleaning syncing fork * code cleaning syncing fork * code cleaning syncing fork * rewied and add item_details.description in case of blank field
This commit is contained in:
parent
29a2e16f62
commit
4fa6194009
@ -99,7 +99,7 @@ class ProductionPlan(Document):
|
|||||||
self.get_mr_items()
|
self.get_mr_items()
|
||||||
|
|
||||||
def get_so_items(self):
|
def get_so_items(self):
|
||||||
so_list = [d.sales_order for d in self.get("sales_orders", []) if d.sales_order]
|
so_list = [d.sales_order for d in self.sales_orders if d.sales_order]
|
||||||
if not so_list:
|
if not so_list:
|
||||||
msgprint(_("Please enter Sales Orders in the above table"))
|
msgprint(_("Please enter Sales Orders in the above table"))
|
||||||
return []
|
return []
|
||||||
@ -109,7 +109,7 @@ class ProductionPlan(Document):
|
|||||||
item_condition = ' and so_item.item_code = {0}'.format(frappe.db.escape(self.item_code))
|
item_condition = ' and so_item.item_code = {0}'.format(frappe.db.escape(self.item_code))
|
||||||
|
|
||||||
items = frappe.db.sql("""select distinct parent, item_code, warehouse,
|
items = frappe.db.sql("""select distinct parent, item_code, warehouse,
|
||||||
(qty - work_order_qty) * conversion_factor as pending_qty, name
|
(qty - work_order_qty) * conversion_factor as pending_qty, description, name
|
||||||
from `tabSales Order Item` so_item
|
from `tabSales Order Item` so_item
|
||||||
where parent in (%s) and docstatus = 1 and qty > work_order_qty
|
where parent in (%s) and docstatus = 1 and qty > work_order_qty
|
||||||
and exists (select name from `tabBOM` bom where bom.item=so_item.item_code
|
and exists (select name from `tabBOM` bom where bom.item=so_item.item_code
|
||||||
@ -121,7 +121,7 @@ class ProductionPlan(Document):
|
|||||||
|
|
||||||
packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse,
|
packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse,
|
||||||
(((so_item.qty - so_item.work_order_qty) * pi.qty) / so_item.qty)
|
(((so_item.qty - so_item.work_order_qty) * pi.qty) / so_item.qty)
|
||||||
as pending_qty, pi.parent_item, so_item.name
|
as pending_qty, pi.parent_item, pi.description, so_item.name
|
||||||
from `tabSales Order Item` so_item, `tabPacked Item` pi
|
from `tabSales Order Item` so_item, `tabPacked Item` pi
|
||||||
where so_item.parent = pi.parent and so_item.docstatus = 1
|
where so_item.parent = pi.parent and so_item.docstatus = 1
|
||||||
and pi.parent_item = so_item.item_code
|
and pi.parent_item = so_item.item_code
|
||||||
@ -134,7 +134,7 @@ class ProductionPlan(Document):
|
|||||||
self.calculate_total_planned_qty()
|
self.calculate_total_planned_qty()
|
||||||
|
|
||||||
def get_mr_items(self):
|
def get_mr_items(self):
|
||||||
mr_list = [d.material_request for d in self.get("material_requests", []) if d.material_request]
|
mr_list = [d.material_request for d in self.material_requests if d.material_request]
|
||||||
if not mr_list:
|
if not mr_list:
|
||||||
msgprint(_("Please enter Material Requests in the above table"))
|
msgprint(_("Please enter Material Requests in the above table"))
|
||||||
return []
|
return []
|
||||||
@ -143,7 +143,7 @@ class ProductionPlan(Document):
|
|||||||
if self.item_code:
|
if self.item_code:
|
||||||
item_condition = " and mr_item.item_code ={0}".format(frappe.db.escape(self.item_code))
|
item_condition = " and mr_item.item_code ={0}".format(frappe.db.escape(self.item_code))
|
||||||
|
|
||||||
items = frappe.db.sql("""select distinct parent, name, item_code, warehouse,
|
items = frappe.db.sql("""select distinct parent, name, item_code, warehouse, description,
|
||||||
(qty - ordered_qty) as pending_qty
|
(qty - ordered_qty) as pending_qty
|
||||||
from `tabMaterial Request Item` mr_item
|
from `tabMaterial Request Item` mr_item
|
||||||
where parent in (%s) and docstatus = 1 and qty > ordered_qty
|
where parent in (%s) and docstatus = 1 and qty > ordered_qty
|
||||||
@ -162,7 +162,7 @@ class ProductionPlan(Document):
|
|||||||
'include_exploded_items': 1,
|
'include_exploded_items': 1,
|
||||||
'warehouse': data.warehouse,
|
'warehouse': data.warehouse,
|
||||||
'item_code': data.item_code,
|
'item_code': data.item_code,
|
||||||
'description': item_details and item_details.description or '',
|
'description': data.description or item_details.description,
|
||||||
'stock_uom': item_details and item_details.stock_uom or '',
|
'stock_uom': item_details and item_details.stock_uom or '',
|
||||||
'bom_no': item_details and item_details.bom_no or '',
|
'bom_no': item_details and item_details.bom_no or '',
|
||||||
'planned_qty': data.pending_qty,
|
'planned_qty': data.pending_qty,
|
||||||
@ -174,10 +174,12 @@ class ProductionPlan(Document):
|
|||||||
if self.get_items_from == "Sales Order":
|
if self.get_items_from == "Sales Order":
|
||||||
pi.sales_order = data.parent
|
pi.sales_order = data.parent
|
||||||
pi.sales_order_item = data.name
|
pi.sales_order_item = data.name
|
||||||
|
pi.description = data.description
|
||||||
|
|
||||||
elif self.get_items_from == "Material Request":
|
elif self.get_items_from == "Material Request":
|
||||||
pi.material_request = data.parent
|
pi.material_request = data.parent
|
||||||
pi.material_request_item = data.name
|
pi.material_request_item = data.name
|
||||||
|
pi.description = data.description
|
||||||
|
|
||||||
def calculate_total_planned_qty(self):
|
def calculate_total_planned_qty(self):
|
||||||
self.total_planned_qty = 0
|
self.total_planned_qty = 0
|
||||||
@ -195,7 +197,6 @@ class ProductionPlan(Document):
|
|||||||
for data in self.po_items:
|
for data in self.po_items:
|
||||||
if data.name == production_plan_item:
|
if data.name == production_plan_item:
|
||||||
data.produced_qty = produced_qty
|
data.produced_qty = produced_qty
|
||||||
data.pending_qty = data.planned_qty - data.produced_qty
|
|
||||||
data.db_update()
|
data.db_update()
|
||||||
|
|
||||||
self.calculate_total_produced_qty()
|
self.calculate_total_produced_qty()
|
||||||
@ -302,6 +303,7 @@ class ProductionPlan(Document):
|
|||||||
wo_list.extend(work_orders)
|
wo_list.extend(work_orders)
|
||||||
|
|
||||||
frappe.flags.mute_messages = False
|
frappe.flags.mute_messages = False
|
||||||
|
|
||||||
if wo_list:
|
if wo_list:
|
||||||
wo_list = ["""<a href="#Form/Work Order/%s" target="_blank">%s</a>""" % \
|
wo_list = ["""<a href="#Form/Work Order/%s" target="_blank">%s</a>""" % \
|
||||||
(p, p) for p in wo_list]
|
(p, p) for p in wo_list]
|
||||||
@ -309,16 +311,15 @@ class ProductionPlan(Document):
|
|||||||
else :
|
else :
|
||||||
msgprint(_("No Work Orders created"))
|
msgprint(_("No Work Orders created"))
|
||||||
|
|
||||||
|
|
||||||
def make_work_order_for_sub_assembly_items(self, item):
|
def make_work_order_for_sub_assembly_items(self, item):
|
||||||
work_orders = []
|
work_orders = []
|
||||||
bom_data = {}
|
bom_data = {}
|
||||||
|
|
||||||
get_sub_assembly_items(item.get("bom_no"), bom_data, item.get("qty"))
|
get_sub_assembly_items(item.get("bom_no"), bom_data)
|
||||||
|
|
||||||
for key, data in bom_data.items():
|
for key, data in bom_data.items():
|
||||||
data.update({
|
data.update({
|
||||||
'qty': data.get("stock_qty"),
|
'qty': data.get("stock_qty") * item.get("qty"),
|
||||||
'production_plan': self.name,
|
'production_plan': self.name,
|
||||||
'company': self.company,
|
'company': self.company,
|
||||||
'fg_warehouse': item.get("fg_warehouse"),
|
'fg_warehouse': item.get("fg_warehouse"),
|
||||||
@ -561,7 +562,7 @@ def get_sales_orders(self):
|
|||||||
item_filter += " and so_item.item_code = %(item)s"
|
item_filter += " and so_item.item_code = %(item)s"
|
||||||
|
|
||||||
open_so = frappe.db.sql("""
|
open_so = frappe.db.sql("""
|
||||||
select distinct so.name, so.transaction_date, so.customer, so.base_grand_total as grand_total
|
select distinct so.name, so.transaction_date, so.customer, so.base_grand_total
|
||||||
from `tabSales Order` so, `tabSales Order Item` so_item
|
from `tabSales Order` so, `tabSales Order Item` so_item
|
||||||
where so_item.parent = so.name
|
where so_item.parent = so.name
|
||||||
and so.docstatus = 1 and so.status not in ("Stopped", "Closed")
|
and so.docstatus = 1 and so.status not in ("Stopped", "Closed")
|
||||||
@ -625,7 +626,7 @@ def get_items_for_material_requests(doc, ignore_existing_ordered_qty=None):
|
|||||||
for data in po_items:
|
for data in po_items:
|
||||||
planned_qty = data.get('required_qty') or data.get('planned_qty')
|
planned_qty = data.get('required_qty') or data.get('planned_qty')
|
||||||
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
|
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
|
||||||
warehouse = warehouse or data.get("warehouse")
|
warehouse = data.get("warehouse") or warehouse
|
||||||
|
|
||||||
item_details = {}
|
item_details = {}
|
||||||
if data.get("bom") or data.get("bom_no"):
|
if data.get("bom") or data.get("bom_no"):
|
||||||
@ -708,11 +709,11 @@ def get_item_data(item_code):
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"bom_no": item_details.get("bom_no"),
|
"bom_no": item_details.get("bom_no"),
|
||||||
"stock_uom": item_details.get("stock_uom"),
|
"stock_uom": item_details.get("stock_uom")
|
||||||
"description": item_details.get("description")
|
# "description": item_details.get("description")
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_sub_assembly_items(bom_no, bom_data, qty):
|
def get_sub_assembly_items(bom_no, bom_data):
|
||||||
data = get_children('BOM', parent = bom_no)
|
data = get_children('BOM', parent = bom_no)
|
||||||
for d in data:
|
for d in data:
|
||||||
if d.expandable:
|
if d.expandable:
|
||||||
@ -729,6 +730,6 @@ def get_sub_assembly_items(bom_no, bom_data, qty):
|
|||||||
})
|
})
|
||||||
|
|
||||||
bom_item = bom_data.get(key)
|
bom_item = bom_data.get(key)
|
||||||
bom_item["stock_qty"] += ((d.stock_qty * qty) / d.parent_bom_qty)
|
bom_item["stock_qty"] += d.stock_qty
|
||||||
|
|
||||||
get_sub_assembly_items(bom_item.get("bom_no"), bom_data, bom_item["stock_qty"])
|
get_sub_assembly_items(bom_item.get("bom_no"), bom_data)
|
||||||
|
@ -11,11 +11,9 @@ from erpnext.manufacturing.doctype.production_plan.production_plan import get_sa
|
|||||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
from erpnext.manufacturing.doctype.production_plan.production_plan import get_items_for_material_requests
|
from erpnext.manufacturing.doctype.production_plan.production_plan import get_items_for_material_requests
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
|
||||||
|
|
||||||
class TestProductionPlan(unittest.TestCase):
|
class TestProductionPlan(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
set_perpetual_inventory(0)
|
|
||||||
for item in ['Test Production Item 1', 'Subassembly Item 1',
|
for item in ['Test Production Item 1', 'Subassembly Item 1',
|
||||||
'Raw Material Item 1', 'Raw Material Item 2']:
|
'Raw Material Item 1', 'Raw Material Item 2']:
|
||||||
create_item(item, valuation_rate=100)
|
create_item(item, valuation_rate=100)
|
||||||
|
Loading…
Reference in New Issue
Block a user