refactor code in Production Planning Tool
diff --git a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
index 6596e23..6138435 100644
--- a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
+++ b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
@@ -120,6 +120,54 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "fieldname": "column_break_6",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "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,
+ "description": "Reserved Warehouse in Sales Order / Finished Goods Warehouse",
+ "fieldname": "warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "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,
"fieldname": "sales_order",
"fieldtype": "Link",
"hidden": 0,
@@ -160,7 +208,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -198,31 +246,6 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "description": "Reserved Warehouse in Sales Order / Finished Goods Warehouse",
- "fieldname": "warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Warehouse",
- "length": 0,
- "no_copy": 0,
- "options": "Warehouse",
- "permlevel": 0,
- "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,
"fieldname": "stock_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -308,7 +331,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-02-10 07:08:38.461787",
+ "modified": "2016-02-11 05:08:19.492712",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan Item",
diff --git a/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json b/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json
index 0522e7a..1a7c894 100644
--- a/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json
+++ b/erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json
@@ -66,7 +66,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "material_request_date",
- "fieldtype": "Date",
+ "fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
@@ -76,6 +76,7 @@
"no_copy": 0,
"oldfieldname": "document_date",
"oldfieldtype": "Date",
+ "options": "material_request.transaction_date",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -99,7 +100,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-02-10 05:13:07.529068",
+ "modified": "2016-02-11 04:21:34.372317",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan Material Request",
diff --git a/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json b/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json
index bed893f..85bf7d6 100644
--- a/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json
+++ b/erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json
@@ -41,7 +41,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "sales_order_date",
- "fieldtype": "Date",
+ "fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
@@ -51,11 +51,12 @@
"no_copy": 0,
"oldfieldname": "document_date",
"oldfieldtype": "Date",
+ "options": "sales_order.transaction_date",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "120px",
- "read_only": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -91,7 +92,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "customer",
- "fieldtype": "Link",
+ "fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
@@ -99,7 +100,7 @@
"label": "Customer",
"length": 0,
"no_copy": 0,
- "options": "Customer",
+ "options": "sales_order.customer",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -116,8 +117,9 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "default": "",
"fieldname": "grand_total",
- "fieldtype": "Currency",
+ "fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
@@ -125,7 +127,7 @@
"label": "Grand Total",
"length": 0,
"no_copy": 0,
- "options": "Company:company:default_currency",
+ "options": "sales_order.base_grand_total",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -148,7 +150,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-02-10 05:13:30.301297",
+ "modified": "2016-02-11 04:17:42.849873",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan Sales Order",
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
index 15c4245..3fa1160 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js
@@ -5,24 +5,25 @@
cur_frm.cscript.onload = function(doc, cdt, cdn) {
cur_frm.set_value("company", frappe.defaults.get_user_default("Company"))
- cur_frm.set_value("use_multi_level_bom", 1)
}
cur_frm.cscript.refresh = function(doc) {
cur_frm.disable_save();
}
-cur_frm.cscript.sales_order = function(doc,cdt,cdn) {
- var d = locals[cdt][cdn];
- if (d.sales_order) {
- return get_server_fields('get_so_details', d.sales_order, 'sales_orders', doc, cdt, cdn, 1);
- }
-}
-
cur_frm.cscript.item_code = function(doc,cdt,cdn) {
var d = locals[cdt][cdn];
if (d.item_code) {
- return get_server_fields('get_item_details', d.item_code, 'items', doc, cdt, cdn, 1);
+ frappe.call({
+ method: "erpnext.manufacturing.doctype.production_order.production_order.get_item_details",
+ args: {
+ "item" : d.item_code
+ },
+ callback: function(r) {
+ $.extend(d, r.message);
+ refresh_field("items");
+ }
+ });
}
}
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
index 3f04713..19b5fd9 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json
@@ -510,7 +510,7 @@
"label": "Create Production Orders",
"length": 0,
"no_copy": 0,
- "options": "raise_production_order",
+ "options": "raise_production_orders",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -629,7 +629,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-02-10 07:28:50.298538",
+ "modified": "2016-02-11 06:18:45.077263",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Planning Tool",
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
index 4be22e4..bec97d1 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
@@ -16,28 +16,8 @@
super(ProductionPlanningTool, self).__init__(arg1, arg2)
self.item_dict = {}
- def get_so_details(self, so):
- """Pull other details from so"""
- so = frappe.db.sql("""select transaction_date, customer, base_grand_total
- from `tabSales Order` where name = %s""", so, as_dict = 1)
- ret = {
- 'sales_order_date': so and so[0]['transaction_date'] or '',
- 'customer' : so[0]['customer'] or '',
- 'grand_total': so[0]['base_grand_total']
- }
- return ret
-
- def get_item_details(self, item_code):
- return get_item_details(item_code)
-
- def clear_so_table(self):
- self.set('sales_orders', [])
-
- def clear_mr_table(self):
- self.set('material_requests', [])
-
- def clear_item_table(self):
- self.set('items', [])
+ def clear_table(self, table_name):
+ self.set(table_name, [])
def validate_company(self):
if not self.company:
@@ -81,7 +61,7 @@
def add_so_in_table(self, open_so):
""" Add sales orders in the table"""
- self.clear_so_table()
+ self.clear_table("sales_orders")
so_list = [d.sales_order for d in self.get('sales_orders')]
for r in open_so:
@@ -125,7 +105,7 @@
def add_mr_in_table(self, pending_mr):
""" Add Material Requests in the table"""
- self.clear_mr_table()
+ self.clear_table("material_requests")
mr_list = [d.material_request for d in self.get('material_requests')]
for r in pending_mr:
@@ -199,7 +179,7 @@
def add_items(self, items):
- self.clear_item_table()
+ self.clear_table("items")
for p in items:
item_details = get_item_details(p['item_code'])
pi = self.append('items', {})
@@ -220,97 +200,108 @@
def validate_data(self):
self.validate_company()
for d in self.get('items'):
- validate_bom_no(d.item_code, d.bom_no)
+ if not d.bom_no:
+ frappe.throw(_("Please select BOM for Item in Row {0}".format(d.idx)))
+ else:
+ validate_bom_no(d.item_code, d.bom_no)
+
if not flt(d.planned_qty):
frappe.throw(_("Please enter Planned Qty for Item {0} at row {1}").format(d.item_code, d.idx))
- def raise_production_order(self):
+ def raise_production_orders(self):
"""It will raise production order (Draft) for all distinct FG items"""
self.validate_data()
from erpnext.utilities.transaction_base import validate_uom_is_integer
validate_uom_is_integer(self, "stock_uom", "planned_qty")
- items = self.get_distinct_items_and_boms()[1]
- pro = self.create_production_order(items)
- if pro:
- pro = ["""<a href="#Form/Production Order/%s" target="_blank">%s</a>""" % \
- (p, p) for p in pro]
- msgprint(_("{0} created").format(comma_and(pro)))
+ items = self.get_production_items()
+
+ pro_list = []
+ frappe.flags.mute_messages = True
+
+ for key in items:
+ production_order = self.create_production_order(items[key])
+ if production_order:
+ pro_list.append(production_order)
+
+ frappe.flags.mute_messages = False
+
+ if pro_list:
+ pro_list = ["""<a href="#Form/Production Order/%s" target="_blank">%s</a>""" % \
+ (p, p) for p in pro_list]
+ msgprint(_("{0} created").format(comma_and(pro_list)))
else :
msgprint(_("No Production Orders created"))
- def get_distinct_items_and_boms(self):
- """ Club similar BOM and item for processing
+ def get_production_items(self):
+ item_dict = {}
+ for d in self.get("items"):
+ item_details= {
+ "production_item" : d.item_code,
+ "sales_order" : d.sales_order,
+ "material_request" : d.material_request,
+ "material_request_item" : d.material_request_item,
+ "bom_no" : d.bom_no,
+ "description" : d.description,
+ "stock_uom" : d.stock_uom,
+ "company" : self.company,
+ "wip_warehouse" : "",
+ "fg_warehouse" : d.warehouse,
+ "status" : "Draft",
+ }
+
+ """ Club similar BOM and item for processing in case of Sales Orders """
+ if self.plan_using == "Sales Order":
+ item_details.update({
+ "qty":flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
+ .get("qty")) + flt(d.planned_qty)
+ })
+ item_dict[(d.item_code, d.sales_order, d.warehouse)] = item_details
+
+ elif self.plan_using == "Material Request":
+ item_details.update({
+ "qty": d.planned_qty
+ })
+ item_dict[(d.item_code, d.material_request_item, d.warehouse)] = item_details
+
+ return item_dict
+
+ def create_production_order(self, item_dict):
+ """Create production order. Called from Production Planning Tool"""
+ from erpnext.manufacturing.doctype.production_order.production_order import OverProductionError, get_default_warehouse
+ warehouse = get_default_warehouse()
+ pro = frappe.new_doc("Production Order")
+ pro.update(item_dict)
+ pro.set_production_order_operations()
+ if warehouse:
+ pro.wip_warehouse = warehouse.get('wip_warehouse')
+ if not pro.fg_warehouse:
+ pro.fg_warehouse = warehouse.get('fg_warehouse')
+
+ try:
+ pro.insert()
+ return pro.name
+ except OverProductionError:
+ pass
+
+ def get_so_wise_planned_qty(self):
+ """
bom_dict {
bom_no: ['sales_order', 'qty']
}
"""
- item_dict, bom_dict = {}, {}
+ bom_dict = {}
for d in self.get("items"):
- if d.bom_no:
- if self.plan_using == "Sales Order":
- bom_dict.setdefault(d.bom_no, []).append([d.sales_order, flt(d.planned_qty)])
- if frappe.db.get_value("Item", d.item_code, "is_pro_applicable"):
- item_dict[(d.item_code, d.sales_order, d.warehouse)] = {
- "production_item" : d.item_code,
- "sales_order" : d.sales_order,
- "qty" : flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),
- {}).get("qty")) + flt(d.planned_qty),
- "bom_no" : d.bom_no,
- "description" : d.description,
- "stock_uom" : d.stock_uom,
- "company" : self.company,
- "wip_warehouse" : "",
- "fg_warehouse" : d.warehouse,
- "status" : "Draft",
- }
- elif self.plan_using == "Material Request":
- bom_dict.setdefault(d.bom_no, []).append([d.material_request_item, flt(d.planned_qty)])
- if frappe.db.get_value("Item", d.item_code, "is_pro_applicable"):
- item_dict[(d.item_code, d.material_request_item, d.warehouse)] = {
- "production_item" : d.item_code,
- "material_request" : d.material_request,
- "material_request_item" : d.material_request_item,
- "qty" : d.planned_qty,
- "bom_no" : d.bom_no,
- "description" : d.description,
- "stock_uom" : d.stock_uom,
- "company" : self.company,
- "wip_warehouse" : "",
- "fg_warehouse" : d.warehouse,
- "status" : "Draft",
- }
- return bom_dict, item_dict
-
- def create_production_order(self, items):
- """Create production order. Called from Production Planning Tool"""
- from erpnext.manufacturing.doctype.production_order.production_order import OverProductionError, get_default_warehouse
- warehouse = get_default_warehouse()
- pro_list = []
- for key in items:
- pro = frappe.new_doc("Production Order")
- pro.update(items[key])
- pro.set_production_order_operations()
- if warehouse:
- pro.wip_warehouse = warehouse.get('wip_warehouse')
- if not pro.fg_warehouse:
- pro.fg_warehouse = warehouse.get('fg_warehouse')
- frappe.flags.mute_messages = True
-
- try:
- pro.insert()
- pro_list.append(pro.name)
- except OverProductionError:
- pass
-
- frappe.flags.mute_messages = False
- return pro_list
-
+ if self.plan_using == "Sales Order":
+ bom_dict.setdefault(d.bom_no, []).append({d.sales_order: flt(d.planned_qty)})
+ elif self.plan_using == "Material Request":
+ bom_dict.setdefault(d.bom_no, []).append({d.material_request_item: flt(d.planned_qty)})
+
def download_raw_materials(self):
""" Create csv data for required raw material to produce finished goods"""
self.validate_data()
- bom_dict = self.get_distinct_items_and_boms()[0]
+ bom_dict = self.get_so_wise_planned_qty()
self.get_raw_materials(bom_dict)
return self.get_csv()
@@ -389,7 +380,7 @@
if not self.purchase_request_for_warehouse:
frappe.throw(_("Please enter Warehouse for which Material Request will be raised"))
- bom_dict = self.get_distinct_items_and_boms()[0]
+ bom_dict = self.get_so_wise_planned_qty()
self.get_raw_materials(bom_dict)
if self.item_dict:
@@ -445,12 +436,12 @@
def insert_purchase_request(self):
items_to_be_requested = self.get_requested_items()
- purchase_request_list = []
+ material_request_list = []
if items_to_be_requested:
for item in items_to_be_requested:
item_wrapper = frappe.get_doc("Item", item)
- pr_doc = frappe.new_doc("Material Request")
- pr_doc.update({
+ material_request = frappe.new_doc("Material Request")
+ material_request.update({
"transaction_date": nowdate(),
"status": "Draft",
"company": self.company,
@@ -458,7 +449,7 @@
"material_request_type": "Purchase"
})
for sales_order, requested_qty in items_to_be_requested[item].items():
- pr_doc.append("items", {
+ material_request.append("items", {
"doctype": "Material Request Item",
"__islocal": 1,
"item_code": item,
@@ -473,13 +464,13 @@
"sales_order": sales_order if sales_order!="No Sales Order" else None
})
- pr_doc.flags.ignore_permissions = 1
- pr_doc.submit()
- purchase_request_list.append(pr_doc.name)
+ material_request.flags.ignore_permissions = 1
+ material_request.submit()
+ material_request_list.append(material_request.name)
- if purchase_request_list:
- pur_req = ["""<a href="#Form/Material Request/%s" target="_blank">%s</a>""" % \
- (p, p) for p in purchase_request_list]
- msgprint(_("Material Requests {0} created").format(comma_and(pur_req)))
+ if material_request_list:
+ message = ["""<a href="#Form/Material Request/%s" target="_blank">%s</a>""" % \
+ (p, p) for p in material_request_list]
+ msgprint(_("Material Requests {0} created").format(comma_and(message)))
else:
msgprint(_("Nothing to request"))