Merge branch 'master' of github.com:webnotes/erpnext

This commit is contained in:
Anand Doshi 2012-11-30 15:15:16 +05:30
commit 746e229026
15 changed files with 991 additions and 1211 deletions

View File

@ -192,7 +192,7 @@ class DocType:
# check total debit / credit
# Due to old wrong entries (total debit != total credit) some voucher could be cancelled
if abs(self.td - self.tc) > 0.01 and not cancel:
if abs(self.td - self.tc) > 0.004 and not cancel:
msgprint("Debit and Credit not equal for this voucher: Diff (Debit) is %s" % (self.td-self.tc))
raise Exception

View File

@ -0,0 +1,12 @@
def execute():
import webnotes
webnotes.reload_doc("production", "doctype", "production_order")
webnotes.reload_doc("stock", "doctype", "stock_entry")
webnotes.conn.sql("""update `tabProduction Order`
set use_multi_level_bom = if(consider_sa_items='Yes', 0, 1)""")
webnotes.conn.sql("""update `tabStock Entry`
set use_multi_level_bom = if(consider_sa_items_as_raw_materials='Yes', 0, 1)""")

View File

@ -697,4 +697,8 @@ patch_list = [
'patch_module': 'patches.november_2012',
'patch_file': 'leave_application_cleanup',
},
{
'patch_module': 'patches.november_2012',
'patch_file': 'production_order_patch',
},
]

View File

@ -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)

View File

@ -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';
}

View File

@ -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):

View File

@ -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
}
]

View File

@ -1,159 +1,109 @@
# DocType, Production Plan Item
[
# These values are common in all dictionaries
{
'creation': '2012-03-27 14:36:03',
'docstatus': 0,
'modified': '2012-03-27 14:36:03',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
# These values are common for all DocType
{
'autoname': u'PPID/.#####',
'colour': u'White:FFF',
'default_print_format': u'Standard',
'doctype': 'DocType',
'istable': 1,
'module': u'Production',
'name': '__common__',
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
'version': 27
},
# These values are common for all DocField
{
'doctype': u'DocField',
'name': '__common__',
'parent': u'Production Plan Item',
'parentfield': u'fields',
'parenttype': u'DocType'
},
# DocType, Production Plan Item
{
'doctype': 'DocType',
'name': u'Production Plan Item'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'sales_order',
'fieldtype': u'Data',
'label': u'Sales Order',
'oldfieldname': u'source_docname',
'oldfieldtype': u'Data',
'permlevel': 1
},
# DocField
{
'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'item_code',
'fieldtype': u'Link',
'label': u'Item Code',
'oldfieldname': u'item_code',
'oldfieldtype': u'Link',
'options': u'Item',
'permlevel': 0,
'reqd': 1,
'trigger': u'Client',
'width': u'150px'
},
# DocField
{
'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': 0,
'reqd': 1,
'width': u'100px'
},
# DocField
{
'default': u'0.00',
'doctype': u'DocField',
'fieldname': u'so_pending_qty',
'fieldtype': u'Currency',
'label': u'SO Pending Qty',
'oldfieldname': u'prevdoc_reqd_qty',
'oldfieldtype': u'Currency',
'permlevel': 1,
'reqd': 0,
'width': u'100px'
},
# DocField
{
'default': u'0.00',
'doctype': u'DocField',
'fieldname': u'planned_qty',
'fieldtype': u'Currency',
'label': u'Planned Qty',
'oldfieldname': u'planned_qty',
'oldfieldtype': u'Currency',
'permlevel': 0,
'reqd': 1,
'width': u'100px'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'stock_uom',
'fieldtype': u'Data',
'label': u'UOM',
'oldfieldname': u'stock_uom',
'oldfieldtype': u'Data',
'permlevel': 1,
'reqd': 1,
'width': u'80px'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'description',
'fieldtype': u'Text',
'label': u'Description',
'oldfieldname': u'description',
'oldfieldtype': u'Text',
'permlevel': 1,
'width': u'200px'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'parent_packing_item',
'fieldtype': u'Link',
'label': u'Parent Packing Item',
'oldfieldname': u'parent_item',
'oldfieldtype': u'Link',
'options': u'Item',
'permlevel': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'is_pro_created',
'fieldtype': u'Check',
'label': u'Is PRO Created',
'oldfieldname': u'pro_created',
'oldfieldtype': u'Check',
'permlevel': 1
}
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-07-03 13:30:04",
"modified_by": "Administrator",
"modified": "2012-11-29 19:02:38"
},
{
"istable": 1,
"autoname": "PPID/.#####",
"name": "__common__",
"default_print_format": "Standard",
"doctype": "DocType",
"module": "Production"
},
{
"name": "__common__",
"parent": "Production Plan Item",
"doctype": "DocField",
"parenttype": "DocType",
"parentfield": "fields"
},
{
"name": "Production Plan Item",
"doctype": "DocType"
},
{
"permlevel": 0,
"oldfieldtype": "Link",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Item Code",
"oldfieldname": "item_code",
"width": "150px",
"trigger": "Client",
"fieldname": "item_code",
"fieldtype": "Link",
"reqd": 1,
"options": "Item"
},
{
"oldfieldtype": "Link",
"doctype": "DocField",
"label": "BOM No",
"oldfieldname": "bom_no",
"width": "100px",
"options": "BOM",
"fieldname": "bom_no",
"fieldtype": "Link",
"reqd": 1,
"permlevel": 0
},
{
"default": "0.00",
"oldfieldtype": "Currency",
"doctype": "DocField",
"label": "Planned Qty",
"oldfieldname": "planned_qty",
"width": "100px",
"fieldname": "planned_qty",
"fieldtype": "Currency",
"reqd": 1,
"permlevel": 0
},
{
"oldfieldtype": "Data",
"doctype": "DocField",
"label": "Sales Order",
"oldfieldname": "source_docname",
"options": "Sales Order",
"fieldname": "sales_order",
"fieldtype": "Link",
"permlevel": 1
},
{
"default": "0.00",
"oldfieldtype": "Currency",
"doctype": "DocField",
"label": "SO Pending Qty",
"oldfieldname": "prevdoc_reqd_qty",
"width": "100px",
"fieldname": "so_pending_qty",
"fieldtype": "Currency",
"reqd": 0,
"permlevel": 1
},
{
"oldfieldtype": "Data",
"doctype": "DocField",
"label": "UOM",
"oldfieldname": "stock_uom",
"width": "80px",
"fieldname": "stock_uom",
"fieldtype": "Data",
"reqd": 1,
"permlevel": 1
},
{
"oldfieldtype": "Text",
"doctype": "DocField",
"label": "Description",
"oldfieldname": "description",
"width": "200px",
"fieldname": "description",
"fieldtype": "Text",
"permlevel": 1
}
]

