Upgraded PPT for more variety of MR creation options. Added tests
This commit is contained in:
parent
0c1be8df35
commit
e977fc5dee
@ -9,6 +9,7 @@
|
|||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Setup",
|
"document_type": "Setup",
|
||||||
|
"editable_grid": 0,
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -468,7 +469,7 @@
|
|||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -476,8 +477,8 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"depends_on": "get_items_from",
|
"depends_on": "",
|
||||||
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
"description": "If checked, all the children of each production item will be included in the Material Requests.",
|
||||||
"fieldname": "use_multi_level_bom",
|
"fieldname": "use_multi_level_bom",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -498,6 +499,59 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"description": "If checked, only Purchase material requests for final raw materials will be included in the Material Requests. Otherwise, Material Requests for parent items will be created",
|
||||||
|
"fieldname": "only_raw_materials",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Only Obtain Raw Materials",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"depends_on": "use_multi_level_bom",
|
||||||
|
"description": "If checked, raw materials for items that are sub-contracted will be included in the Material Requests",
|
||||||
|
"fieldname": "include_subcontracted",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Include sub-contracted raw materials",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
@ -705,13 +759,14 @@
|
|||||||
"hide_toolbar": 1,
|
"hide_toolbar": 1,
|
||||||
"icon": "icon-calendar",
|
"icon": "icon-calendar",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
|
"image_view": 0,
|
||||||
"in_create": 1,
|
"in_create": 1,
|
||||||
"in_dialog": 0,
|
"in_dialog": 0,
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-06-02 17:59:48.976304",
|
"modified": "2016-07-27 19:37:49.608457",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Production Planning Tool",
|
"name": "Production Planning Tool",
|
||||||
@ -731,6 +786,7 @@
|
|||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 0,
|
"report": 0,
|
||||||
|
"restrict": 0,
|
||||||
"role": "Manufacturing User",
|
"role": "Manufacturing User",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
|
@ -175,7 +175,7 @@ class ProductionPlanningTool(Document):
|
|||||||
and bom.is_active = 1) %s""" % \
|
and bom.is_active = 1) %s""" % \
|
||||||
(", ".join(["%s"] * len(mr_list)), item_condition), tuple(mr_list), as_dict=1)
|
(", ".join(["%s"] * len(mr_list)), item_condition), tuple(mr_list), as_dict=1)
|
||||||
|
|
||||||
self.add_items(items)
|
self.add_items(items)
|
||||||
|
|
||||||
|
|
||||||
def add_items(self, items):
|
def add_items(self, items):
|
||||||
@ -313,10 +313,10 @@ class ProductionPlanningTool(Document):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
item_list = []
|
item_list = []
|
||||||
|
|
||||||
for bom, so_wise_qty in bom_dict.items():
|
for bom, so_wise_qty in bom_dict.items():
|
||||||
bom_wise_item_details = {}
|
bom_wise_item_details = {}
|
||||||
if self.use_multi_level_bom:
|
if self.use_multi_level_bom and self.only_raw_materials and self.include_subcontracted:
|
||||||
# get all raw materials with sub assembly childs
|
# get all raw materials with sub assembly childs
|
||||||
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
|
||||||
for d in frappe.db.sql("""select fb.item_code,
|
for d in frappe.db.sql("""select fb.item_code,
|
||||||
@ -326,28 +326,40 @@ class ProductionPlanningTool(Document):
|
|||||||
where bom.name = fb.parent and item.name = fb.item_code
|
where bom.name = fb.parent and item.name = fb.item_code
|
||||||
and (item.is_sub_contracted_item = 0 or ifnull(item.default_bom, "")="")
|
and (item.is_sub_contracted_item = 0 or ifnull(item.default_bom, "")="")
|
||||||
and item.is_stock_item = 1
|
and item.is_stock_item = 1
|
||||||
and fb.docstatus<2 and bom.name=%s
|
and fb.docstatus<2 and bom.name=%(bom)s
|
||||||
group by fb.item_code, fb.stock_uom""", bom, as_dict=1):
|
group by fb.item_code, fb.stock_uom""", {"bom":bom}, as_dict=1):
|
||||||
bom_wise_item_details.setdefault(d.item_code, d)
|
bom_wise_item_details.setdefault(d.item_code, d)
|
||||||
else:
|
else:
|
||||||
# Get all raw materials considering SA items as raw materials,
|
# Get all raw materials considering SA items as raw materials,
|
||||||
# so no childs of SA items
|
# so no childs of SA items
|
||||||
for d in frappe.db.sql("""select bom_item.item_code,
|
bom_wise_item_details = self.get_subitems(bom_wise_item_details, bom,1, self.use_multi_level_bom,self.only_raw_materials, self.include_subcontracted)
|
||||||
ifnull(sum(bom_item.qty/ifnull(bom.quantity, 1)), 0) as qty,
|
|
||||||
bom_item.description, bom_item.stock_uom, item.min_order_qty
|
|
||||||
from `tabBOM Item` bom_item, `tabBOM` bom, tabItem item
|
|
||||||
where bom.name = bom_item.parent and bom.name = %s and bom_item.docstatus < 2
|
|
||||||
and bom_item.item_code = item.name
|
|
||||||
and item.is_stock_item = 1
|
|
||||||
group by bom_item.item_code""", bom, as_dict=1):
|
|
||||||
bom_wise_item_details.setdefault(d.item_code, d)
|
|
||||||
for item, item_details in bom_wise_item_details.items():
|
for item, item_details in bom_wise_item_details.items():
|
||||||
for so_qty in so_wise_qty:
|
for so_qty in so_wise_qty:
|
||||||
item_list.append([item, flt(item_details.qty) * so_qty[1], item_details.description,
|
item_list.append([item, flt(item_details.qty) * so_qty[1], item_details.description,
|
||||||
item_details.stock_uom, item_details.min_order_qty, so_qty[0]])
|
item_details.stock_uom, item_details.min_order_qty, so_qty[0]])
|
||||||
|
|
||||||
self.make_items_dict(item_list)
|
self.make_items_dict(item_list)
|
||||||
|
|
||||||
|
def get_subitems(self,bom_wise_item_details, bom, parent_qty, include_sublevel, only_raw, supply_subs):
|
||||||
|
for d in frappe.db.sql("""select bom_item.item_code, default_material_request_type,
|
||||||
|
ifnull(%(parent_qty)s * sum(bom_item.qty/ifnull(bom.quantity, 1)), 0) as qty,
|
||||||
|
item.is_sub_contracted_item as is_sub_contracted, item.default_bom as default_bom
|
||||||
|
from `tabBOM Item` bom_item, `tabBOM` bom, tabItem item
|
||||||
|
where bom.name = bom_item.parent and bom.name = %(bom)s and bom_item.docstatus < 2
|
||||||
|
and bom_item.item_code = item.name
|
||||||
|
and item.is_stock_item = 1
|
||||||
|
group by bom_item.item_code""", {"bom": bom, "parent_qty": parent_qty}, as_dict=1):
|
||||||
|
if (d.default_material_request_type == "Purchase" and not (d.is_sub_contracted and only_raw and include_sublevel)) or (d.default_material_request_type == "Manufacture" and not only_raw):
|
||||||
|
if d.item_code in bom_wise_item_details:
|
||||||
|
bom_wise_item_details[d.item_code].qty = bom_wise_item_details[d.item_code].qty + d.qty
|
||||||
|
else:
|
||||||
|
bom_wise_item_details[d.item_code] = d
|
||||||
|
if include_sublevel:
|
||||||
|
if (d.default_material_request_type == "Purchase" and d.is_sub_contracted and supply_subs) or (d.default_material_request_type == "Manufacture"):
|
||||||
|
child_details = self.get_subitems(bom_wise_item_details,d.default_bom,d.qty, include_sublevel, only_raw, supply_subs)
|
||||||
|
return bom_wise_item_details
|
||||||
|
|
||||||
def make_items_dict(self, item_list):
|
def make_items_dict(self, item_list):
|
||||||
for i in item_list:
|
for i in item_list:
|
||||||
self.item_dict.setdefault(i[0], []).append([flt(i[1]), i[2], i[3], i[4], i[5]])
|
self.item_dict.setdefault(i[0], []).append([flt(i[1]), i[2], i[3], i[4], i[5]])
|
||||||
|
@ -0,0 +1,336 @@
|
|||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# MIT License. See license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import frappe.defaults
|
||||||
|
import unittest
|
||||||
|
from frappe.test_runner import make_test_records
|
||||||
|
|
||||||
|
from erpnext.manufacturing.doctype.production_planning_tool.production_planning_tool import ProductionPlanningTool
|
||||||
|
|
||||||
|
# load test records and dependencies
|
||||||
|
|
||||||
|
test_records = frappe.get_test_records('Production Planning Tool')
|
||||||
|
|
||||||
|
test_dependencies = ["Item","BOM"]
|
||||||
|
|
||||||
|
class TestEvent(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_materials_requests_all_raw_multi_level(self):
|
||||||
|
items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D","_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A","_Test PPT Item SC B","_Test PPT Item Master"]
|
||||||
|
quantities = [14,9,36,1,0,0,0,0,0,0]
|
||||||
|
types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase","Purchase","Manufacture"]
|
||||||
|
|
||||||
|
self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=1, only_raw_materials=1, include_subcontracted=1)
|
||||||
|
|
||||||
|
def test_materials_requests_multi_no_subcontracted(self):
|
||||||
|
items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D","_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A","_Test PPT Item SC B","_Test PPT Item Master"]
|
||||||
|
quantities = [14,5,20,0,0,0,0,0,0,0]
|
||||||
|
types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase","Purchase","Manufacture"]
|
||||||
|
|
||||||
|
# This one should fail for now
|
||||||
|
self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=1, only_raw_materials=1, include_subcontracted=0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_materials_requests_manufacture_and_sub_multi_level(self):
|
||||||
|
items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D","_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A","_Test PPT Item SC B","_Test PPT Item Master"]
|
||||||
|
quantities = [14,9,36,1,2,5,2,1,4,0]
|
||||||
|
types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase","Purchase","Manufacture"]
|
||||||
|
|
||||||
|
self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=1, only_raw_materials=0, include_subcontracted=1)
|
||||||
|
|
||||||
|
def test_materials_requests_manufacture_multi_level(self):
|
||||||
|
items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D","_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A","_Test PPT Item SC B","_Test PPT Item Master"]
|
||||||
|
quantities = [14,5,20,0,2,5,2,1,4,0]
|
||||||
|
types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase","Purchase","Manufacture"]
|
||||||
|
|
||||||
|
self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=1, only_raw_materials=0, include_subcontracted=0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_materials_requests_single_level_purch_only(self):
|
||||||
|
items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D","_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A","_Test PPT Item SC B","_Test PPT Item Master"]
|
||||||
|
quantities = [2,0,0,0,0,0,0,1,0,0]
|
||||||
|
types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase","Purchase","Manufacture"]
|
||||||
|
|
||||||
|
self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=0, only_raw_materials=1, include_subcontracted=0)
|
||||||
|
|
||||||
|
def test_materials_requests_single_level(self):
|
||||||
|
items = ["_Test PPT Item Raw A","_Test PPT Item Raw B","_Test PPT Item Raw C","_Test PPT Item Raw D","_Test PPT Item Sub A","_Test PPT Item Sub B","_Test PPT Item Sub C","_Test PPT Item SC A","_Test PPT Item SC B","_Test PPT Item Master"]
|
||||||
|
quantities = [2,0,0,0,2,1,0,1,0,0]
|
||||||
|
types = ["Purchase","Purchase","Purchase","Purchase","Manufacture","Manufacture","Manufacture","Purchase","Purchase","Manufacture"]
|
||||||
|
|
||||||
|
self.runtest_materials_requests(items, quantities, types, use_multi_level_bom=0, only_raw_materials=0, include_subcontracted=0)
|
||||||
|
|
||||||
|
def runtest_materials_requests(self, items, quantities, types,use_multi_level_bom, only_raw_materials, include_subcontracted):
|
||||||
|
|
||||||
|
clear_material_requests()
|
||||||
|
create_test_records()
|
||||||
|
|
||||||
|
ppt = run_production_planning_tool(use_multi_level_bom=use_multi_level_bom, only_raw_materials=only_raw_materials, include_subcontracted=include_subcontracted, item_code = "_Test PPT Item Master",bom_no = "BOM-_Test PPT Item Master-001", planned_qty = 1, planned_start_date = "5/5/2029", warehouse = "_Test Warehouse - _TC", company = "_Test Company")
|
||||||
|
create_material_requests(ppt)
|
||||||
|
|
||||||
|
for item, qty, type in zip(items, quantities, types):
|
||||||
|
self.assertEqual(qty, get_requested_qty(item))
|
||||||
|
for mat_req_type in get_requested_types(item):
|
||||||
|
self.assertEqual(type, mat_req_type)
|
||||||
|
|
||||||
|
def create_test_records():
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
|
||||||
|
subA = make_item("_Test PPT Item Sub A",{
|
||||||
|
"item_code": "_Test PPT Item Sub A",
|
||||||
|
"item_name": "_Test PPT Item Sub A",
|
||||||
|
"description": "A manufactured _Test PPT Item Sub Assembly",
|
||||||
|
"default_material_request_type": "Manufacture",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
subB = make_item("_Test PPT Item Sub B",{
|
||||||
|
"item_code": "_Test PPT Item Sub B",
|
||||||
|
"item_name": "_Test PPT Item Sub B",
|
||||||
|
"description": "A manufactured _Test PPT Item Sub Assembly",
|
||||||
|
"default_material_request_type": "Manufacture",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
subC = make_item("_Test PPT Item Sub C",{
|
||||||
|
"item_code": "_Test PPT Item Sub C",
|
||||||
|
"item_name": "_Test PPT Item Sub C",
|
||||||
|
"description": "A manufactured _Test PPT Item Sub Assembly",
|
||||||
|
"default_material_request_type": "Manufacture",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
sCA = make_item("_Test PPT Item SC A",{
|
||||||
|
"item_code": "_Test PPT Item SC A",
|
||||||
|
"item_name": "_Test PPT Item SC A",
|
||||||
|
"description": "A subcontracted part with raw materials",
|
||||||
|
"default_material_request_type": "Purchase",
|
||||||
|
"is_sub_contracted_item": 1,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
subA = make_item("_Test PPT Item Sub A",{
|
||||||
|
"item_code": "_Test PPT Item Sub A",
|
||||||
|
"item_name": "_Test PPT Item Sub A",
|
||||||
|
"description": "A manufactured _Test PPT Item Sub Assembly",
|
||||||
|
"default_material_request_type": "Manufacture",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
sCB = make_item("_Test PPT Item SC B",{
|
||||||
|
"item_code": "_Test PPT Item SC B",
|
||||||
|
"item_name": "_Test PPT Item SC B",
|
||||||
|
"description": "A subcontracted part with raw materials",
|
||||||
|
"default_material_request_type": "Purchase",
|
||||||
|
"is_sub_contracted_item": 1,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
rawA = make_item("_Test PPT Item Raw A",{
|
||||||
|
"item_code": "_Test PPT Item Raw A",
|
||||||
|
"item_name": "_Test PPT Item Raw A",
|
||||||
|
"description": "A raw material",
|
||||||
|
"default_material_request_type": "Purchase",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
rawB = make_item("_Test PPT Item Raw B",{
|
||||||
|
"item_code": "_Test PPT Item Raw B",
|
||||||
|
"item_name": "_Test PPT Item Raw B",
|
||||||
|
"description": "A raw material",
|
||||||
|
"default_material_request_type": "Purchase",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
rawC = make_item("_Test PPT Item Raw C",{
|
||||||
|
"item_code": "_Test PPT Item Raw C",
|
||||||
|
"item_name": "_Test PPT Item Raw C",
|
||||||
|
"description": "A raw material",
|
||||||
|
"default_material_request_type": "Purchase",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
rawD = make_item("_Test PPT Item Raw D",{
|
||||||
|
"item_code": "_Test PPT Item Raw D",
|
||||||
|
"item_name": "_Test PPT Item Raw D",
|
||||||
|
"description": "A raw material",
|
||||||
|
"default_material_request_type": "Purchase",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
master = make_item("_Test PPT Item Master",{
|
||||||
|
"item_code": "_Test PPT Item Master",
|
||||||
|
"item_name": "_Test PPT Item Master",
|
||||||
|
"description": "The final assembly",
|
||||||
|
"default_material_request_type": "Manufacture",
|
||||||
|
"is_sub_contracted_item": 0,
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"stock_uom": "_Test UOM",
|
||||||
|
"item_group": "_Test Item Group",
|
||||||
|
"default_warehouse": "_Test Warehouse - _TC"})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bom_subB = make_bom("BOM-_Test PPT Item Sub B-001",{"quantity":1.0,
|
||||||
|
"item": "_Test PPT Item Sub B",
|
||||||
|
"is_active": 1,
|
||||||
|
"is_default": 1,
|
||||||
|
"docstatus": 1,
|
||||||
|
"with_operations": 0}, [{"item_code": "_Test PPT Item Raw B", "doctype":"BOM Item", "qty":1, "rate":100, "amount": 100,"stock_uom": "_Test UOM"},
|
||||||
|
{"item_code": "_Test PPT Item Raw C", "doctype":"BOM Item", "qty":4, "rate":100, "amount": 400,"stock_uom": "_Test UOM"}
|
||||||
|
])
|
||||||
|
|
||||||
|
bom_subC = make_bom("BOM-_Test PPT Item Sub C-001",{"quantity":1,
|
||||||
|
"item": "_Test PPT Item Sub C",
|
||||||
|
"is_active": 1,
|
||||||
|
"is_default": 1,
|
||||||
|
"docstatus": 1,
|
||||||
|
"with_operations": 0}, [{"item_code": "_Test PPT Item Raw A","item_name": "_Test PPT Item Raw A", "doctype":"BOM Item", "qty":6, "rate":100, "amount": 600},
|
||||||
|
{"item_code": "_Test PPT Item Sub B","item_name": "_Test PPT Item Sub B", "bom_no":"BOM-_Test PPT Item Sub B-001", "doctype":"BOM Item", "qty":2, "rate":100, "amount": 200}
|
||||||
|
])
|
||||||
|
|
||||||
|
bom_sCA = make_bom("BOM-_Test PPT Item SC A-001",{"quantity":1,
|
||||||
|
"item": "_Test PPT Item SC A",
|
||||||
|
"is_active": 1,
|
||||||
|
"is_default": 1,
|
||||||
|
"docstatus": 1,
|
||||||
|
"with_operations": 0}, [{"item_code": "_Test PPT Item Raw D","item_name": "_Test PPT Item Raw D", "doctype":"BOM Item", "qty":1, "rate":100, "amount": 100}
|
||||||
|
])
|
||||||
|
|
||||||
|
bom_sCB = make_bom("BOM-_Test PPT Item SC B-001",{"quantity":1,
|
||||||
|
"item": "_Test PPT Item SC B",
|
||||||
|
"is_active": 1,
|
||||||
|
"is_default": 1,
|
||||||
|
"docstatus": 1,
|
||||||
|
"with_operations": 0}, [{"item_code": "_Test PPT Item Raw B","item_name": "_Test PPT Item Raw B","doctype":"BOM Item", "qty":1, "rate":100, "amount": 100},
|
||||||
|
{"item_code": "_Test PPT Item Raw C","item_name": "_Test PPT Item Raw C", "doctype":"BOM Item", "qty":4, "rate":100, "amount": 400}
|
||||||
|
])
|
||||||
|
bom_subA = make_bom("BOM-_Test PPT Item Sub A-001",{"quantity":1,
|
||||||
|
"item": "_Test PPT Item Sub A",
|
||||||
|
"is_active": 1,
|
||||||
|
"is_default": 1,
|
||||||
|
"docstatus": 1,
|
||||||
|
"with_operations": 0}, [{"item_code": "_Test PPT Item Sub C","item_name": "_Test PPT Item Sub C", "bom_no":"BOM-_Test PPT Item Sub C-001", "doctype":"BOM Item", "qty":1, "rate":100, "amount": 100},
|
||||||
|
{"item_code": "_Test PPT Item SC B","item_name": "_Test PPT Item SC B", "bom_no":"BOM-_Test PPT Item SC B-001", "doctype":"BOM Item", "qty":2, "rate":100, "amount": 200}
|
||||||
|
])
|
||||||
|
bom_master = make_bom("BOM-_Test PPT Item Master-001",{"quantity":1,
|
||||||
|
"item": "_Test PPT Item Master",
|
||||||
|
"is_active": 1,
|
||||||
|
"is_default": 1,
|
||||||
|
"docstatus": 1,
|
||||||
|
"with_operations": 0}, [{"item_code": "_Test PPT Item Sub A","item_name": "_Test PPT Item Sub A", "bom_no":"BOM-_Test PPT Item Sub A-001", "doctype":"BOM Item", "qty":2, "rate":100, "amount": 200},
|
||||||
|
{"item_code": "_Test PPT Item Sub B","item_name": "_Test PPT Item Sub B", "bom_no":"BOM-_Test PPT Item Sub B-001", "doctype":"BOM Item", "qty":1, "rate":100, "amount": 100},
|
||||||
|
{"item_code": "_Test PPT Item Raw A","item_name": "_Test PPT Item Raw A", "doctype":"BOM Item", "qty":2, "rate":100, "amount": 200},
|
||||||
|
{"item_code": "_Test PPT Item SC A","item_name": "_Test PPT Item SC A", "bom_no":"BOM-_Test PPT Item SC A-001", "doctype":"BOM Item", "qty":1, "rate":100, "amount": 100}
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def make_bom(name, properties=None, items=None):
|
||||||
|
if frappe.db.exists("BOM", name):
|
||||||
|
return frappe.get_doc("BOM", name)
|
||||||
|
|
||||||
|
bom = frappe.new_doc("BOM")
|
||||||
|
item = frappe.get_doc({
|
||||||
|
"doctype": "BOM",
|
||||||
|
"name": name,
|
||||||
|
"quantity": "1",
|
||||||
|
"with_operations": 0
|
||||||
|
})
|
||||||
|
|
||||||
|
if properties:
|
||||||
|
bom.update(properties)
|
||||||
|
|
||||||
|
if items:
|
||||||
|
for item in items:
|
||||||
|
bom.append("items", item)
|
||||||
|
|
||||||
|
|
||||||
|
bom.insert()
|
||||||
|
bom.submit()
|
||||||
|
|
||||||
|
return bom
|
||||||
|
|
||||||
|
def clear_material_requests():
|
||||||
|
frappe.db.sql("delete from `tabMaterial Request Item`")
|
||||||
|
frappe.db.sql("delete from `tabMaterial Request`")
|
||||||
|
|
||||||
|
|
||||||
|
def run_production_planning_tool(**args):
|
||||||
|
ppt = frappe.new_doc("Production Planning Tool")
|
||||||
|
args = frappe._dict(args)
|
||||||
|
|
||||||
|
if args.use_multi_level_bom:
|
||||||
|
ppt.use_multi_level_bom = args.use_multi_level_bom
|
||||||
|
else:
|
||||||
|
ppt.use_multi_level_bom = 0
|
||||||
|
|
||||||
|
if args.only_raw_materials:
|
||||||
|
ppt.only_raw_materials = args.only_raw_materials
|
||||||
|
else:
|
||||||
|
ppt.only_raw_materials = 0
|
||||||
|
|
||||||
|
if args.include_subcontracted:
|
||||||
|
ppt.include_subcontracted = args.include_subcontracted
|
||||||
|
else:
|
||||||
|
ppt.include_subcontracted = 0
|
||||||
|
|
||||||
|
if args.warehouse:
|
||||||
|
ppt.purchase_request_for_warehouse = args.warehouse
|
||||||
|
|
||||||
|
if args.company:
|
||||||
|
ppt.company = args.company
|
||||||
|
ppt.create_material_requests_for_all_required_qty = 1
|
||||||
|
|
||||||
|
ppt.append("items",{"item_code": args.item_code, "bom_no": args.bom_no, "planned_qty": args.planned_qty, "planned_start_date": args.planned_start_date, "warehouse": args.warehouse})
|
||||||
|
|
||||||
|
return ppt
|
||||||
|
|
||||||
|
def create_production_orders(ppt):
|
||||||
|
raise_production_orders(ppt)
|
||||||
|
|
||||||
|
def create_material_requests(ppt):
|
||||||
|
ppt.raise_material_requests()
|
||||||
|
|
||||||
|
def get_requested_qty(item_code):
|
||||||
|
total_qty = 0
|
||||||
|
for d in frappe.db.sql("""select item.qty as qty from `tabMaterial Request` mat_req, `tabMaterial Request Item` item
|
||||||
|
where item.item_code = %(item_code)s and item.parent = mat_req.name""", {"item_code":item_code}, as_dict=1):
|
||||||
|
total_qty += d.qty
|
||||||
|
return total_qty
|
||||||
|
|
||||||
|
def get_requested_types(item_code):
|
||||||
|
types = []
|
||||||
|
for d in frappe.db.sql("""select mat_req.material_request_type as type from `tabMaterial Request` mat_req, `tabMaterial Request Item` item
|
||||||
|
where item.item_code = %(item_code)s and item.parent = mat_req.name""", {"item_code":item_code}, as_dict=1):
|
||||||
|
types.append(d.type)
|
||||||
|
return types
|
||||||
|
|
@ -0,0 +1,3 @@
|
|||||||
|
[
|
||||||
|
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user