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 # check total debit / credit
# Due to old wrong entries (total debit != total credit) some voucher could be cancelled # 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)) msgprint("Debit and Credit not equal for this voucher: Diff (Debit) is %s" % (self.td-self.tc))
raise Exception 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_module': 'patches.november_2012',
'patch_file': 'leave_application_cleanup', '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 # 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""" """Create production order. Called from Production Planning Tool"""
default_values = { default_values = {
@ -82,15 +82,20 @@ class DocType:
'wip_warehouse' : '', 'wip_warehouse' : '',
'fg_warehouse' : '', 'fg_warehouse' : '',
'status' : 'Draft', 'status' : 'Draft',
'company' : company, 'fiscal_year' : get_defaults()['fiscal_year']
'fiscal_year' : get_defaults()['fiscal_year']
} }
pro_list = [] 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') pro_doc = Document('Production Order')
for key in d.keys(): pro_doc.production_item = item_so[0]
pro_doc.fields[key] = d[key] 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: for key in default_values:
pro_doc.fields[key] = default_values[key] pro_doc.fields[key] = default_values[key]
@ -100,7 +105,30 @@ class DocType:
return pro_list 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): def update_bom(self, bom_no):
main_bom_list = self.traverse_bom_tree(bom_no, 1) main_bom_list = self.traverse_bom_tree(bom_no, 1)
main_bom_list.reverse() main_bom_list.reverse()
@ -113,4 +141,4 @@ class DocType:
bom_obj.update_flat_bom_engine() bom_obj.update_flat_bom_engine()
bom_obj.doc.docstatus = 1 bom_obj.doc.docstatus = 1
bom_obj.doc.save() 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) { cur_frm.cscript.onload = function(doc, dt, dn) {
if (!doc.posting_date) doc.transaction_date = dateutil.obj_to_str(new Date()); if (!doc.posting_date) doc.transaction_date = dateutil.obj_to_str(new Date());
if (!doc.status) doc.status = 'Draft'; if (!doc.status) doc.status = 'Draft';
cfn_set_fields(doc, dt, dn); 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 ========================================== // ================================== Refresh ==========================================
@ -48,15 +40,10 @@ var cfn_set_fields = function(doc, dt, dn) {
} }
} }
// ==================================================================================================
cur_frm.cscript.production_item = 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); get_server_fields('get_item_detail',doc.production_item,'',doc,dt,dn,1);
} }
// Stop PRODUCTION ORDER
//
cur_frm.cscript['Stop Production Order'] = function() { cur_frm.cscript['Stop Production Order'] = function() {
var doc = cur_frm.doc; var doc = cur_frm.doc;
var check = confirm("Do you really want to stop production order: " + doc.name); 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() { cur_frm.cscript['Unstop Production Order'] = function() {
var doc = cur_frm.doc; var doc = cur_frm.doc;
var check = confirm("Do really want to unstop production order: " + doc.name); 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); loaddoc('Stock Entry', se.name);
} }
// ==================================================================================================
cur_frm.fields_dict['production_item'].get_query = function(doc) { 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'; 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. msgprint("""Incorrect BOM: %s entered.
May be BOM not exists or inactive or not submitted May be BOM not exists or inactive or not submitted
or for some other item.""" % cstr(self.doc.bom_no), raise_exception=1) 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): def stop_unstop(self, status):

View File

@ -1,358 +1,324 @@
# DocType, Production Order
[ [
{
# These values are common in all dictionaries "owner": "Administrator",
{ "docstatus": 0,
'creation': '2012-05-15 12:14:48', "creation": "2012-07-03 13:30:03",
'docstatus': 0, "modified_by": "Administrator",
'modified': '2012-05-28 19:03:56', "modified": "2012-11-30 14:28:03"
'modified_by': u'Administrator', },
'owner': u'Administrator' {
}, "is_submittable": 1,
"in_create": 0,
# These values are common for all DocType "default_print_format": "Standard",
{ "doctype": "DocType",
'_last_update': u'1325837006', "module": "Production",
'colour': u'White:FFF', "name": "__common__"
'default_print_format': u'Standard', },
'doctype': 'DocType', {
'in_create': 0, "name": "__common__",
'is_submittable': 1, "parent": "Production Order",
'module': u'Production', "doctype": "DocField",
'name': '__common__', "parenttype": "DocType",
'section_style': u'Tabbed', "parentfield": "fields"
'server_code_error': u' ', },
'show_in_menu': 0, {
'version': 1 "name": "__common__",
}, "parent": "Production Order",
"read": 1,
# These values are common for all DocField "doctype": "DocPerm",
{ "parenttype": "DocType",
'doctype': u'DocField', "parentfield": "permissions"
'name': '__common__', },
'parent': u'Production Order', {
'parentfield': u'fields', "name": "Production Order",
'parenttype': u'DocType' "doctype": "DocType"
}, },
{
# These values are common for all DocPerm "doctype": "DocField",
{ "width": "50%",
'doctype': u'DocPerm', "fieldname": "column_break0",
'name': '__common__', "fieldtype": "Column Break",
'parent': u'Production Order', "permlevel": 0
'parentfield': u'permissions', },
'parenttype': u'DocType', {
'read': 1 "description": "Item for which this Production Order is raised.",
}, "oldfieldtype": "Link",
"colour": "White:FFF",
# DocType, Production Order "doctype": "DocField",
{ "label": "Production Item",
'doctype': 'DocType', "oldfieldname": "production_item",
'name': u'Production Order' "permlevel": 0,
}, "trigger": "Client",
"fieldname": "production_item",
# DocPerm "fieldtype": "Link",
{ "reqd": 1,
'amend': 1, "in_filter": 1,
'cancel': 1, "options": "Item"
'create': 1, },
'doctype': u'DocPerm', {
'permlevel': 0, "description": "Bill of Material which was considered for manufacturing the production item.",
'role': u'System Manager', "oldfieldtype": "Link",
'submit': 1, "colour": "White:FFF",
'write': 1 "doctype": "DocField",
}, "label": "BOM No",
"oldfieldname": "bom_no",
# DocPerm "permlevel": 0,
{ "trigger": "Client",
'doctype': u'DocPerm', "fieldname": "bom_no",
'permlevel': 1, "fieldtype": "Link",
'role': u'All' "reqd": 1,
}, "options": "BOM"
},
# DocPerm {
{ "description": "Quantity of item for which Production Order is raised.",
'amend': 1, "oldfieldtype": "Currency",
'cancel': 1, "colour": "White:FFF",
'create': 1, "doctype": "DocField",
'doctype': u'DocPerm', "label": "Qty",
'permlevel': 0, "oldfieldname": "qty",
'role': u'Production Manager', "fieldname": "qty",
'submit': 1, "fieldtype": "Currency",
'write': 1 "reqd": 1,
}, "permlevel": 0
},
# DocPerm {
{ "description": "The date on which current entry will get or has actually executed.",
'amend': 1, "oldfieldtype": "Date",
'cancel': 1, "colour": "White:FFF",
'create': 1, "doctype": "DocField",
'doctype': u'DocPerm', "label": "Posting Date",
'permlevel': 0, "oldfieldname": "posting_date",
'role': u'Production User', "fieldname": "posting_date",
'submit': 1, "fieldtype": "Date",
'write': 1 "reqd": 1,
}, "permlevel": 0
},
# DocField {
{ "oldfieldtype": "Column Break",
'doctype': u'DocField', "doctype": "DocField",
'fieldname': u'column_break0', "width": "50%",
'fieldtype': u'Column Break', "fieldname": "column_break1",
'permlevel': 0, "fieldtype": "Column Break",
'width': u'50%' "permlevel": 0
}, },
{
# DocField "description": "The warehouse for finished goods where stock of produced items will be updated.",
{ "oldfieldtype": "Link",
'colour': u'White:FFF', "colour": "White:FFF",
'description': u'Item for which this Production Order is raised.', "doctype": "DocField",
'doctype': u'DocField', "label": "FG Warehouse",
'fieldname': u'production_item', "oldfieldname": "fg_warehouse",
'fieldtype': u'Link', "permlevel": 0,
'in_filter': 1, "fieldname": "fg_warehouse",
'label': u'Production Item', "fieldtype": "Link",
'oldfieldname': u'production_item', "reqd": 1,
'oldfieldtype': u'Link', "in_filter": 1,
'options': u'Item', "options": "Warehouse"
'permlevel': 1, },
'reqd': 1, {
'trigger': u'Client' "description": "The work in progress warehouse where raw materials will be operated upon to create finished goods.",
}, "oldfieldtype": "Link",
"colour": "White:FFF",
# DocField "doctype": "DocField",
{ "label": "WIP Warehouse",
'doctype': u'DocField', "oldfieldname": "wip_warehouse",
'fieldname': u'description', "permlevel": 0,
'fieldtype': u'Text', "fieldname": "wip_warehouse",
'label': u'Description', "fieldtype": "Link",
'oldfieldname': u'description', "reqd": 1,
'oldfieldtype': u'Text', "in_filter": 1,
'permlevel': 0, "options": "Warehouse"
'width': u'300px' },
}, {
"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.",
# DocField "default": "1",
{ "oldfieldtype": "Select",
'doctype': u'DocField', "colour": "White:FFF",
'fieldname': u'stock_uom', "doctype": "DocField",
'fieldtype': u'Data', "label": "Use Multi-Level BOM",
'label': u'Stock UOM', "oldfieldname": "consider_sa_items",
'oldfieldname': u'stock_uom', "fieldname": "use_multi_level_bom",
'oldfieldtype': u'Data', "fieldtype": "Check",
'permlevel': 1 "reqd": 1,
}, "in_filter": 1,
"permlevel": 0
# DocField },
{ {
'colour': u'White:FFF', "description": "Updated after finished goods are transferred to FG Warehouse through Stock Entry",
'description': u'Bill of Material which was considered for manufacturing the production item.', "no_copy": 1,
'doctype': u'DocField', "oldfieldtype": "Currency",
'fieldname': u'bom_no', "colour": "White:FFF",
'fieldtype': u'Link', "doctype": "DocField",
'label': u'BOM No', "label": "Produced Qty",
'oldfieldname': u'bom_no', "oldfieldname": "produced_qty",
'oldfieldtype': u'Link', "fieldname": "produced_qty",
'options': u'BOM', "fieldtype": "Currency",
'permlevel': 1, "permlevel": 1
'reqd': 1, },
'trigger': u'Client' {
}, "doctype": "DocField",
"label": "More Info",
# DocField "fieldname": "more_info",
{ "fieldtype": "Section Break",
'colour': u'White:FFF', "permlevel": 0
'description': u'Quantity of item for which Production Order is raised.', },
'doctype': u'DocField', {
'fieldname': u'qty', "doctype": "DocField",
'fieldtype': u'Currency', "width": "50%",
'label': u'Qty', "fieldname": "column_break2",
'oldfieldname': u'qty', "fieldtype": "Column Break",
'oldfieldtype': u'Currency', "permlevel": 0
'permlevel': 0, },
'reqd': 1 {
}, "no_copy": 1,
"oldfieldtype": "Select",
# DocField "doctype": "DocField",
{ "label": "Origin",
'colour': u'White:FFF', "oldfieldname": "origin",
'description': u'The warehouse for finished goods where stock of produced items will be updated.', "options": "Manual\nMRP",
'doctype': u'DocField', "fieldname": "origin",
'fieldname': u'fg_warehouse', "fieldtype": "Select",
'fieldtype': u'Link', "reqd": 1,
'in_filter': 1, "permlevel": 0,
'label': u'FG Warehouse', "in_filter": 1
'oldfieldname': u'fg_warehouse', },
'oldfieldtype': u'Link', {
'options': u'Warehouse', "no_copy": 1,
'permlevel': 0, "oldfieldtype": "Select",
'reqd': 1 "doctype": "DocField",
}, "label": "Status",
"oldfieldname": "status",
# DocField "permlevel": 1,
{ "fieldname": "status",
'colour': u'White:FFF', "fieldtype": "Select",
'description': u'The work in progress warehouse where raw materials will be operated upon to create finished goods.', "search_index": 1,
'doctype': u'DocField', "reqd": 1,
'fieldname': u'wip_warehouse', "options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled",
'fieldtype': u'Link', "in_filter": 1
'in_filter': 1, },
'label': u'WIP Warehouse', {
'oldfieldname': u'wip_warehouse', "doctype": "DocField",
'oldfieldtype': u'Link', "label": "Sales Order",
'options': u'Warehouse', "options": "Sales Order",
'permlevel': 0, "fieldname": "sales_order",
'reqd': 1 "fieldtype": "Link",
}, "permlevel": 0
},
# DocField {
{ "description": "Select name of the project if Production Order need to be created against any project",
'doctype': u'DocField', "oldfieldtype": "Link",
'fieldname': u'amended_from', "label": "Project Name",
'fieldtype': u'Data', "oldfieldname": "project_name",
'label': u'Amended From', "trigger": "Client",
'no_copy': 1, "fieldname": "project_name",
'oldfieldname': u'amended_from', "fieldtype": "Link",
'oldfieldtype': u'Data', "doctype": "DocField",
'permlevel': 1 "options": "Project",
}, "permlevel": 0,
"in_filter": 1
# DocField },
{ {
'doctype': u'DocField', "oldfieldtype": "Link",
'fieldname': u'amendment_date', "doctype": "DocField",
'fieldtype': u'Date', "label": "Company",
'label': u'Amendment Date', "oldfieldname": "company",
'no_copy': 1, "options": "Company",
'oldfieldname': u'amendment_date', "fieldname": "company",
'oldfieldtype': u'Date', "fieldtype": "Link",
'permlevel': 1 "reqd": 1,
}, "permlevel": 0
},
# DocField {
{ "oldfieldtype": "Select",
'doctype': u'DocField', "doctype": "DocField",
'fieldname': u'column_break1', "label": "Fiscal Year",
'fieldtype': u'Column Break', "oldfieldname": "fiscal_year",
'oldfieldtype': u'Column Break', "options": "link:Fiscal Year",
'permlevel': 0, "fieldname": "fiscal_year",
'width': u'50%' "fieldtype": "Select",
}, "reqd": 1,
"permlevel": 0,
# DocField "in_filter": 1
{ },
'colour': u'White:FFF', {
'description': u'The date on which current entry will get or has actually executed.', "no_copy": 1,
'doctype': u'DocField', "oldfieldtype": "Data",
'fieldname': u'posting_date', "doctype": "DocField",
'fieldtype': u'Date', "label": "Amended From",
'label': u'Posting Date', "oldfieldname": "amended_from",
'oldfieldname': u'posting_date', "fieldname": "amended_from",
'oldfieldtype': u'Date', "fieldtype": "Data",
'permlevel': 0, "permlevel": 1
'reqd': 1 },
}, {
"no_copy": 1,
# DocField "oldfieldtype": "Date",
{ "doctype": "DocField",
'colour': u'White:FFF', "label": "Amendment Date",
'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.', "oldfieldname": "amendment_date",
'doctype': u'DocField', "fieldname": "amendment_date",
'fieldname': u'consider_sa_items', "fieldtype": "Date",
'fieldtype': u'Select', "permlevel": 1
'in_filter': 1, },
'label': u'Consider SA Items as raw material', {
'oldfieldname': u'consider_sa_items', "doctype": "DocField",
'oldfieldtype': u'Select', "width": "50%",
'options': u'\nYes\nNo', "fieldname": "column_break3",
'permlevel': 1, "fieldtype": "Column Break",
'reqd': 1 "permlevel": 0
}, },
{
# DocField "oldfieldtype": "Data",
{ "doctype": "DocField",
'description': u'Select name of the project if Production Order need to be created against any project', "label": "Stock UOM",
'doctype': u'DocField', "oldfieldname": "stock_uom",
'fieldname': u'project_name', "fieldname": "stock_uom",
'fieldtype': u'Link', "fieldtype": "Data",
'in_filter': 1, "permlevel": 1
'label': u'Project Name', },
'oldfieldname': u'project_name', {
'oldfieldtype': u'Link', "oldfieldtype": "Text",
'options': u'Project', "doctype": "DocField",
'permlevel': 0, "label": "Production Item Description",
'trigger': u'Client' "oldfieldname": "description",
}, "width": "300px",
"fieldname": "description",
# DocField "fieldtype": "Text",
{ "permlevel": 0
'doctype': u'DocField', },
'fieldname': u'origin', {
'fieldtype': u'Select', "amend": 1,
'in_filter': 1, "create": 1,
'label': u'Origin', "doctype": "DocPerm",
'no_copy': 1, "submit": 1,
'oldfieldname': u'origin', "write": 1,
'oldfieldtype': u'Select', "role": "System Manager",
'options': u'Manual\nMRP', "cancel": 1,
'permlevel': 1, "permlevel": 0
'reqd': 1 },
}, {
"doctype": "DocPerm",
# DocField "role": "All",
{ "permlevel": 1
'doctype': u'DocField', },
'fieldname': u'status', {
'fieldtype': u'Select', "amend": 1,
'in_filter': 1, "create": 1,
'label': u'Status', "doctype": "DocPerm",
'no_copy': 1, "submit": 1,
'oldfieldname': u'status', "write": 1,
'oldfieldtype': u'Select', "role": "Production Manager",
'options': u'\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled', "cancel": 1,
'permlevel': 1, "permlevel": 0
'reqd': 1, },
'search_index': 1 {
}, "amend": 1,
"create": 1,
# DocField "doctype": "DocPerm",
{ "submit": 1,
'colour': u'White:FFF', "write": 1,
'description': u'Updated after finished goods are transferred to FG Warehouse through Stock Entry', "role": "Production User",
'doctype': u'DocField', "cancel": 1,
'fieldname': u'produced_qty', "permlevel": 0
'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
}
] ]

View File

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

View File

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

View File

@ -14,11 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
cur_frm.cscript.item_code = function(doc,cdt,cdn) { cur_frm.cscript.onload = function(doc, cdt, cdn) {
var d = locals[cdt][cdn]; doc.company = sys_defaults.company;
if (d.item_code) { refresh_field("company");
get_server_fields('get_item_details', d.item_code, 'pp_details', doc, cdt, cdn, 1);
}
} }
cur_frm.cscript.sales_order = function(doc,cdt,cdn) { 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.item_code = function(doc,cdt,cdn) {
cur_frm.cscript.download_raw_material = function(doc, cdt, cdn) { var d = locals[cdt][cdn];
var callback = function(r, rt){ if (d.item_code) {
if (r.message) get_server_fields('get_item_details', d.item_code, 'pp_details', doc, cdt, cdn, 1);
$c_obj_csv(make_doclist(cdt, cdn), 'download_raw_materials', '', '');
} }
$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) { 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) { cur_frm.fields_dict['pp_details'].grid.get_field('bom_no').get_query = function(doc) {
var d = locals[this.doctype][this.docname]; 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'; 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; 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 from webnotes import msgprint, errprint
sql = webnotes.conn.sql sql = webnotes.conn.sql
# -----------------------------------------------------------------------------------------
class DocType: class DocType:
def __init__(self, doc, doclist=[]): def __init__(self, doc, doclist=[]):
self.doc = doc self.doc = doc
self.doclist = doclist self.doclist = doclist
self.item_dict = {} 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): def get_item_details(self, item_code):
""" Pull other item details from item master""" """ Pull other item details from item master"""
item = sql("""select description, stock_uom, default_bom from `tabItem` where name = %s item = sql("""select description, stock_uom, default_bom
and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())""", item_code, as_dict =1 ) from `tabItem` where name = %s""", item_code, as_dict =1)
ret = { ret = {
'description' : item and item[0]['description'], 'description' : item and item[0]['description'],
'stock_uom' : item and item[0]['stock_uom'], 'stock_uom' : item and item[0]['stock_uom'],
'bom_no' : item and item[0]['default_bom'] 'bom_no' : item and item[0]['default_bom']
} }
return ret 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): def clear_so_table(self):
""" Clears sales order table"""
self.doclist = self.doc.clear_table(self.doclist, 'pp_so_details') self.doclist = self.doc.clear_table(self.doclist, 'pp_so_details')
def clear_item_table(self): def clear_item_table(self):
""" Clears item table"""
self.doclist = self.doc.clear_table(self.doclist, 'pp_details') 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): def validate_company(self):
if not self.doc.company: if not self.doc.company:
msgprint("Please enter Company", raise_exception=1) msgprint("Please enter Company", raise_exception=1)
def get_open_sales_orders(self):
""" Pull sales orders which are pending to deliver based on criteria selected"""
def get_filter_condition(self): so_filter = item_filter = ""
self.validate_company()
cond = ''
if self.doc.from_date: 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: 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: if self.doc.customer:
cond += ' and t1.customer = "' + self.doc.customer + '"' so_filter += ' and so.customer = "' + self.doc.customer + '"'
if self.doc.fg_item: if self.doc.fg_item:
cond += ' and t3.item_code = "' + self.doc.fg_item + '"' item_filter += ' and item.name = "' + self.doc.fg_item + '"'
return cond 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): def add_so_in_table(self, open_so):
""" Add sales orders in the table""" """ Add sales orders in the table"""
so_list = [] so_list = [d.sales_order for d in getlist(self.doclist, 'pp_so_details')]
for d in getlist(self.doclist, 'pp_so_details'):
so_list.append(d.sales_order)
for r in open_so: for r in open_so:
if cstr(r['name']) not in so_list: 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 = r['name']
pp_so.sales_order_date = cstr(r['transaction_date']) pp_so.sales_order_date = cstr(r['transaction_date'])
pp_so.customer = cstr(r['customer']) pp_so.customer = cstr(r['customer'])
pp_so.grand_total = flt(r['grand_total']) pp_so.grand_total = flt(r['grand_total'])
def get_items_from_so(self): def get_items_from_so(self):
""" Pull items from Sales Order, only proction item """ Pull items from Sales Order, only proction item
and subcontracted item will be pulled from Packing item and subcontracted item will be pulled from Packing item
and add items in the table and add items in the table
""" """
so = self.get_included_so() items = self.get_items()
items = self.get_packing_items(so)
self.add_items(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): return items + dnpi_items
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
def add_items(self, items):
self.clear_item_table()
def add_items(self, packing_items): for p in items:
for d in getlist(self.doclist, 'pp_details'): item_details = sql("""select description, stock_uom, default_bom
if d.sales_order: from tabItem where name=%s""", p['item_code'])
d.parent = ''
for p in packing_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 = addchild(self.doc, 'pp_details', 'Production Plan Item', 1, self.doclist)
pi.sales_order = p['name'] pi.sales_order = p['parent']
pi.parent_packing_item = p['parent_item']
pi.item_code = p['item_code'] pi.item_code = p['item_code']
pi.description = item_details and item_details[0][0] or '' pi.description = item_details and item_details[0][0] or ''
pi.stock_uom = item_details and item_details[0][1] 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']) pi.planned_qty = flt(p['pending_qty'])
def validate_data(self): def validate_data(self):
for d in getlist(self.doclist, 'pp_details'): for d in getlist(self.doclist, 'pp_details'):
if not d.pro_created: self.validate_bom_no(d)
self.validate_bom_no(d) if not flt(d.planned_qty):
msgprint("Please Enter Planned Qty for item: %s at row no: %s" %
if not flt(d.planned_qty): (d.item_code, d.idx), raise_exception=1)
msgprint("Please Enter Planned Qty for item: %s at row no: %s"% (d.item_code, d.idx), raise_exception=1)
return 'validated'
def validate_bom_no(self, d): def validate_bom_no(self, d):
if not d.bom_no: 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: else:
bom = sql("""select name from `tabBOM` where item = %s and docstatus = 1 bom = sql("""select name from `tabBOM` where name = %s and item = %s
and name = %s and ifnull(is_active, 'No') = 'Yes'""", (d.item_code, d.bom_no), as_dict = 1) and docstatus = 1 and ifnull(is_active, 'No') = 'Yes'""",
(d.bom_no, d.item_code), as_dict = 1)
if not bom: if not bom:
msgprint("""Incorrect BOM No: %s entered for item: %s at row no: %s 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): def download_raw_materials(self):
""" Create csv data for required raw material to produce finished goods""" """ 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) self.get_raw_materials(bom_dict)
return self.get_csv() return self.get_csv()
def get_raw_materials(self, bom_dict): def get_raw_materials(self, bom_dict):
""" Get raw materials considering sub-assembly items """ """ Get raw materials considering sub-assembly items """
for bom in bom_dict: 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, # Get all raw materials considering SA items as raw materials,
# so no childs of SA items # so no childs of SA items
fl_bom_items = sql(""" 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` from `tabBOM Item`
where parent = '%s' and docstatus < 2 where parent = '%s' and docstatus < 2
group by item_code group by item_code
""" % (flt(bom_dict[bom]), bom)) """ % (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) self.make_items_dict(fl_bom_items)
def make_items_dict(self, item_list): def make_items_dict(self, item_list):
for i in item_list: for i in item_list:
self.item_dict[i[0]] = [(flt(self.item_dict.get(i[0], [0])[0]) + flt(i[1])), i[2], i[3]] 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): 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: 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_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) item_qty= sql("""select warehouse, indented_qty, ordered_qty, actual_qty
i_qty, o_qty, a_qty = 0,0,0 from `tabBin` where item_code = %s""", d)
i_qty, o_qty, a_qty = 0, 0, 0
for w in item_qty: 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]) 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])]) item_list.append(['', '', '', '', w[0], flt(w[1]), flt(w[2]), flt(w[3])])
if item_qty: if item_qty:
item_list.append(['', '', '', '', 'Total', i_qty, o_qty, a_qty]) item_list.append(['', '', '', '', 'Total', i_qty, o_qty, a_qty])
return item_list 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

View File

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

View File

@ -337,9 +337,7 @@ class DocType(TransactionBase):
#update enquiry #update enquiry
self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent') self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent')
# Submit
# -------
def on_submit(self): def on_submit(self):
self.check_prev_docstatus() self.check_prev_docstatus()
self.update_stock_ledger(update_stock = 1) 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)) 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) 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) get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self)
#update prevdoc status
self.update_prevdoc_status('submit') self.update_prevdoc_status('submit')
# set SO status
set(self.doc, 'status', 'Submitted') set(self.doc, 'status', 'Submitted')
# ON CANCEL
# ===============================================================================================
def on_cancel(self): def on_cancel(self):
# Cannot cancel stopped SO # Cannot cancel stopped SO
if self.doc.status == 'Stopped': if self.doc.status == 'Stopped':
@ -366,13 +358,10 @@ class DocType(TransactionBase):
self.check_nextdoc_docstatus() self.check_nextdoc_docstatus()
self.update_stock_ledger(update_stock = -1) self.update_stock_ledger(update_stock = -1)
#update prevdoc status
self.update_prevdoc_status('cancel') self.update_prevdoc_status('cancel')
# ::::::::: SET SO STATUS ::::::::::
set(self.doc, 'status', 'Cancelled') set(self.doc, 'status', 'Cancelled')
# CHECK NEXT DOCSTATUS
# does not allow to cancel document if DN or RV made against it is SUBMITTED # does not allow to cancel document if DN or RV made against it is SUBMITTED
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
def check_nextdoc_docstatus(self): 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)) 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: 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) 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 # 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)) 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: 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) 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 #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) 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: 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) 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) 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: 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) 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): def check_modified_date(self):
mod_db = sql("select modified from `tabSales Order` where name = '%s'" % self.doc.name) 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 get all items from flat bom except
child items of sub-contracted and sub assembly items child items of sub-contracted and sub assembly items
and sub assembly items itself. and sub assembly items itself.
""" """
if consider_sa_items_as_rm == 'Yes': if use_multi_level_bom:
# 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:
# get all raw materials with sub assembly childs # get all raw materials with sub assembly childs
fl_bom_sa_child_item = sql(""" fl_bom_sa_child_item = sql("""
select select
@ -187,6 +175,17 @@ class DocType(TransactionBase):
group by item_code,stock_uom group by item_code,stock_uom
""" , (fg_qty, bom_no)) """ , (fg_qty, bom_no))
self.make_items_dict(fl_bom_sa_child_item) 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 # Update only qty remaining to be issued for production
if self.doc.process == 'Material Transfer': if self.doc.process == 'Material Transfer':
@ -214,12 +213,8 @@ class DocType(TransactionBase):
if self.doc.bom_no: if self.doc.bom_no:
if not self.doc.fg_completed_qty: if not self.doc.fg_completed_qty:
msgprint("Please enter FG Completed Qty", raise_exception=1) 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): def get_items(self):
if self.doc.purpose == 'Production Order': if self.doc.purpose == 'Production Order':
pro_obj = self.doc.production_order and get_obj('Production Order', self.doc.production_order) or '' 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 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) 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': elif self.doc.purpose == 'Other':
self.validate_bom_no() self.validate_bom_no()
bom_no = self.doc.bom_no bom_no = self.doc.bom_no
fg_qty = self.doc.fg_completed_qty 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) self.doclist = self.doc.clear_table(self.doclist, 'mtn_details', 1)
sw = (self.doc.process == 'Backflush') and cstr(pro_obj.doc.wip_warehouse) or '' sw = (self.doc.process == 'Backflush') and cstr(pro_obj.doc.wip_warehouse) or ''

View File

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