View File

@ -1,124 +1,84 @@
# DocType, Production Plan Sales Order
[
# These values are common in all dictionaries
{
'creation': '2012-03-27 14:36:04',
'docstatus': 0,
'modified': '2012-03-27 14:36:04',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
# These values are common for all DocType
{
'autoname': u'PP/.SO/.#####',
'colour': u'White:FFF',
'default_print_format': u'Standard',
'doctype': 'DocType',
'istable': 1,
'module': u'Production',
'name': '__common__',
'section_style': u'Simple',
'server_code_error': u' ',
'show_in_menu': 0,
'version': 5
},
# These values are common for all DocField
{
'doctype': u'DocField',
'name': '__common__',
'parent': u'Production Plan Sales Order',
'parentfield': u'fields',
'parenttype': u'DocType'
},
# These values are common for all DocPerm
{
'doctype': u'DocPerm',
'name': '__common__',
'parent': u'Production Plan Sales Order',
'parentfield': u'permissions',
'parenttype': u'DocType',
'read': 1,
'role': u'System Manager'
},
# DocType, Production Plan Sales Order
{
'doctype': 'DocType',
'name': u'Production Plan Sales Order'
},
# DocPerm
{
'doctype': u'DocPerm',
'permlevel': 0,
'write': 1
},
# DocPerm
{
'doctype': u'DocPerm',
'permlevel': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'sales_order',
'fieldtype': u'Link',
'label': u'Sales Order',
'oldfieldname': u'prevdoc_docname',
'oldfieldtype': u'Data',
'options': u'Sales Order',
'permlevel': 0,
'width': u'150px'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'sales_order_date',
'fieldtype': u'Date',
'label': u'Sales Order Date',
'oldfieldname': u'document_date',
'oldfieldtype': u'Date',
'permlevel': 1,
'width': u'100px'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'customer',
'fieldtype': u'Link',
'label': u'Customer',
'options': u'Customer',
'permlevel': 1,
'width': u'150px'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'grand_total',
'fieldtype': u'Currency',
'label': u'Grand Total',
'permlevel': 1,
'width': u'100px'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'include_in_plan',
'fieldtype': u'Check',
'label': u'Include In Plan',
'oldfieldname': u'include_in_plan',
'oldfieldtype': u'Check',
'permlevel': 0,
'width': u'100px'
}
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-07-03 13:30:04",
"modified_by": "Administrator",
"modified": "2012-11-29 17:49:15"
},
{
"istable": 1,
"autoname": "PP/.SO/.#####",
"name": "__common__",
"default_print_format": "Standard",
"doctype": "DocType",
"module": "Production"
},
{
"name": "__common__",
"parent": "Production Plan Sales Order",
"doctype": "DocField",
"parenttype": "DocType",
"parentfield": "fields"
},
{
"name": "__common__",
"parent": "Production Plan Sales Order",
"read": 1,
"doctype": "DocPerm",
"parenttype": "DocType",
"role": "System Manager",
"parentfield": "permissions"
},
{
"name": "Production Plan Sales Order",
"doctype": "DocType"
},
{
"oldfieldtype": "Data",
"doctype": "DocField",
"label": "Sales Order",
"oldfieldname": "prevdoc_docname",
"width": "150px",
"options": "Sales Order",
"fieldname": "sales_order",
"fieldtype": "Link",
"permlevel": 0
},
{
"oldfieldtype": "Date",
"doctype": "DocField",
"label": "SO Date",
"oldfieldname": "document_date",
"width": "120px",
"fieldname": "sales_order_date",
"fieldtype": "Date",
"permlevel": 1
},
{
"doctype": "DocField",
"label": "Customer",
"width": "150px",
"options": "Customer",
"fieldname": "customer",
"fieldtype": "Link",
"permlevel": 1
},
{
"doctype": "DocField",
"label": "Grand Total",
"width": "120px",
"fieldname": "grand_total",
"fieldtype": "Currency",
"permlevel": 1
},
{
"write": 1,
"doctype": "DocPerm",
"permlevel": 0
},
{
"doctype": "DocPerm",
"permlevel": 1
}
]

