mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-31 18:59:08 +00:00
Production cleanup with linking with sales order
This commit is contained in:
@@ -73,7 +73,7 @@ class DocType:
|
||||
|
||||
|
||||
# Raise Production Order
|
||||
def create_production_order(self,company, pp_items):
|
||||
def create_production_order(self, items):
|
||||
"""Create production order. Called from Production Planning Tool"""
|
||||
|
||||
default_values = {
|
||||
@@ -82,15 +82,20 @@ class DocType:
|
||||
'wip_warehouse' : '',
|
||||
'fg_warehouse' : '',
|
||||
'status' : 'Draft',
|
||||
'company' : company,
|
||||
'fiscal_year' : get_defaults()['fiscal_year']
|
||||
'fiscal_year' : get_defaults()['fiscal_year']
|
||||
}
|
||||
pro_list = []
|
||||
|
||||
for d in pp_items:
|
||||
for item_so in items:
|
||||
if item_so[1]:
|
||||
self.validate_production_order_against_so(
|
||||
item_so[0], item_so[1], items[item_so].get("qty"))
|
||||
|
||||
pro_doc = Document('Production Order')
|
||||
for key in d.keys():
|
||||
pro_doc.fields[key] = d[key]
|
||||
pro_doc.production_item = item_so[0]
|
||||
pro_doc.sales_order = item_so[1]
|
||||
for key in items[item_so]:
|
||||
pro_doc.fields[key] = items[item_so][key]
|
||||
|
||||
for key in default_values:
|
||||
pro_doc.fields[key] = default_values[key]
|
||||
@@ -100,7 +105,30 @@ class DocType:
|
||||
|
||||
return pro_list
|
||||
|
||||
|
||||
def validate_production_order_against_so(self, item, sales_order, qty, pro_order=None):
|
||||
# already ordered qty
|
||||
ordered_qty_against_so = webnotes.conn.sql("""select sum(qty) from `tabProduction Order`
|
||||
where production_item = %s and sales_order = %s and name != %s""",
|
||||
(item, sales_order, cstr(pro_order)))[0][0]
|
||||
# qty including current
|
||||
total_ordered_qty_against_so = flt(ordered_qty_against_so) + flt(qty)
|
||||
|
||||
# get qty from Sales Order Item table
|
||||
so_item_qty = webnotes.conn.sql("""select sum(qty) from `tabSales Order Item`
|
||||
where parent = %s and item_code = %s""", (sales_order, item))[0][0]
|
||||
# get qty from Packing Item table
|
||||
dnpi_qty = webnotes.conn.sql("""select sum(qty) from `tabDelivery Note Packing Item`
|
||||
where parent = %s and parenttype = 'Sales Order' and item_code = %s""",
|
||||
(sales_order, item))[0][0]
|
||||
# total qty in SO
|
||||
so_qty = flt(so_item_qty) + flt(dnpi_qty)
|
||||
|
||||
if total_ordered_qty_against_so > so_qty:
|
||||
msgprint("""Total production order qty for item: %s against sales order: %s \
|
||||
will be %s, which is greater than sales order qty (%s).
|
||||
Please reduce qty or remove the item.""" %
|
||||
(item, sales_order, total_ordered_qty_against_so, so_qty), raise_exception=1)
|
||||
|
||||
def update_bom(self, bom_no):
|
||||
main_bom_list = self.traverse_bom_tree(bom_no, 1)
|
||||
main_bom_list.reverse()
|
||||
@@ -113,4 +141,4 @@ class DocType:
|
||||
bom_obj.update_flat_bom_engine()
|
||||
bom_obj.doc.docstatus = 1
|
||||
bom_obj.doc.save()
|
||||
self.check_bom_list.append(bom)
|
||||
self.check_bom_list.append(bom)
|
||||
@@ -18,15 +18,7 @@
|
||||
cur_frm.cscript.onload = function(doc, dt, dn) {
|
||||
if (!doc.posting_date) doc.transaction_date = dateutil.obj_to_str(new Date());
|
||||
if (!doc.status) doc.status = 'Draft';
|
||||
|
||||
cfn_set_fields(doc, dt, dn);
|
||||
|
||||
if (doc.origin != "MRP"){
|
||||
doc.origin = "Manual";
|
||||
set_field_permlevel('production_item', 0);
|
||||
set_field_permlevel('bom_no', 0);
|
||||
set_field_permlevel('consider_sa_items',0);
|
||||
}
|
||||
}
|
||||
|
||||
// ================================== Refresh ==========================================
|
||||
@@ -48,15 +40,10 @@ var cfn_set_fields = function(doc, dt, dn) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================================================================================================
|
||||
|
||||
cur_frm.cscript.production_item = function(doc, dt, dn) {
|
||||
get_server_fields('get_item_detail',doc.production_item,'',doc,dt,dn,1);
|
||||
}
|
||||
|
||||
// Stop PRODUCTION ORDER
|
||||
//
|
||||
cur_frm.cscript['Stop Production Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
var check = confirm("Do you really want to stop production order: " + doc.name);
|
||||
@@ -65,8 +52,6 @@ cur_frm.cscript['Stop Production Order'] = function() {
|
||||
}
|
||||
}
|
||||
|
||||
// Unstop PRODUCTION ORDER
|
||||
//
|
||||
cur_frm.cscript['Unstop Production Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
var check = confirm("Do really want to unstop production order: " + doc.name);
|
||||
@@ -97,8 +82,6 @@ cur_frm.cscript.make_se = function(doc, process) {
|
||||
loaddoc('Stock Entry', se.name);
|
||||
}
|
||||
|
||||
|
||||
// ==================================================================================================
|
||||
cur_frm.fields_dict['production_item'].get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabItem`.`name`, `tabItem`.`description` FROM `tabItem` WHERE (IFNULL(`tabItem`.`end_of_life`,"") = "" OR `tabItem`.`end_of_life` = "0000-00-00" OR `tabItem`.`end_of_life` > NOW()) AND `tabItem`.docstatus != 2 AND `tabItem`.is_pro_applicable = "Yes" AND `tabItem`.%(key)s LIKE "%s" ORDER BY `tabItem`.`name` LIMIT 50';
|
||||
}
|
||||
|
||||
@@ -72,6 +72,14 @@ class DocType:
|
||||
msgprint("""Incorrect BOM: %s entered.
|
||||
May be BOM not exists or inactive or not submitted
|
||||
or for some other item.""" % cstr(self.doc.bom_no), raise_exception=1)
|
||||
|
||||
if self.doc.sales_order:
|
||||
if not webnotes.conn.sql("""select name from `tabSales Order`
|
||||
where name=%s and docstatus = 1""", self.doc.sales_order):
|
||||
msgprint("Sales Order: %s is not valid" % self.doc.sales_order, raise_exception=1)
|
||||
|
||||
get_obj("Production Control").validate_production_order_against_so(
|
||||
self.doc.production_item, self.doc.sales_order, self.doc.qty, self.doc.name)
|
||||
|
||||
|
||||
def stop_unstop(self, status):
|
||||
|
||||
@@ -1,358 +1,324 @@
|
||||
# DocType, Production Order
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-05-15 12:14:48',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-05-28 19:03:56',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1325837006',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'in_create': 0,
|
||||
'is_submittable': 1,
|
||||
'module': u'Production',
|
||||
'name': '__common__',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Production Order',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Production Order',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Production Order
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Production Order'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Production Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Production User',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Item for which this Production Order is raised.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'production_item',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Production Item',
|
||||
'oldfieldname': u'production_item',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 1,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Stock UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Bill of Material which was considered for manufacturing the production item.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'bom_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'BOM No',
|
||||
'oldfieldname': u'bom_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'BOM',
|
||||
'permlevel': 1,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Quantity of item for which Production Order is raised.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The warehouse for finished goods where stock of produced items will be updated.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fg_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'FG Warehouse',
|
||||
'oldfieldname': u'fg_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The work in progress warehouse where raw materials will be operated upon to create finished goods.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'wip_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'WIP Warehouse',
|
||||
'oldfieldname': u'wip_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amended_from',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Amended From',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amended_from',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amendment_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Amendment Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amendment_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The date on which current entry will get or has actually executed.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'posting_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Posting Date',
|
||||
'oldfieldname': u'posting_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Select "Yes" if stock is maintained and tracked for sub-assembly items. Select "No" if you want child items of sub-assembly for material transfer.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'consider_sa_items',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Consider SA Items as raw material',
|
||||
'oldfieldname': u'consider_sa_items',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nYes\nNo',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'description': u'Select name of the project if Production Order need to be created against any project',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'project_name',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Project Name',
|
||||
'oldfieldname': u'project_name',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Project',
|
||||
'permlevel': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'origin',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Origin',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'origin',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'Manual\nMRP',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'status',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Status',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'status',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled',
|
||||
'permlevel': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Updated after finished goods are transferred to FG Warehouse through Stock Entry',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'produced_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Produced Qty',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'produced_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Company',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
}
|
||||
{
|
||||
"owner": "Administrator",
|
||||
"docstatus": 0,
|
||||
"creation": "2012-07-03 13:30:03",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2012-11-30 14:28:03"
|
||||
},
|
||||
{
|
||||
"is_submittable": 1,
|
||||
"in_create": 0,
|
||||
"default_print_format": "Standard",
|
||||
"doctype": "DocType",
|
||||
"module": "Production",
|
||||
"name": "__common__"
|
||||
},
|
||||
{
|
||||
"name": "__common__",
|
||||
"parent": "Production Order",
|
||||
"doctype": "DocField",
|
||||
"parenttype": "DocType",
|
||||
"parentfield": "fields"
|
||||
},
|
||||
{
|
||||
"name": "__common__",
|
||||
"parent": "Production Order",
|
||||
"read": 1,
|
||||
"doctype": "DocPerm",
|
||||
"parenttype": "DocType",
|
||||
"parentfield": "permissions"
|
||||
},
|
||||
{
|
||||
"name": "Production Order",
|
||||
"doctype": "DocType"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"width": "50%",
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "Item for which this Production Order is raised.",
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Production Item",
|
||||
"oldfieldname": "production_item",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"reqd": 1,
|
||||
"in_filter": 1,
|
||||
"options": "Item"
|
||||
},
|
||||
{
|
||||
"description": "Bill of Material which was considered for manufacturing the production item.",
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "BOM No",
|
||||
"oldfieldname": "bom_no",
|
||||
"permlevel": 0,
|
||||
"trigger": "Client",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"reqd": 1,
|
||||
"options": "BOM"
|
||||
},
|
||||
{
|
||||
"description": "Quantity of item for which Production Order is raised.",
|
||||
"oldfieldtype": "Currency",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Qty",
|
||||
"oldfieldname": "qty",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Currency",
|
||||
"reqd": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "The date on which current entry will get or has actually executed.",
|
||||
"oldfieldtype": "Date",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Posting Date",
|
||||
"oldfieldname": "posting_date",
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"reqd": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Column Break",
|
||||
"doctype": "DocField",
|
||||
"width": "50%",
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "The warehouse for finished goods where stock of produced items will be updated.",
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "FG Warehouse",
|
||||
"oldfieldname": "fg_warehouse",
|
||||
"permlevel": 0,
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"reqd": 1,
|
||||
"in_filter": 1,
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"description": "The work in progress warehouse where raw materials will be operated upon to create finished goods.",
|
||||
"oldfieldtype": "Link",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "WIP Warehouse",
|
||||
"oldfieldname": "wip_warehouse",
|
||||
"permlevel": 0,
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"reqd": 1,
|
||||
"in_filter": 1,
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"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.",
|
||||
"default": "1",
|
||||
"oldfieldtype": "Select",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"oldfieldname": "consider_sa_items",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"reqd": 1,
|
||||
"in_filter": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "Updated after finished goods are transferred to FG Warehouse through Stock Entry",
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Currency",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Produced Qty",
|
||||
"oldfieldname": "produced_qty",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Currency",
|
||||
"permlevel": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"label": "More Info",
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"width": "50%",
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Select",
|
||||
"doctype": "DocField",
|
||||
"label": "Origin",
|
||||
"oldfieldname": "origin",
|
||||
"options": "Manual\nMRP",
|
||||
"fieldname": "origin",
|
||||
"fieldtype": "Select",
|
||||
"reqd": 1,
|
||||
"permlevel": 0,
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Select",
|
||||
"doctype": "DocField",
|
||||
"label": "Status",
|
||||
"oldfieldname": "status",
|
||||
"permlevel": 1,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"search_index": 1,
|
||||
"reqd": 1,
|
||||
"options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled",
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"label": "Sales Order",
|
||||
"options": "Sales Order",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "Select name of the project if Production Order need to be created against any project",
|
||||
"oldfieldtype": "Link",
|
||||
"label": "Project Name",
|
||||
"oldfieldname": "project_name",
|
||||
"trigger": "Client",
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"doctype": "DocField",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Link",
|
||||
"doctype": "DocField",
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"options": "Company",
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"reqd": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Select",
|
||||
"doctype": "DocField",
|
||||
"label": "Fiscal Year",
|
||||
"oldfieldname": "fiscal_year",
|
||||
"options": "link:Fiscal Year",
|
||||
"fieldname": "fiscal_year",
|
||||
"fieldtype": "Select",
|
||||
"reqd": 1,
|
||||
"permlevel": 0,
|
||||
"in_filter": 1
|
||||
},
|
||||
{
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Data",
|
||||
"doctype": "DocField",
|
||||
"label": "Amended From",
|
||||
"oldfieldname": "amended_from",
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"permlevel": 1
|
||||
},
|
||||
{
|
||||
"no_copy": 1,
|
||||
"oldfieldtype": "Date",
|
||||
"doctype": "DocField",
|
||||
"label": "Amendment Date",
|
||||
"oldfieldname": "amendment_date",
|
||||
"fieldname": "amendment_date",
|
||||
"fieldtype": "Date",
|
||||
"permlevel": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"width": "50%",
|
||||
"fieldname": "column_break3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Data",
|
||||
"doctype": "DocField",
|
||||
"label": "Stock UOM",
|
||||
"oldfieldname": "stock_uom",
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Data",
|
||||
"permlevel": 1
|
||||
},
|
||||
{
|
||||
"oldfieldtype": "Text",
|
||||
"doctype": "DocField",
|
||||
"label": "Production Item Description",
|
||||
"oldfieldname": "description",
|
||||
"width": "300px",
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"submit": 1,
|
||||
"write": 1,
|
||||
"role": "System Manager",
|
||||
"cancel": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"role": "All",
|
||||
"permlevel": 1
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"submit": 1,
|
||||
"write": 1,
|
||||
"role": "Production Manager",
|
||||
"cancel": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"submit": 1,
|
||||
"write": 1,
|
||||
"role": "Production User",
|
||||
"cancel": 1,
|
||||
"permlevel": 0
|
||||
}
|
||||
]
|
||||
@@ -170,39 +170,58 @@ class DocType:
|
||||
msgprint("Please Enter Planned Qty for item: %s at row no: %s" %
|
||||
(d.item_code, d.idx), raise_exception=1)
|
||||
|
||||
|
||||
def validate_bom_no(self, d):
|
||||
if not d.bom_no:
|
||||
msgprint("Please enter bom no for item: %s at row no: %s" % (d.item_code, d.idx), raise_exception=1)
|
||||
msgprint("Please enter bom no for item: %s at row no: %s" %
|
||||
(d.item_code, d.idx), raise_exception=1)
|
||||
else:
|
||||
bom = sql("""select name from `tabBOM` where item = %s and docstatus = 1
|
||||
and name = %s and ifnull(is_active, 'No') = 'Yes'""", (d.item_code, d.bom_no), as_dict = 1)
|
||||
bom = sql("""select name from `tabBOM` where name = %s and item = %s
|
||||
and docstatus = 1 and ifnull(is_active, 'No') = 'Yes'""",
|
||||
(d.bom_no, d.item_code), as_dict = 1)
|
||||
if not bom:
|
||||
msgprint("""Incorrect BOM No: %s entered for item: %s at row no: %s
|
||||
May be BOM is inactive or for other item or does not exists in the system"""% (d.bom_no, d.item_doce, d.idx))
|
||||
May be BOM is inactive or for other item or does not exists in the system""" %
|
||||
(d.bom_no, d.item_doce, d.idx), raise_exception=1)
|
||||
|
||||
def raise_production_order(self):
|
||||
"""It will raise production order (Draft) for all distinct FG items"""
|
||||
self.validate_company()
|
||||
self.validate_data()
|
||||
|
||||
items = self.get_distinct_items_and_boms()[1]
|
||||
pro = get_obj('Production Control').create_production_order(items)
|
||||
if pro:
|
||||
msgprint("Following Production Order has been generated:\n" + '\n'.join(pro))
|
||||
else :
|
||||
msgprint("No Production Order generated.")
|
||||
|
||||
|
||||
def get_distinct_items_and_boms(self):
|
||||
""" Club similar BOM and item for processing"""
|
||||
item_dict, bom_dict = {}, {}
|
||||
for d in self.doclist.get({"parentfield": "pp_details"}):
|
||||
bom_dict[d.bom_no] = bom_dict.get(d.bom_no, 0) + flt(d.planned_qty)
|
||||
item_dict[(d.item_code, d.sales_order)] = {
|
||||
"qty" : flt(item_dict.get((d.item_code, d.sales_order), {}).get("qty")) + \
|
||||
flt(d.planned_qty),
|
||||
"bom_no": d.bom_no,
|
||||
"description": d.description,
|
||||
"stock_uom": d.stock_uom,
|
||||
"use_multi_level_bom": self.doc.use_multi_level_bom,
|
||||
"company": self.doc.company,
|
||||
}
|
||||
return bom_dict, item_dict
|
||||
|
||||
def download_raw_materials(self):
|
||||
""" Create csv data for required raw material to produce finished goods"""
|
||||
bom_dict = self.get_distinct_bom(action = 'download_rm')
|
||||
bom_dict = self.get_distinct_items_and_boms()[0]
|
||||
self.get_raw_materials(bom_dict)
|
||||
return self.get_csv()
|
||||
|
||||
def get_raw_materials(self, bom_dict):
|
||||
""" Get raw materials considering sub-assembly items """
|
||||
for bom in bom_dict:
|
||||
if self.doc.use_multi_level_bom == 'No':
|
||||
# Get all raw materials considering SA items as raw materials,
|
||||
# so no childs of SA items
|
||||
fl_bom_items = sql("""
|
||||
select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom
|
||||
from `tabBOM Item`
|
||||
where parent = '%s' and docstatus < 2
|
||||
group by item_code
|
||||
""" % (flt(bom_dict[bom]), bom))
|
||||
|
||||
else:
|
||||
if self.doc.use_multi_level_bom:
|
||||
# get all raw materials with sub assembly childs
|
||||
fl_bom_items = sql("""
|
||||
select
|
||||
@@ -216,7 +235,16 @@ class DocType:
|
||||
) a
|
||||
group by item_code,stock_uom
|
||||
""" , (flt(bom_dict[bom]), bom))
|
||||
|
||||
else:
|
||||
# Get all raw materials considering SA items as raw materials,
|
||||
# so no childs of SA items
|
||||
fl_bom_items = sql("""
|
||||
select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s', description, stock_uom
|
||||
from `tabBOM Item`
|
||||
where parent = '%s' and docstatus < 2
|
||||
group by item_code
|
||||
""" % (flt(bom_dict[bom]), bom))
|
||||
|
||||
self.make_items_dict(fl_bom_items)
|
||||
|
||||
|
||||
@@ -238,44 +266,4 @@ class DocType:
|
||||
if item_qty:
|
||||
item_list.append(['', '', '', '', 'Total', i_qty, o_qty, a_qty])
|
||||
|
||||
return item_list
|
||||
|
||||
def raise_production_order(self):
|
||||
"""It will raise production order (Draft) for all distinct FG items"""
|
||||
self.validate_company()
|
||||
self.validate_data()
|
||||
|
||||
pp_items = self.get_distinct_bom(action = 'raise_pro_order')
|
||||
pro = get_obj(dt = 'Production Control').create_production_order(self.doc.company, pp_items)
|
||||
if pro:
|
||||
for d in getlist(self.doclist, 'pp_details'):
|
||||
d.is_pro_created = 1
|
||||
msgprint("Following Production Order has been generated:\n" + '\n'.join(pro))
|
||||
else :
|
||||
msgprint("No Production Order generated.")
|
||||
|
||||
|
||||
def get_distinct_bom(self, action):
|
||||
""" Club similar BOM and item for processing"""
|
||||
|
||||
bom_dict, item_dict, pp_items = {}, {}, []
|
||||
for d in getlist(self.doclist, 'pp_details'):
|
||||
if action == 'download_rm':
|
||||
bom_dict[d.bom_no] = bom_dict.get(d.bom_no, 0) + flt(d.planned_qty)
|
||||
elif not d.is_pro_created:
|
||||
item_dict[d.item_code] = [
|
||||
(flt(item_dict.get(d.item_code, [0])[0]) + flt(d.planned_qty)),
|
||||
d.bom_no, d.description, d.stock_uom]
|
||||
|
||||
if action == 'raise_pro_order':
|
||||
for d in item_dict:
|
||||
pp_items.append({
|
||||
'production_item' : d,
|
||||
'qty' : item_dict[d][0],
|
||||
'bom_no' : item_dict[d][1],
|
||||
'description' : item_dict[d][2],
|
||||
'stock_uom' : item_dict[d][3],
|
||||
'consider_sa_items' : self.doc.use_multi_level_bom == "Yes" and "No" or "Yes"
|
||||
})
|
||||
|
||||
return action == 'download_rm' and bom_dict or pp_items
|
||||
return item_list
|
||||
@@ -4,7 +4,7 @@
|
||||
"docstatus": 0,
|
||||
"creation": "2012-07-03 13:30:03",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2012-11-29 17:52:20"
|
||||
"modified": "2012-11-30 14:08:55"
|
||||
},
|
||||
{
|
||||
"read_only": 1,
|
||||
@@ -159,15 +159,14 @@
|
||||
"options": "clear_item_table"
|
||||
},
|
||||
{
|
||||
"description": "If selected as \"No\", all sub-assembly items will be treated as a raw material. Otherwise, BOM for sub-assembly items will be considered for raw materials.",
|
||||
"default": "Yes",
|
||||
"description": "If checked, BOM for sub-assembly items will be considered for raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
||||
"default": "1",
|
||||
"colour": "White:FFF",
|
||||
"doctype": "DocField",
|
||||
"label": "Use multi-level BOM",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"reqd": 1,
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Select",
|
||||
"options": "No\nYes"
|
||||
"fieldtype": "Check"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
|
||||
Reference in New Issue
Block a user