View File

@ -14,11 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
cur_frm.cscript.item_code = function(doc,cdt,cdn) {
var d = locals[cdt][cdn];
if (d.item_code) {
get_server_fields('get_item_details', d.item_code, 'pp_details', doc, cdt, cdn, 1);
}
cur_frm.cscript.onload = function(doc, cdt, cdn) {
doc.company = sys_defaults.company;
refresh_field("company");
}
cur_frm.cscript.sales_order = function(doc,cdt,cdn) {
@ -28,25 +26,35 @@ cur_frm.cscript.sales_order = function(doc,cdt,cdn) {
}
}
cur_frm.cscript.download_raw_material = function(doc, cdt, cdn) {
var callback = function(r, rt){
if (r.message)
$c_obj_csv(make_doclist(cdt, cdn), 'download_raw_materials', '', '');
cur_frm.cscript.item_code = function(doc,cdt,cdn) {
var d = locals[cdt][cdn];
if (d.item_code) {
get_server_fields('get_item_details', d.item_code, 'pp_details', doc, cdt, cdn, 1);
}
$c_obj(make_doclist(cdt, cdn), 'validate_data', '', callback)
}
//-------------------------------------------------------------------------------
//
cur_frm.cscript.download_materials_required = function(doc, cdt, cdn) {
$c_obj(make_doclist(cdt, cdn), 'validate_data', '', function(r, rt) {
if (!r['exc'])
$c_obj_csv(make_doclist(cdt, cdn), 'download_raw_materials', '', '');
});
}
cur_frm.fields_dict['pp_details'].grid.get_field('item_code').get_query = function(doc) {
return 'SELECT DISTINCT `tabItem`.`name`,`tabItem`.`item_name` FROM `tabItem` WHERE (IFNULL(`tabItem`.`end_of_life`,"") = "" OR `tabItem`.`end_of_life`="0000-00-00" OR `tabItem`.`end_of_life` > NOW()) AND `tabItem`.is_pro_applicable = "Yes" AND tabItem.%(key)s like "%s" ORDER BY `tabItem`.`name` LIMIT 50';
return 'SELECT DISTINCT `tabItem`.`name`,`tabItem`.`item_name` \
FROM `tabItem` WHERE `tabItem`.is_pro_applicable = "Yes" \
AND (IFNULL(`tabItem`.`end_of_life`,"") = "" \
OR `tabItem`.`end_of_life`="0000-00-00" OR `tabItem`.`end_of_life` > NOW()) \
AND tabItem.%(key)s like "%s" \
ORDER BY `tabItem`.`name` LIMIT 50';
}
cur_frm.fields_dict['pp_details'].grid.get_field('bom_no').get_query = function(doc) {
var d = locals[this.doctype][this.docname];
return 'SELECT DISTINCT `tabBOM`.`name` FROM `tabBOM` WHERE `tabBOM`.`item` = "' + d.item_code + '" AND `tabBOM`.`is_active` = "Yes" AND `tabBOM`.docstatus = 1 AND `tabBOM`.`name` like "%s" ORDER BY `tabBOM`.`name` LIMIT 50';
var d = locals[this.doctype][this.docname];
return 'SELECT DISTINCT `tabBOM`.`name` \
FROM `tabBOM` WHERE `tabBOM`.`item` = "' + d.item_code +
'" AND `tabBOM`.`is_active` = "Yes" AND `tabBOM`.docstatus = 1 \
AND `tabBOM`.`name` like "%s" ORDER BY `tabBOM`.`name` LIMIT 50';
}
cur_frm.fields_dict.customer.get_query = erpnext.utils.customer_query;

View File

@ -23,151 +23,135 @@ from webnotes.model.code import get_obj
from webnotes import msgprint, errprint
sql = webnotes.conn.sql
# -----------------------------------------------------------------------------------------
class DocType:
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
self.item_dict = {}
def get_so_details(self, so):
"""Pull other details from so"""
so = sql("""select transaction_date, customer, 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]['grand_total']
}
return ret
def get_item_details(self, item_code):
""" Pull other item details from item master"""
item = sql("""select description, stock_uom, default_bom from `tabItem` where name = %s
and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())""", item_code, as_dict =1 )
item = sql("""select description, stock_uom, default_bom
from `tabItem` where name = %s""", item_code, as_dict =1)
ret = {
'description' : item and item[0]['description'],
'stock_uom' : item and item[0]['stock_uom'],
'bom_no' : item and item[0]['default_bom']
}
return ret
def get_so_details(self, so):
"""Pull other details from so"""
so = sql("select transaction_date, customer, 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]['grand_total']
}
return ret
def clear_so_table(self):
""" Clears sales order table"""
self.doclist = self.doc.clear_table(self.doclist, 'pp_so_details')
def clear_item_table(self):
""" Clears item table"""
self.doclist = self.doc.clear_table(self.doclist, 'pp_details')
def get_open_sales_orders(self):
""" Pull sales orders which are pending to deliver based on criteria selected"""
cond = self.get_filter_condition()
open_so = sql("""
select
distinct t1.name, t1.transaction_date, t1.customer, t1.grand_total
from
`tabSales Order` t1, `tabSales Order Item` t2, `tabDelivery Note Packing Item` t3, tabItem t4
where
t1.name = t2.parent and t1.name = t3.parent and t3.parenttype = 'Sales Order' and t1.docstatus = 1 and t2.item_code = t3.parent_item
and t4.name = t3.item_code and t1.status != 'Stopped' and t1.company = '%s' and ifnull(t2.qty, 0) > ifnull(t2.delivered_qty, 0)
and (ifnull(t4.is_pro_applicable, 'No') = 'Yes' or ifnull(t4.is_sub_contracted_item, 'No') = 'Yes') %s
order by t1.name desc
"""% (self.doc.company, cond), as_dict = 1)
self.add_so_in_table(open_so)
def validate_company(self):
if not self.doc.company:
msgprint("Please enter Company", raise_exception=1)
def get_filter_condition(self):
self.validate_company()
cond = ''
def get_open_sales_orders(self):
""" Pull sales orders which are pending to deliver based on criteria selected"""
so_filter = item_filter = ""
if self.doc.from_date:
cond += ' and t1.transaction_date >= "' + self.doc.from_date + '"'
so_filter += ' and so.transaction_date >= "' + self.doc.from_date + '"'
if self.doc.to_date:
cond += ' and t1.transaction_date <= "' + self.doc.to_date + '"'
so_filter += ' and so.transaction_date <= "' + self.doc.to_date + '"'
if self.doc.customer:
cond += ' and t1.customer = "' + self.doc.customer + '"'
so_filter += ' and so.customer = "' + self.doc.customer + '"'
if self.doc.fg_item:
cond += ' and t3.item_code = "' + self.doc.fg_item + '"'
return cond
item_filter += ' and item.name = "' + self.doc.fg_item + '"'
open_so = sql("""
select distinct so.name, so.transaction_date, so.customer, so.grand_total
from `tabSales Order` so, `tabSales Order Item` so_item
where so_item.parent = so.name
and so.docstatus = 1 and so.status != "Stopped"
and so.company = 'Web Notes Technologies Pvt Ltd'
and ifnull(so_item.qty, 0) > ifnull(so_item.delivered_qty, 0) %s
and (exists (select * from `tabItem` item where item.name=so_item.item_code
and (ifnull(item.is_pro_applicable, 'No') = 'Yes'
or ifnull(item.is_sub_contracted_item, 'No') = 'Yes') %s)
or exists (select * from `tabDelivery Note Packing Item` dnpi
where dnpi.parent = so.name and dnpi.parent_item = so_item.item_code
and exists (select * from `tabItem` item where item.name=dnpi.item_code
and (ifnull(item.is_pro_applicable, 'No') = 'Yes'
or ifnull(item.is_sub_contracted_item, 'No') = 'Yes') %s)))
""" % (so_filter, item_filter, item_filter), as_dict=1)
self.add_so_in_table(open_so)
def add_so_in_table(self, open_so):
""" Add sales orders in the table"""
so_list = []
for d in getlist(self.doclist, 'pp_so_details'):
so_list.append(d.sales_order)
so_list = [d.sales_order for d in getlist(self.doclist, 'pp_so_details')]
for r in open_so:
if cstr(r['name']) not in so_list:
pp_so = addchild(self.doc, 'pp_so_details', 'Production Plan Sales Order', 1, self.doclist)
pp_so = addchild(self.doc, 'pp_so_details',
'Production Plan Sales Order', 1, self.doclist)
pp_so.sales_order = r['name']
pp_so.sales_order_date = cstr(r['transaction_date'])
pp_so.customer = cstr(r['customer'])
pp_so.grand_total = flt(r['grand_total'])
def get_items_from_so(self):
""" Pull items from Sales Order, only proction item
and subcontracted item will be pulled from Packing item
and add items in the table
"""
so = self.get_included_so()
items = self.get_packing_items(so)
items = self.get_items()
self.add_items(items)
def get_items(self):
so_list = filter(None, [d.sales_order for d in getlist(self.doclist, 'pp_so_details')])
if not so_list:
msgprint("Please enter sales order in the above table", raise_exception=1)
items = sql("""select distinct parent, item_code,
(qty - ifnull(delivered_qty, 0)) as pending_qty
from `tabSales Order Item` so_item
where parent in (%s) and docstatus = 1 and ifnull(qty, 0) > ifnull(delivered_qty, 0)
and exists (select * from `tabItem` item where item.name=so_item.item_code
and (ifnull(item.is_pro_applicable, 'No') = 'Yes'
or ifnull(item.is_sub_contracted_item, 'No') = 'Yes'))""" % \
(", ".join(["%s"] * len(so_list))), tuple(so_list), as_dict=1)
dnpi_items = sql("""select distinct dnpi.parent, dnpi.item_code,
(((so_item.qty - ifnull(so_item.delivered_qty, 0)) * dnpi.qty) / so_item.qty)
as pending_qty
from `tabSales Order Item` so_item, `tabDelivery Note Packing Item` dnpi
where so_item.parent = dnpi.parent and so_item.docstatus = 1
and dnpi.parent_item = so_item.item_code
and so_item.parent in (%s) and ifnull(so_item.qty, 0) > ifnull(so_item.delivered_qty, 0)
and exists (select * from `tabItem` item where item.name=dnpi.item_code
and (ifnull(item.is_pro_applicable, 'No') = 'Yes'
or ifnull(item.is_sub_contracted_item, 'No') = 'Yes'))""" % \
(", ".join(["%s"] * len(so_list))), tuple(so_list), as_dict=1)
def get_included_so(self):
so = "'" + "','".join([cstr(d.sales_order) for d in getlist(self.doclist, 'pp_so_details') if d.include_in_plan]) + "'"
return so
def get_packing_items(self, so):
packing_items = sql("""
select
t0.name, t2.parent_item, t2.item_code,
(t1.qty - ifnull(t1.delivered_qty,0)) * (ifnull(t2.qty,0) / ifnull(t1.qty,1)) as 'pending_qty'
from
`tabSales Order` t0, `tabSales Order Item` t1, `tabDelivery Note Packing Item` t2, `tabItem` t3
where
t0.name = t1.parent and t0.name = t2.parent and t1.name = t2.parent_detail_docname
and t0.name in (%s) and t0.docstatus = 1 and t1.qty > ifnull(t1.delivered_qty,0) and t3.name = t2.item_code
and (ifnull(t3.is_pro_applicable, 'No') = 'Yes' or ifnull(t3.is_sub_contracted_item, 'No') = 'Yes')
""" % so, as_dict=1)
return packing_items
return items + dnpi_items
def add_items(self, items):
self.clear_item_table()
def add_items(self, packing_items):
for d in getlist(self.doclist, 'pp_details'):
if d.sales_order:
d.parent = ''
for p in packing_items:
item_details = sql("select description, stock_uom, default_bom from tabItem where name=%s", p['item_code'])
for p in items:
item_details = sql("""select description, stock_uom, default_bom
from tabItem where name=%s""", p['item_code'])
pi = addchild(self.doc, 'pp_details', 'Production Plan Item', 1, self.doclist)
pi.sales_order = p['name']
pi.parent_packing_item = p['parent_item']
pi.sales_order = p['parent']
pi.item_code = p['item_code']
pi.description = item_details and item_details[0][0] or ''
pi.stock_uom = item_details and item_details[0][1] or ''
@ -176,129 +160,112 @@ class DocType:
pi.planned_qty = flt(p['pending_qty'])
def validate_data(self):
for d in getlist(self.doclist, 'pp_details'):
if not d.pro_created:
self.validate_bom_no(d)
if not flt(d.planned_qty):
msgprint("Please Enter Planned Qty for item: %s at row no: %s"% (d.item_code, d.idx), raise_exception=1)
return 'validated'
self.validate_bom_no(d)
if not flt(d.planned_qty):
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.consider_sa_items == 'Yes':
if self.doc.use_multi_level_bom:
# get all raw materials with sub assembly childs
fl_bom_items = sql("""
select
item_code,ifnull(sum(qty_consumed_per_unit),0)*%s as qty,
description, stock_uom
from
(
select distinct fb.name, fb.description, fb.item_code,
fb.qty_consumed_per_unit, fb.stock_uom
from `tabBOM Explosion Item` fb,`tabItem` it
where it.name = fb.item_code
and ifnull(it.is_pro_applicable, 'No') = 'No'
and ifnull(it.is_sub_contracted_item, 'No') = 'No'
and fb.docstatus<2 and fb.parent=%s
) 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
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:
# get all raw materials with sub assembly childs
fl_bom_items = sql("""
select
item_code,ifnull(sum(qty_consumed_per_unit),0)*%s as qty, description, stock_uom
from
(
select distinct fb.name, fb.description, fb.item_code, fb.qty_consumed_per_unit, fb.stock_uom
from `tabBOM Explosion Item` fb,`tabItem` it
where it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No'
and ifnull(it.is_sub_contracted_item, 'No') = 'No' and fb.docstatus<2 and fb.parent=%s
) a
group by item_code,stock_uom
""" , (flt(bom_dict[bom]), bom))
self.make_items_dict(fl_bom_items)
def make_items_dict(self, item_list):
for i in item_list:
self.item_dict[i[0]] = [(flt(self.item_dict.get(i[0], [0])[0]) + flt(i[1])), i[2], i[3]]
def get_csv(self):
item_list = [['Item Code', 'Description', 'Stock UOM', 'Required Qty', 'Warehouse', 'Quantity Requested for Purchase', 'Ordered Qty', 'Actual Qty']]
item_list = [['Item Code', 'Description', 'Stock UOM', 'Required Qty', 'Warehouse',
'Quantity Requested for Purchase', 'Ordered Qty', 'Actual Qty']]
for d in self.item_dict:
item_list.append([d, self.item_dict[d][1], self.item_dict[d][2], self.item_dict[d][0]]),
item_qty= sql("select warehouse, indented_qty, ordered_qty, actual_qty from `tabBin` where item_code = %s", d)
i_qty, o_qty, a_qty = 0,0,0
item_list.append([d, self.item_dict[d][1], self.item_dict[d][2], self.item_dict[d][0]])
item_qty= sql("""select warehouse, indented_qty, ordered_qty, actual_qty
from `tabBin` where item_code = %s""", d)
i_qty, o_qty, a_qty = 0, 0, 0
for w in item_qty:
i_qty, o_qty, a_qty = i_qty + flt(w[1]), o_qty + flt(w[2]), a_qty + flt(w[3])
item_list.append(['', '', '', '', w[0], flt(w[1]), flt(w[2]), flt(w[3])])
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 is 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.consider_sa_items
})
return action == 'download_rm' and bom_dict or pp_items
return item_list

View File

@ -1,318 +1,219 @@
# DocType, Production Planning Tool
[
# These values are common in all dictionaries
{
'creation': '2012-03-27 14:36:05',
'docstatus': 0,
'modified': '2012-03-27 14:36:05',
'modified_by': u'Administrator',
'owner': u'jai@webnotestech.com'
},
# These values are common for all DocType
{
'_last_update': u'1326188323',
'colour': u'White:FFF',
'default_print_format': u'Standard',
'doctype': 'DocType',
'in_create': 1,
'issingle': 1,
'module': u'Production',
'name': '__common__',
'read_only': 1,
'section_style': u'Tabbed',
'server_code_error': u' ',
'show_in_menu': 1,
'version': 106
},
# These values are common for all DocField
{
'doctype': u'DocField',
'name': '__common__',
'parent': u'Production Planning Tool',
'parentfield': u'fields',
'parenttype': u'DocType',
'permlevel': 0
},
# These values are common for all DocPerm
{
'create': 1,
'doctype': u'DocPerm',
'name': '__common__',
'parent': u'Production Planning Tool',
'parentfield': u'permissions',
'parenttype': u'DocType',
'permlevel': 0,
'read': 1,
'write': 1
},
# DocType, Production Planning Tool
{
'doctype': 'DocType',
'name': u'Production Planning Tool'
},
# DocPerm
{
'doctype': u'DocPerm',
'role': u'System Manager'
},
# DocPerm
{
'doctype': u'DocPerm',
'role': u'Production User'
},
# DocPerm
{
'doctype': u'DocPerm',
'role': u'Production Manager'
},
# DocField
{
'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'select_sales_orders',
'fieldtype': u'Section Break',
'label': u'Select Sales Orders'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'column_break0',
'fieldtype': u'Column Break',
'width': u'50%'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'from_date',
'fieldtype': u'Date',
'label': u'From Date'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'to_date',
'fieldtype': u'Date',
'label': u'To Date'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'fg_item',
'fieldtype': u'Link',
'label': u'FG Item',
'options': u'Item'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'column_break1',
'fieldtype': u'Column Break',
'width': u'50%'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'customer',
'fieldtype': u'Link',
'label': u'Customer',
'options': u'Customer'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'company',
'fieldtype': u'Link',
'label': u'Company',
'options': u'Company',
'reqd': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'section_break0',
'fieldtype': u'Section Break',
'options': u'Simple'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'column_break2',
'fieldtype': u'Column Break',
'width': u'50%'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'get_sales_orders',
'fieldtype': u'Button',
'label': u'Get Sales Orders',
'options': u'get_open_sales_orders'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'column_break3',
'fieldtype': u'Column Break',
'width': u'50%'
},
# DocField
{
'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'clear_so_table',
'fieldtype': u'Button',
'label': u'Clear SO Table',
'options': u'clear_so_table',
'trigger': u'Client'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'section_break1',
'fieldtype': u'Section Break',
'options': u'Simple'
},
# DocField
{
'description': u'Select Sales Orders from which you want to create Production Orders. You can get sales orders based on above criteria.',
'doctype': u'DocField',
'fieldname': u'pp_so_details',
'fieldtype': u'Table',
'label': u'Production Plan Sales Orders',
'options': u'Production Plan Sales Order'
},
# DocField
{
'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'items',
'fieldtype': u'Section Break',
'label': u'Items'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'get_items_from_so',
'fieldtype': u'Button',
'label': u'Get Items from SO',
'options': u'get_items_from_so'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'column_break4',
'fieldtype': u'Column Break',
'width': u'50%'
},
# DocField
{
'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'clear_item_table',
'fieldtype': u'Button',
'label': u'Clear Item Table',
'options': u'clear_item_table',
'trigger': u'Client'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'section_break2',
'fieldtype': u'Section Break',
'options': u'Simple'
},
# DocField
{
'description': u'Enter items and planned qty for which you want to raise production orders or download raw materials for analysis. You can pull items (which are pending to deliver) from SO as well by adding SO in plan.',
'doctype': u'DocField',
'fieldname': u'pp_details',
'fieldtype': u'Table',
'label': u'Production Plan Items',
'options': u'Production Plan Item'
},
# DocField
{
'colour': u'White:FFF',
'default': u'No',
'description': u'Select "Yes" if stock is maintained and tracked for sub assembly items.',
'doctype': u'DocField',
'fieldname': u'consider_sa_items',
'fieldtype': u'Select',
'label': u'Consider Sub Assemblies as Raw Material',
'options': u'No\nYes',
'reqd': 1
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'section_break3',
'fieldtype': u'Section Break',
'options': u'Simple'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'column_break5',
'fieldtype': u'Column Break',
'width': u'50%'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'raise_production_order',
'fieldtype': u'Button',
'label': u'Raise Production Order',
'options': u'raise_production_order'
},
# DocField
{
'doctype': u'DocField',
'fieldname': u'column_break6',
'fieldtype': u'Column Break',
'width': u'50%'
},
# DocField
{
'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'download_raw_material',
'fieldtype': u'Button',
'label': u'Download Raw Material',
'trigger': u'Client'
}
{
"owner": "jai@webnotestech.com",
"docstatus": 0,
"creation": "2012-07-03 13:30:03",
"modified_by": "Administrator",
"modified": "2012-11-30 14:08:55"
},
{
"read_only": 1,
"issingle": 1,
"in_create": 1,
"default_print_format": "Standard",
"doctype": "DocType",
"module": "Production",
"name": "__common__"
},
{
"name": "__common__",
"parent": "Production Planning Tool",
"doctype": "DocField",
"parenttype": "DocType",
"permlevel": 0,
"parentfield": "fields"
},
{
"name": "__common__",
"parent": "Production Planning Tool",
"read": 1,
"create": 1,
"doctype": "DocPerm",
"write": 1,
"parenttype": "DocType",
"permlevel": 0,
"parentfield": "permissions"
},
{
"name": "Production Planning Tool",
"doctype": "DocType"
},
{
"description": "Select Sales Orders from which you want to create Production Orders.",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Select Sales Orders",
"fieldname": "select_sales_orders",
"fieldtype": "Section Break"
},
{
"doctype": "DocField",
"width": "50%",
"fieldname": "column_break0",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"label": "Filter based on item",
"fieldname": "fg_item",
"fieldtype": "Link",
"options": "Item"
},
{
"doctype": "DocField",
"label": "Filter based on customer",
"fieldname": "customer",
"fieldtype": "Link",
"options": "Customer"
},
{
"doctype": "DocField",
"label": "Company",
"reqd": 1,
"fieldname": "company",
"fieldtype": "Link",
"options": "Company"
},
{
"doctype": "DocField",
"width": "50%",
"fieldname": "column_break1",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"label": "From Date",
"fieldname": "from_date",
"fieldtype": "Date"
},
{
"doctype": "DocField",
"label": "To Date",
"fieldname": "to_date",
"fieldtype": "Date"
},
{
"doctype": "DocField",
"fieldname": "section_break1",
"fieldtype": "Section Break",
"options": "Simple"
},
{
"description": "Pull sales orders (pending to deliver) based on the above criteria",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Get Sales Orders",
"fieldname": "get_sales_orders",
"fieldtype": "Button",
"options": "get_open_sales_orders"
},
{
"colour": "White:FFF",
"doctype": "DocField",
"label": "Production Plan Sales Orders",
"fieldname": "pp_so_details",
"fieldtype": "Table",
"options": "Production Plan Sales Order"
},
{
"colour": "White:FFF",
"doctype": "DocField",
"label": "Clear Table",
"trigger": "Client",
"fieldname": "clear_so_table",
"fieldtype": "Button",
"options": "clear_so_table"
},
{
"description": "Enter items and planned qty for which you want to raise production orders or download raw materials for analysis.",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Create Production Orders",
"fieldname": "create_production_orders",
"fieldtype": "Section Break"
},
{
"description": "Pull items from Sales Order mentioned in the above table.",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Get Items",
"fieldname": "get_items_from_so",
"fieldtype": "Button",
"options": "get_items_from_so"
},
{
"colour": "White:FFF",
"doctype": "DocField",
"label": "Production Plan Items",
"fieldname": "pp_details",
"fieldtype": "Table",
"options": "Production Plan Item"
},
{
"colour": "White:FFF",
"doctype": "DocField",
"label": "Clear Table",
"trigger": "Client",
"fieldname": "clear_item_table",
"fieldtype": "Button",
"options": "clear_item_table"
},
{
"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",
"reqd": 1,
"fieldname": "use_multi_level_bom",
"fieldtype": "Check"
},
{
"doctype": "DocField",
"fieldname": "section_break3",
"fieldtype": "Section Break",
"options": "Simple"
},
{
"doctype": "DocField",
"width": "50%",
"fieldname": "column_break5",
"fieldtype": "Column Break"
},
{
"description": "Separate production order will be created for each finished good item.",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Raise Production Order",
"fieldname": "raise_production_order",
"fieldtype": "Button",
"options": "raise_production_order"
},
{
"doctype": "DocField",
"width": "50%",
"fieldname": "column_break6",
"fieldtype": "Column Break"
},
{
"description": "Download a report containing all raw materials with their latest inventory status",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Download Materials Required",
"trigger": "Client",
"fieldname": "download_materials_required",
"fieldtype": "Button"
},
{
"role": "System Manager",
"doctype": "DocPerm"
},
{
"role": "Production User",
"doctype": "DocPerm"
},
{
"role": "Production Manager",
"doctype": "DocPerm"
}
]

View File

@ -337,9 +337,7 @@ class DocType(TransactionBase):
#update enquiry
self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent')
# Submit
# -------
def on_submit(self):
self.check_prev_docstatus()
self.update_stock_ledger(update_stock = 1)
@ -347,17 +345,11 @@ class DocType(TransactionBase):
update_customer = sql("update `tabCustomer` set last_sales_order = '%s', modified = '%s' where name = '%s'" %(self.doc.name, self.doc.modified, self.doc.customer))
get_obj('Sales Common').check_credit(self,self.doc.grand_total)
# Check for Approving Authority
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self)
#update prevdoc status
self.update_prevdoc_status('submit')
# set SO status
set(self.doc, 'status', 'Submitted')
# ON CANCEL
# ===============================================================================================
def on_cancel(self):
# Cannot cancel stopped SO
if self.doc.status == 'Stopped':
@ -366,13 +358,10 @@ class DocType(TransactionBase):
self.check_nextdoc_docstatus()
self.update_stock_ledger(update_stock = -1)
#update prevdoc status
self.update_prevdoc_status('cancel')
# ::::::::: SET SO STATUS ::::::::::
set(self.doc, 'status', 'Cancelled')
# CHECK NEXT DOCSTATUS
# does not allow to cancel document if DN or RV made against it is SUBMITTED
# ----------------------------------------------------------------------------
def check_nextdoc_docstatus(self):
@ -380,18 +369,28 @@ class DocType(TransactionBase):
submit_dn = sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Item` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name))
if submit_dn:
msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doc.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
# Checks Sales Invoice
submit_rv = sql("select t1.name from `tabSales Invoice` t1,`tabSales Invoice Item` t2 where t1.name = t2.parent and t2.sales_order = '%s' and t1.docstatus = 1" % (self.doc.name))
if submit_rv:
msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Sales Invoice : "+ cstr(submit_rv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
#check maintenance schedule
submit_ms = sql("select t1.name from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
if submit_ms:
msgprint("Maintenance Schedule : " + cstr(submit_ms[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Schedule : "+ cstr(submit_ms[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
# check maintenance visit
submit_mv = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
if submit_mv:
msgprint("Maintenance Visit : " + cstr(submit_mv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Visit : " + cstr(submit_mv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
# check production order
pro_order = sql("""select name from `tabProduction Order` where sales_order = %s and docstatus = 1""", self.doc.name)
if pro_order:
msgprint("""Production Order: %s exists against this sales order.
Please cancel production order first and then cancel this sales order""" %
pro_order[0][0], raise_exception=1)
def check_modified_date(self):
mod_db = sql("select modified from `tabSales Order` where name = '%s'" % self.doc.name)

View File

@ -154,25 +154,13 @@ class DocType(TransactionBase):
def get_raw_materials(self, bom_no, fg_qty, consider_sa_items_as_rm):
def get_raw_materials(self, bom_no, fg_qty, use_multi_level_bom):
"""
get all items from flat bom except
child items of sub-contracted and sub assembly items
and sub assembly items itself.
"""
if consider_sa_items_as_rm == 'Yes':
# Get all raw materials considering SA items as raw materials,
# so no childs of SA items
fl_bom_sa_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
""" % (fg_qty, bom_no))
self.make_items_dict(fl_bom_sa_items)
else:
if use_multi_level_bom:
# get all raw materials with sub assembly childs
fl_bom_sa_child_item = sql("""
select
@ -187,6 +175,17 @@ class DocType(TransactionBase):
group by item_code,stock_uom
""" , (fg_qty, bom_no))
self.make_items_dict(fl_bom_sa_child_item)
else:
# Get all raw materials considering multi level BOM,
# if multi level bom consider childs of Sub-Assembly items
fl_bom_sa_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
""" % (fg_qty, bom_no))
self.make_items_dict(fl_bom_sa_items)
# Update only qty remaining to be issued for production
if self.doc.process == 'Material Transfer':
@ -214,12 +213,8 @@ class DocType(TransactionBase):
if self.doc.bom_no:
if not self.doc.fg_completed_qty:
msgprint("Please enter FG Completed Qty", raise_exception=1)
if not self.doc.consider_sa_items_as_raw_materials:
msgprint("Please confirm whether you want to consider sub assembly item as raw materials", raise_exception=1)
# get items
#------------------
def get_items(self):
if self.doc.purpose == 'Production Order':
pro_obj = self.doc.production_order and get_obj('Production Order', self.doc.production_order) or ''
@ -227,14 +222,14 @@ class DocType(TransactionBase):
bom_no = pro_obj.doc.bom_no
fg_qty = (self.doc.process == 'Backflush') and flt(self.doc.fg_completed_qty) or flt(pro_obj.doc.qty)
consider_sa_items_as_rm = pro_obj.doc.consider_sa_items
use_multi_level_bom = pro_obj.doc.use_multi_level_bom
elif self.doc.purpose == 'Other':
self.validate_bom_no()
bom_no = self.doc.bom_no
fg_qty = self.doc.fg_completed_qty
consider_sa_items_as_rm = self.doc.consider_sa_items_as_raw_materials
use_multi_level_bom = self.doc.use_multi_level_bom
self.get_raw_materials(bom_no, fg_qty, consider_sa_items_as_rm)
self.get_raw_materials(bom_no, fg_qty, use_multi_level_bom)
self.doclist = self.doc.clear_table(self.doclist, 'mtn_details', 1)
sw = (self.doc.process == 'Backflush') and cstr(pro_obj.doc.wip_warehouse) or ''

View File

@ -2,9 +2,9 @@
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-11-02 17:16:56",
"creation": "2012-11-28 11:26:22",
"modified_by": "Administrator",
"modified": "2012-11-26 11:51:08"
"modified": "2012-11-30 14:10:02"
},
{
"is_submittable": 1,
@ -195,14 +195,13 @@
"permlevel": 0
},
{
"description": "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.",
"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.",
"depends_on": "eval:doc.purpose == 'Other'",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Consider SA Items as Raw Materials",
"options": "\nNo\nYes",
"fieldname": "consider_sa_items_as_raw_materials",
"fieldtype": "Select",
"label": "Use Multi-Level BOM",
"fieldname": "use_multi_level_bom",
"fieldtype": "Check",
"permlevel": 0
},
{