mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-19 04:59:18 +00:00
bom cleanup
This commit is contained in:
@@ -19,16 +19,16 @@ cur_frm.cscript.refresh = function(doc,dt,dn){
|
|||||||
cur_frm.toggle_enable("item", doc.__islocal);
|
cur_frm.toggle_enable("item", doc.__islocal);
|
||||||
|
|
||||||
if (!doc.__islocal && doc.docstatus==0) {
|
if (!doc.__islocal && doc.docstatus==0) {
|
||||||
cur_frm.set_intro("Submit the BOM to use it in production");
|
cur_frm.set_intro("Submit the BOM to use it for manufacturing or repacking.");
|
||||||
} else cur_frm.set_intro("");
|
} else cur_frm.set_intro("");
|
||||||
|
|
||||||
cur_frm.cscript.track_operations(doc);
|
cur_frm.cscript.with_operations(doc);
|
||||||
set_operation_no(doc);
|
set_operation_no(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.track_operations = function(doc) {
|
cur_frm.cscript.with_operations = function(doc) {
|
||||||
cur_frm.fields_dict["bom_materials"].grid.set_column_disp("operation_no", doc.track_operations);
|
cur_frm.fields_dict["bom_materials"].grid.set_column_disp("operation_no", doc.with_operations);
|
||||||
cur_frm.fields_dict["bom_materials"].grid.toggle_reqd("operation_no", doc.track_operations)
|
cur_frm.fields_dict["bom_materials"].grid.toggle_reqd("operation_no", doc.with_operations)
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.operation_no = function(doc, cdt, cdn) {
|
cur_frm.cscript.operation_no = function(doc, cdt, cdn) {
|
||||||
@@ -44,8 +44,14 @@ var set_operation_no = function(doc) {
|
|||||||
var op = op_table[i].operation_no;
|
var op = op_table[i].operation_no;
|
||||||
if (op && !inList(operations, op)) operations.push(op);
|
if (op && !inList(operations, op)) operations.push(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.fields_dict["bom_materials"].grid.get_field("operation_no")
|
cur_frm.fields_dict["bom_materials"].grid.get_field("operation_no")
|
||||||
.df.options = operations.join("\n");
|
.df.options = operations.join("\n");
|
||||||
|
|
||||||
|
$.each(getchildren("BOM Item", doc.name, "bom_materials"), function(i, v) {
|
||||||
|
if(!inList(operations, cstr(v.operation_no))) v.operation_no = null;
|
||||||
|
});
|
||||||
|
|
||||||
refresh_field("bom_materials");
|
refresh_field("bom_materials");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +61,7 @@ cur_frm.fields_dict["bom_operations"].grid.on_row_delete = function(cdt, cdn){
|
|||||||
|
|
||||||
cur_frm.cscript.item = function(doc, dt, dn) {
|
cur_frm.cscript.item = function(doc, dt, dn) {
|
||||||
if (doc.item) {
|
if (doc.item) {
|
||||||
get_server_fields('get_item_detail',doc.item,'',doc,dt,dn,1);
|
get_server_fields('get_item_details',doc.item,'',doc,dt,dn,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,17 +135,6 @@ cur_frm.cscript.rate = function(doc, cdt, cdn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.is_default = function(doc, cdt, cdn) {
|
|
||||||
if (doc.docstatus == 1)
|
|
||||||
$c_obj(make_doclist(cdt, cdn), 'manage_default_bom', '', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cur_frm.cscript.is_active = function(doc, dt, dn) {
|
|
||||||
if (!doc.__islocal)
|
|
||||||
$c_obj(make_doclist(dt, dn), 'manage_active_bom', '', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
var calculate_op_cost = function(doc, dt, dn) {
|
var calculate_op_cost = function(doc, dt, dn) {
|
||||||
var op = getchildren('BOM Operation', doc.name, 'bom_operations');
|
var op = getchildren('BOM Operation', doc.name, 'bom_operations');
|
||||||
total_op_cost = 0;
|
total_op_cost = 0;
|
||||||
@@ -196,10 +191,6 @@ cur_frm.fields_dict['bom_materials'].grid.get_field('item_code').get_query = fun
|
|||||||
|
|
||||||
cur_frm.fields_dict['bom_materials'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) {
|
cur_frm.fields_dict['bom_materials'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) {
|
||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
msgprint('SELECT DISTINCT `tabBOM`.`name`, `tabBOM`.`remarks` FROM `tabBOM` \
|
|
||||||
WHERE `tabBOM`.`item` = "' + d.item_code + '" AND `tabBOM`.`is_active` = 1 AND \
|
|
||||||
`tabBOM`.docstatus = 1 AND `tabBOM`.`name` like "%s" \
|
|
||||||
ORDER BY `tabBOM`.`name` LIMIT 50');
|
|
||||||
return 'SELECT DISTINCT `tabBOM`.`name`, `tabBOM`.`remarks` FROM `tabBOM` \
|
return 'SELECT DISTINCT `tabBOM`.`name`, `tabBOM`.`remarks` FROM `tabBOM` \
|
||||||
WHERE `tabBOM`.`item` = "' + d.item_code + '" AND `tabBOM`.`is_active` = 1 AND \
|
WHERE `tabBOM`.`item` = "' + d.item_code + '" AND `tabBOM`.`is_active` = 1 AND \
|
||||||
`tabBOM`.docstatus = 1 AND `tabBOM`.`name` like "%s" \
|
`tabBOM`.docstatus = 1 AND `tabBOM`.`name` like "%s" \
|
||||||
|
|||||||
@@ -38,24 +38,52 @@ class DocType:
|
|||||||
else:
|
else:
|
||||||
idx = 1
|
idx = 1
|
||||||
self.doc.name = 'BOM/' + self.doc.item + ('/%.3i' % idx)
|
self.doc.name = 'BOM/' + self.doc.item + ('/%.3i' % idx)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
self.clear_operations()
|
||||||
|
self.validate_main_item()
|
||||||
|
self.validate_operations()
|
||||||
|
self.validate_materials()
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
self.check_recursion()
|
||||||
|
self.update_cost_and_exploded_items()
|
||||||
|
|
||||||
|
def on_submit(self):
|
||||||
|
self.manage_default_bom()
|
||||||
|
|
||||||
|
def on_cancel(self):
|
||||||
|
# check if used in any other bom
|
||||||
|
par = sql("""select t1.parent from `tabBOM Item` t1, `tabBOM` t2
|
||||||
|
where t1.parent = t2.name and t1.bom_no = %s and t1.docstatus = 1
|
||||||
|
and t2.is_active = 1""", self.doc.name)
|
||||||
|
if par:
|
||||||
|
msgprint("""BOM can not be cancelled, as it is a child item \
|
||||||
|
in following active BOM %s""" % [d[0] for d in par], raise_exception=1)
|
||||||
|
|
||||||
|
webnotes.conn.set(self.doc, "is_active", 0)
|
||||||
|
webnotes.conn.set(self.doc, "is_default", 0)
|
||||||
|
self.manage_default_bom()
|
||||||
|
self.update_cost_and_exploded_items(calculate_cost=False)
|
||||||
|
|
||||||
|
def on_update_after_submit(self):
|
||||||
|
self.manage_default_bom()
|
||||||
|
self.validate_inactive_bom()
|
||||||
|
|
||||||
def get_item_det(self, item_code):
|
def get_item_det(self, item_code):
|
||||||
item = sql("""select name, is_asset_item, is_purchase_item, docstatus,
|
item = sql("""select name, is_asset_item, is_purchase_item, docstatus, description,
|
||||||
is_sub_contracted_item, stock_uom, default_bom,
|
is_sub_contracted_item, stock_uom, default_bom,
|
||||||
last_purchase_rate, standard_rate, is_manufactured_item
|
last_purchase_rate, standard_rate, is_manufactured_item
|
||||||
from `tabItem` where item_code = %s""", item_code, as_dict = 1)
|
from `tabItem` where item_code = %s""", item_code, as_dict = 1)
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
||||||
|
def get_item_details(self, item_code):
|
||||||
def get_item_detail(self, item_code):
|
|
||||||
return { 'uom' : webnotes.conn.get_value("Item", item_code, "stock_uom")}
|
return { 'uom' : webnotes.conn.get_value("Item", item_code, "stock_uom")}
|
||||||
|
|
||||||
def get_workstation_details(self,workstation):
|
def get_workstation_details(self,workstation):
|
||||||
return {'hour_rate': webnotes.conn.get_value("Workstation", workstation, "hour_rate")}
|
return {'hour_rate': webnotes.conn.get_value("Workstation", workstation, "hour_rate")}
|
||||||
|
|
||||||
|
|
||||||
def validate_rm_item(self, item):
|
def validate_rm_item(self, item):
|
||||||
if item[0]['name'] == self.doc.item:
|
if item[0]['name'] == self.doc.item:
|
||||||
msgprint("Item_code: %s in materials tab cannot be same as FG Item",
|
msgprint("Item_code: %s in materials tab cannot be same as FG Item",
|
||||||
@@ -67,7 +95,6 @@ class DocType:
|
|||||||
if not item or item[0]['docstatus'] == 2:
|
if not item or item[0]['docstatus'] == 2:
|
||||||
msgprint("Item %s does not exist in system" % item[0]['item_code'], raise_exception = 1)
|
msgprint("Item %s does not exist in system" % item[0]['item_code'], raise_exception = 1)
|
||||||
|
|
||||||
|
|
||||||
def get_bom_material_detail(self):
|
def get_bom_material_detail(self):
|
||||||
""" Get raw material details like uom, desc and rate"""
|
""" Get raw material details like uom, desc and rate"""
|
||||||
|
|
||||||
@@ -90,7 +117,6 @@ class DocType:
|
|||||||
}
|
}
|
||||||
return ret_item
|
return ret_item
|
||||||
|
|
||||||
|
|
||||||
def get_rm_rate(self, arg):
|
def get_rm_rate(self, arg):
|
||||||
""" Get raw material rate as per selected method, if bom exists takes bom cost """
|
""" Get raw material rate as per selected method, if bom exists takes bom cost """
|
||||||
|
|
||||||
@@ -128,26 +154,26 @@ class DocType:
|
|||||||
|
|
||||||
return rate and flt(sum(rate))/len(rate) or 0
|
return rate and flt(sum(rate))/len(rate) or 0
|
||||||
|
|
||||||
|
|
||||||
def manage_default_bom(self):
|
def manage_default_bom(self):
|
||||||
""" Uncheck others if current one is selected as default,
|
""" Uncheck others if current one is selected as default,
|
||||||
update default bom in item master
|
update default bom in item master
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.doc.is_default and self.doc.is_active:
|
if self.doc.is_default and self.doc.is_active:
|
||||||
sql("update `tabBOM` set is_default = 0 where name != %s and item=%s",
|
from webnotes.model.utils import set_default
|
||||||
(self.doc.name, self.doc.item))
|
|
||||||
|
set_default(self.doc, "item")
|
||||||
webnotes.conn.set_value("Item", self.doc.item, "default_bom", self.doc.name)
|
webnotes.conn.set_value("Item", self.doc.item, "default_bom", self.doc.name)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
sql("update `tabItem` set default_bom = '' where name = %s and default_bom = %s",
|
if not self.doc.is_active:
|
||||||
|
webnotes.conn.set(self.doc, "is_default", 0)
|
||||||
|
|
||||||
|
sql("update `tabItem` set default_bom = null where name = %s and default_bom = %s",
|
||||||
(self.doc.item, self.doc.name))
|
(self.doc.item, self.doc.name))
|
||||||
|
|
||||||
|
def clear_operations(self):
|
||||||
def validate(self):
|
if not self.doc.with_operations:
|
||||||
self.validate_main_item()
|
self.doclist = self.doc.clear_table(self.doclist, 'bom_operations')
|
||||||
self.validate_operations()
|
|
||||||
self.validate_materials()
|
|
||||||
|
|
||||||
def validate_main_item(self):
|
def validate_main_item(self):
|
||||||
""" Validate main FG item"""
|
""" Validate main FG item"""
|
||||||
@@ -161,7 +187,6 @@ class DocType:
|
|||||||
msgprint("""As Item: %s is not a manufactured / sub-contracted item, \
|
msgprint("""As Item: %s is not a manufactured / sub-contracted item, \
|
||||||
you can not make BOM for it""" % self.doc.item, raise_exception = 1)
|
you can not make BOM for it""" % self.doc.item, raise_exception = 1)
|
||||||
|
|
||||||
|
|
||||||
def validate_operations(self):
|
def validate_operations(self):
|
||||||
""" Check duplicate operation no"""
|
""" Check duplicate operation no"""
|
||||||
self.op = []
|
self.op = []
|
||||||
@@ -178,7 +203,7 @@ class DocType:
|
|||||||
check_list = []
|
check_list = []
|
||||||
for m in getlist(self.doclist, 'bom_materials'):
|
for m in getlist(self.doclist, 'bom_materials'):
|
||||||
# check if operation no not in op table
|
# check if operation no not in op table
|
||||||
if self.doc.track_operations and cstr(m.operation_no) not in self.op:
|
if self.doc.with_operations and cstr(m.operation_no) not in self.op:
|
||||||
msgprint("""Operation no: %s against item: %s at row no: %s \
|
msgprint("""Operation no: %s against item: %s at row no: %s \
|
||||||
is not present at Operations table""" %
|
is not present at Operations table""" %
|
||||||
(m.operation_no, m.item_code, m.idx), raise_exception = 1)
|
(m.operation_no, m.item_code, m.idx), raise_exception = 1)
|
||||||
@@ -203,18 +228,16 @@ class DocType:
|
|||||||
|
|
||||||
self.check_if_item_repeated(m.item_code, m.operation_no, check_list)
|
self.check_if_item_repeated(m.item_code, m.operation_no, check_list)
|
||||||
|
|
||||||
|
|
||||||
def validate_bom_no(self, item, bom_no, idx):
|
def validate_bom_no(self, item, bom_no, idx):
|
||||||
"""Validate BOM No of sub-contracted items"""
|
"""Validate BOM No of sub-contracted items"""
|
||||||
bom = sql("""select name from `tabBOM` where name = %s and item = %s
|
bom = sql("""select name from `tabBOM` where name = %s and item = %s
|
||||||
and is_active = 1 and docstatus < 2 """,
|
and is_active=1 and docstatus=1""",
|
||||||
(bom_no, item), as_dict =1)
|
(bom_no, item), as_dict =1)
|
||||||
if not bom:
|
if not bom:
|
||||||
msgprint("""Incorrect BOM No: %s against item: %s at row no: %s.
|
msgprint("""Incorrect BOM No: %s against item: %s at row no: %s.
|
||||||
It may be inactive or cancelled or for some other item.""" %
|
It may be inactive or cancelled or for some other item.""" %
|
||||||
(bom_no, item, idx), raise_exception = 1)
|
(bom_no, item, idx), raise_exception = 1)
|
||||||
|
|
||||||
|
|
||||||
def check_if_item_repeated(self, item, op, check_list):
|
def check_if_item_repeated(self, item, op, check_list):
|
||||||
if [cstr(item), cstr(op)] in check_list:
|
if [cstr(item), cstr(op)] in check_list:
|
||||||
msgprint("Item %s has been entered twice against same operation" %
|
msgprint("Item %s has been entered twice against same operation" %
|
||||||
@@ -222,11 +245,6 @@ class DocType:
|
|||||||
else:
|
else:
|
||||||
check_list.append([cstr(item), cstr(op)])
|
check_list.append([cstr(item), cstr(op)])
|
||||||
|
|
||||||
|
|
||||||
def on_update(self):
|
|
||||||
self.check_recursion()
|
|
||||||
self.update_cost_and_exploded_items()
|
|
||||||
|
|
||||||
def check_recursion(self):
|
def check_recursion(self):
|
||||||
""" Check whether recursion occurs in any bom"""
|
""" Check whether recursion occurs in any bom"""
|
||||||
|
|
||||||
@@ -243,7 +261,6 @@ class DocType:
|
|||||||
""" % (cstr(b), cstr(d[2]), self.doc.name), raise_exception = 1)
|
""" % (cstr(b), cstr(d[2]), self.doc.name), raise_exception = 1)
|
||||||
if b[0]:
|
if b[0]:
|
||||||
bom_list.append(b[0])
|
bom_list.append(b[0])
|
||||||
|
|
||||||
|
|
||||||
def update_cost_and_exploded_items(self, calculate_cost=True):
|
def update_cost_and_exploded_items(self, calculate_cost=True):
|
||||||
bom_list = self.traverse_tree()
|
bom_list = self.traverse_tree()
|
||||||
@@ -252,9 +269,10 @@ class DocType:
|
|||||||
bom_obj = get_obj("BOM", bom, with_children=1)
|
bom_obj = get_obj("BOM", bom, with_children=1)
|
||||||
if calculate_cost:
|
if calculate_cost:
|
||||||
bom_obj.calculate_cost()
|
bom_obj.calculate_cost()
|
||||||
bom_obj.update_flat_bom()
|
bom_obj.update_exploded_items()
|
||||||
|
if bom == self.doc.name:
|
||||||
|
self.doc, self.doclist = bom_obj.doc, bom_obj.doclist
|
||||||
|
|
||||||
|
|
||||||
def traverse_tree(self):
|
def traverse_tree(self):
|
||||||
def _get_childs(bom_no):
|
def _get_childs(bom_no):
|
||||||
return [cstr(d[0]) for d in webnotes.conn.sql("""select bom_no from `tabBOM Item`
|
return [cstr(d[0]) for d in webnotes.conn.sql("""select bom_no from `tabBOM Item`
|
||||||
@@ -268,7 +286,6 @@ class DocType:
|
|||||||
count += 1
|
count += 1
|
||||||
return bom_list
|
return bom_list
|
||||||
|
|
||||||
|
|
||||||
def calculate_cost(self):
|
def calculate_cost(self):
|
||||||
"""Calculate bom totals"""
|
"""Calculate bom totals"""
|
||||||
self.calculate_op_cost()
|
self.calculate_op_cost()
|
||||||
@@ -276,7 +293,6 @@ class DocType:
|
|||||||
self.doc.total_cost = self.doc.raw_material_cost + self.doc.operating_cost
|
self.doc.total_cost = self.doc.raw_material_cost + self.doc.operating_cost
|
||||||
self.doc.modified = now()
|
self.doc.modified = now()
|
||||||
self.doc.save()
|
self.doc.save()
|
||||||
|
|
||||||
|
|
||||||
def calculate_op_cost(self):
|
def calculate_op_cost(self):
|
||||||
"""Update workstation rate and calculates totals"""
|
"""Update workstation rate and calculates totals"""
|
||||||
@@ -288,7 +304,6 @@ class DocType:
|
|||||||
total_op_cost += flt(d.operating_cost)
|
total_op_cost += flt(d.operating_cost)
|
||||||
self.doc.operating_cost = total_op_cost
|
self.doc.operating_cost = total_op_cost
|
||||||
|
|
||||||
|
|
||||||
def calculate_rm_cost(self):
|
def calculate_rm_cost(self):
|
||||||
"""Fetch RM rate as per today's valuation rate and calculate totals"""
|
"""Fetch RM rate as per today's valuation rate and calculate totals"""
|
||||||
total_rm_cost = 0
|
total_rm_cost = 0
|
||||||
@@ -301,21 +316,19 @@ class DocType:
|
|||||||
total_rm_cost += d.amount
|
total_rm_cost += d.amount
|
||||||
self.doc.raw_material_cost = total_rm_cost
|
self.doc.raw_material_cost = total_rm_cost
|
||||||
|
|
||||||
|
def update_exploded_items(self):
|
||||||
def update_flat_bom(self):
|
|
||||||
""" Update Flat BOM, following will be correct data"""
|
""" Update Flat BOM, following will be correct data"""
|
||||||
self.get_flat_bom_items()
|
self.get_exploded_items()
|
||||||
self.add_to_flat_bom_detail()
|
self.add_exploded_items()
|
||||||
|
|
||||||
|
def get_exploded_items(self):
|
||||||
def get_flat_bom_items(self):
|
|
||||||
""" Get all raw materials including items from child bom"""
|
""" Get all raw materials including items from child bom"""
|
||||||
self.cur_flat_bom_items = []
|
self.cur_exploded_items = []
|
||||||
for d in getlist(self.doclist, 'bom_materials'):
|
for d in getlist(self.doclist, 'bom_materials'):
|
||||||
if d.bom_no:
|
if d.bom_no:
|
||||||
self.get_child_flat_bom_items(d.bom_no, d.qty)
|
self.get_child_exploded_items(d.bom_no, d.qty)
|
||||||
else:
|
else:
|
||||||
self.cur_flat_bom_items.append({
|
self.cur_exploded_items.append({
|
||||||
'item_code' : d.item_code,
|
'item_code' : d.item_code,
|
||||||
'description' : d.description,
|
'description' : d.description,
|
||||||
'stock_uom' : d.stock_uom,
|
'stock_uom' : d.stock_uom,
|
||||||
@@ -327,8 +340,7 @@ class DocType:
|
|||||||
'qty_consumed_per_unit' : flt(d.qty_consumed_per_unit)
|
'qty_consumed_per_unit' : flt(d.qty_consumed_per_unit)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def get_child_exploded_items(self, bom_no, qty):
|
||||||
def get_child_flat_bom_items(self, bom_no, qty):
|
|
||||||
""" Add all items from Flat BOM of child BOM"""
|
""" Add all items from Flat BOM of child BOM"""
|
||||||
|
|
||||||
child_fb_items = sql("""select item_code, description, stock_uom, qty, rate,
|
child_fb_items = sql("""select item_code, description, stock_uom, qty, rate,
|
||||||
@@ -336,7 +348,7 @@ class DocType:
|
|||||||
from `tabBOM Explosion Item` where parent = '%s' and docstatus = 1""" %
|
from `tabBOM Explosion Item` where parent = '%s' and docstatus = 1""" %
|
||||||
bom_no, as_dict = 1)
|
bom_no, as_dict = 1)
|
||||||
for d in child_fb_items:
|
for d in child_fb_items:
|
||||||
self.cur_flat_bom_items.append({
|
self.cur_exploded_items.append({
|
||||||
'item_code' : d['item_code'],
|
'item_code' : d['item_code'],
|
||||||
'description' : d['description'],
|
'description' : d['description'],
|
||||||
'stock_uom' : d['stock_uom'],
|
'stock_uom' : d['stock_uom'],
|
||||||
@@ -349,10 +361,10 @@ class DocType:
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
def add_to_flat_bom_detail(self):
|
def add_exploded_items(self):
|
||||||
"Add items to Flat BOM table"
|
"Add items to Flat BOM table"
|
||||||
self.doclist = self.doc.clear_table(self.doclist, 'flat_bom_details', 1)
|
self.doclist = self.doc.clear_table(self.doclist, 'flat_bom_details', 1)
|
||||||
for d in self.cur_flat_bom_items:
|
for d in self.cur_exploded_items:
|
||||||
ch = addchild(self.doc, 'flat_bom_details', 'BOM Explosion Item', 1, self.doclist)
|
ch = addchild(self.doc, 'flat_bom_details', 'BOM Explosion Item', 1, self.doclist)
|
||||||
for i in d.keys():
|
for i in d.keys():
|
||||||
ch.fields[i] = d[i]
|
ch.fields[i] = d[i]
|
||||||
@@ -360,40 +372,14 @@ class DocType:
|
|||||||
ch.save(1)
|
ch.save(1)
|
||||||
self.doc.save()
|
self.doc.save()
|
||||||
|
|
||||||
|
|
||||||
def get_parent_bom_list(self, bom_no):
|
def get_parent_bom_list(self, bom_no):
|
||||||
p_bom = sql("select parent from `tabBOM Item` where bom_no = '%s'" % bom_no)
|
p_bom = sql("select parent from `tabBOM Item` where bom_no = '%s'" % bom_no)
|
||||||
return p_bom and [i[0] for i in p_bom] or []
|
return p_bom and [i[0] for i in p_bom] or []
|
||||||
|
|
||||||
|
|
||||||
def on_submit(self):
|
|
||||||
self.manage_default_bom()
|
|
||||||
|
|
||||||
|
|
||||||
def on_cancel(self):
|
|
||||||
# check if used in any other bom
|
|
||||||
par = sql("""select t1.parent from `tabBOM Item` t1, `tabBOM` t2
|
|
||||||
where t1.parent = t2.name and t1.bom_no = %s and t1.docstatus = 1
|
|
||||||
and t2.is_active = 1""", self.doc.name)
|
|
||||||
if par:
|
|
||||||
msgprint("""BOM can not be cancelled, as it is a child item \
|
|
||||||
in following active BOM %s""" % [d[0] for d in par], raise_exception=1)
|
|
||||||
|
|
||||||
webnotes.conn.set(self.doc, "is_active", 0)
|
|
||||||
webnotes.conn.set(self.doc, "is_default", 0)
|
|
||||||
self.manage_default_bom()
|
|
||||||
self.update_cost_and_exploded_items(calculate_cost=False)
|
|
||||||
|
|
||||||
|
|
||||||
def on_update_after_submit(self):
|
|
||||||
self.manage_default_bom()
|
|
||||||
self.validate_inactive_bom()
|
|
||||||
|
|
||||||
|
|
||||||
def validate_inactive_bom(self):
|
def validate_inactive_bom(self):
|
||||||
if not self.doc.is_active:
|
if not self.doc.is_active:
|
||||||
act_pbom = sql("""select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2
|
act_pbom = sql("""select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2
|
||||||
where t1.bom_no =%s and t2.name = t1.parent and t2.is_active = 1
|
where t1.bom_no = %s and t2.name = t1.parent and t2.is_active = 1
|
||||||
and t2.docstatus = 1 and t1.docstatus =1 """, self.doc.name)
|
and t2.docstatus = 1 and t1.docstatus =1 """, self.doc.name)
|
||||||
if act_pbom and act_pbom[0][0]:
|
if act_pbom and act_pbom[0][0]:
|
||||||
msgprint("""Sorry cannot inactivate as BOM: %s is child
|
msgprint("""Sorry cannot inactivate as BOM: %s is child
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"creation": "2012-12-14 10:15:15",
|
"creation": "2012-12-14 10:15:15",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"modified": "2012-12-14 13:40:48"
|
"modified": "2012-12-14 16:51:01"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
"doctype": "DocType"
|
"doctype": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Select the item code for which Bill of Material is being created",
|
"description": "Item to be manufactured or repacked",
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Item",
|
"label": "Item",
|
||||||
@@ -65,9 +65,35 @@
|
|||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"no_copy": 1,
|
||||||
|
"oldfieldtype": "Select",
|
||||||
|
"allow_on_submit": 1,
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Track Operations",
|
"label": "Is Active",
|
||||||
"fieldname": "track_operations",
|
"oldfieldname": "is_active",
|
||||||
|
"default": "1",
|
||||||
|
"fieldname": "is_active",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"reqd": 0,
|
||||||
|
"hidden": 0,
|
||||||
|
"permlevel": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"no_copy": 1,
|
||||||
|
"oldfieldtype": "Check",
|
||||||
|
"allow_on_submit": 1,
|
||||||
|
"doctype": "DocField",
|
||||||
|
"label": "Is Default",
|
||||||
|
"oldfieldname": "is_default",
|
||||||
|
"fieldname": "is_default",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"permlevel": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Manage cost of operations",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"label": "With Operations",
|
||||||
|
"fieldname": "with_operations",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
@@ -78,7 +104,7 @@
|
|||||||
"options": "Specify the operations, operating cost and give a unique Operation no to your operations.",
|
"options": "Specify the operations, operating cost and give a unique Operation no to your operations.",
|
||||||
"fieldname": "operations",
|
"fieldname": "operations",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"depends_on": "track_operations",
|
"depends_on": "with_operations",
|
||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -100,7 +126,6 @@
|
|||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Enter the raw materials required to manufacture the BOM item. Specify the operation no as entered in the previous tab which will be performed on the raw materials entered.",
|
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "BOM Item",
|
"label": "BOM Item",
|
||||||
@@ -120,7 +145,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Consider Raw Material Cost As Per",
|
"label": "Rate Of Materials Based On",
|
||||||
"options": "Valuation Rate\nLast Purchase Rate",
|
"options": "Valuation Rate\nLast Purchase Rate",
|
||||||
"fieldname": "rm_cost_as_per",
|
"fieldname": "rm_cost_as_per",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
@@ -130,7 +155,7 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Total Cost",
|
"label": "Total Cost",
|
||||||
"fieldname": "total_cost",
|
"fieldname": "total_cost",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Currency",
|
||||||
"permlevel": 1
|
"permlevel": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -141,16 +166,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Raw Material Cost",
|
"label": "Total Raw Material Cost",
|
||||||
"fieldname": "raw_material_cost",
|
"fieldname": "raw_material_cost",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Currency",
|
||||||
"permlevel": 1
|
"permlevel": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Operating Cost",
|
"label": "Total Operating Cost",
|
||||||
"fieldname": "operating_cost",
|
"fieldname": "operating_cost",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Currency",
|
||||||
"permlevel": 1
|
"permlevel": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -161,7 +186,7 @@
|
|||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Total quantity of items for which raw materials required and operations done will be defined",
|
"description": "Quantity of item obtained after manufacturing / repacking from given quantities of raw materials",
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@@ -187,7 +212,6 @@
|
|||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Select name of the project if BOM need to be created against any project",
|
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Project Name",
|
"label": "Project Name",
|
||||||
@@ -198,37 +222,12 @@
|
|||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"in_filter": 1
|
"in_filter": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldtype": "Select",
|
|
||||||
"allow_on_submit": 1,
|
|
||||||
"doctype": "DocField",
|
|
||||||
"label": "Is Active",
|
|
||||||
"oldfieldname": "is_active",
|
|
||||||
"default": "1",
|
|
||||||
"fieldname": "is_active",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"reqd": 1,
|
|
||||||
"hidden": 0,
|
|
||||||
"permlevel": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldtype": "Check",
|
|
||||||
"allow_on_submit": 1,
|
|
||||||
"doctype": "DocField",
|
|
||||||
"label": "Is Default",
|
|
||||||
"oldfieldname": "is_default",
|
|
||||||
"fieldname": "is_default",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"permlevel": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Amended From",
|
"label": "Amended From",
|
||||||
"options": "Sales Invoice",
|
"options": "BOM",
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"permlevel": 1
|
"permlevel": 1
|
||||||
@@ -237,8 +236,7 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"depends_on": "eval:!doc.__islocal",
|
"depends_on": "eval:!doc.__islocal",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "BOM Explosion Items",
|
"label": "Materials Required (Exploded)",
|
||||||
"options": "Simple",
|
|
||||||
"fieldname": "section_break0",
|
"fieldname": "section_break0",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@@ -250,7 +248,7 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldtype": "Table",
|
"oldfieldtype": "Table",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "BOM Explosion Item",
|
"label": "Materials Required (Exploded)",
|
||||||
"oldfieldname": "flat_bom_details",
|
"oldfieldname": "flat_bom_details",
|
||||||
"default": "No Toolbar",
|
"default": "No Toolbar",
|
||||||
"fieldname": "flat_bom_details",
|
"fieldname": "flat_bom_details",
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
{
|
{
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"creation": "2012-07-03 13:30:04",
|
"creation": "2012-12-14 10:15:16",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"modified": "2012-12-10 18:30:00"
|
"modified": "2012-12-14 16:53:30"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
"label": "Amount",
|
"label": "Amount",
|
||||||
"oldfieldname": "amount_as_per_sr",
|
"oldfieldname": "amount_as_per_sr",
|
||||||
"fieldname": "amount",
|
"fieldname": "amount",
|
||||||
"fieldtype": "Float"
|
"fieldtype": "Currency"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"oldfieldtype": "Link",
|
"oldfieldtype": "Link",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"creation": "2012-12-14 10:15:16",
|
"creation": "2012-12-14 10:15:16",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"modified": "2012-12-14 13:11:49"
|
"modified": "2012-12-14 16:35:33"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
"oldfieldname": "amount_as_per_mar",
|
"oldfieldname": "amount_as_per_mar",
|
||||||
"width": "150px",
|
"width": "150px",
|
||||||
"fieldname": "amount",
|
"fieldname": "amount",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Currency",
|
||||||
"permlevel": 1
|
"permlevel": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,20 +2,15 @@
|
|||||||
{
|
{
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"creation": "2012-03-27 14:36:02",
|
"creation": "2012-12-14 10:15:16",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"modified": "2012-12-10 18:30:00"
|
"modified": "2012-12-14 16:06:37"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section_style": "Simple",
|
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
"colour": "White:FFF",
|
"doctype": "DocType",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing"
|
||||||
"show_in_menu": 0,
|
|
||||||
"version": 8,
|
|
||||||
"server_code_error": " ",
|
|
||||||
"doctype": "DocType"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
@@ -38,15 +33,6 @@
|
|||||||
"name": "BOM Operation",
|
"name": "BOM Operation",
|
||||||
"doctype": "DocType"
|
"doctype": "DocType"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"write": 1,
|
|
||||||
"permlevel": 0,
|
|
||||||
"doctype": "DocPerm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"permlevel": 1,
|
|
||||||
"doctype": "DocPerm"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@@ -59,7 +45,7 @@
|
|||||||
{
|
{
|
||||||
"oldfieldtype": "Text",
|
"oldfieldtype": "Text",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Opn Description",
|
"label": "Operation Description",
|
||||||
"oldfieldname": "opn_description",
|
"oldfieldname": "opn_description",
|
||||||
"fieldname": "opn_description",
|
"fieldname": "opn_description",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Text",
|
||||||
@@ -70,7 +56,6 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"label": "Workstation",
|
"label": "Workstation",
|
||||||
"oldfieldname": "workstation",
|
"oldfieldname": "workstation",
|
||||||
"trigger": "Client",
|
|
||||||
"fieldname": "workstation",
|
"fieldname": "workstation",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@@ -103,5 +88,14 @@
|
|||||||
"fieldname": "operating_cost",
|
"fieldname": "operating_cost",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"reqd": 0
|
"reqd": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"write": 1,
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"permlevel": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"permlevel": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -42,6 +42,6 @@ def rebuilt_exploded_bom():
|
|||||||
get_obj("BOM", bom[0], with_children=1).on_update()
|
get_obj("BOM", bom[0], with_children=1).on_update()
|
||||||
|
|
||||||
def cleanup_bom():
|
def cleanup_bom():
|
||||||
webnotes.conn.sql("""UPDATE `tabBOM` SET is_active = if(is_active='Yes', 1, 0),
|
webnotes.conn.sql("""UPDATE `tabBOM` SET is_active = if(is_active in ('Yes', 1), 1, 0),
|
||||||
track_operations = 1""")
|
with_operations = 1""")
|
||||||
|
|
||||||
@@ -66,7 +66,6 @@ KBItemToolbar = function(args, kb) {
|
|||||||
|
|
||||||
this.setup_del = function() {
|
this.setup_del = function() {
|
||||||
$(this.line1).find('.del-link').click(function() {
|
$(this.line1).find('.del-link').click(function() {
|
||||||
console.log(1);
|
|
||||||
this.innerHTML = 'deleting...';
|
this.innerHTML = 'deleting...';
|
||||||
this.disabled = 1;
|
this.disabled = 1;
|
||||||
$c_page('utilities', 'questions', 'delete', {
|
$c_page('utilities', 'questions', 'delete', {
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ erpnext.setup_mousetrap = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind(["command+s", "ctrl+s"], function() {
|
Mousetrap.bind(["command+s", "ctrl+s"], function() {
|
||||||
if(cur_frm && !cur_frm.save_disabled)
|
if(cur_frm && !cur_frm.save_disabled && cint(cur_frm.doc.docstatus)===0)
|
||||||
cur_frm.save();
|
cur_frm.save();
|
||||||
else if(wn.container.page.save_action)
|
else if(wn.container.page.save_action)
|
||||||
wn.container.page.save_action();
|
wn.container.page.save_action();
|
||||||
|
|||||||
@@ -154,7 +154,6 @@ erpnext.SalesChart = Class.extend({
|
|||||||
rename: function() {
|
rename: function() {
|
||||||
var node = this.selected_node();
|
var node = this.selected_node();
|
||||||
wn.model.rename_doc(this.ctype, node.data('label'), function(new_name) {
|
wn.model.rename_doc(this.ctype, node.data('label'), function(new_name) {
|
||||||
console.log(new_name)
|
|
||||||
node.data('label', new_name).find(".tree-label").html(new_name);
|
node.data('label', new_name).find(".tree-label").html(new_name);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
"""Global Defaults"""
|
"""Global Defaults"""
|
||||||
import webnotes
|
import webnotes
|
||||||
|
from webnotes.utils import cint
|
||||||
|
|
||||||
keydict = {
|
keydict = {
|
||||||
"fiscal_year": "current_fiscal_year",
|
"fiscal_year": "current_fiscal_year",
|
||||||
@@ -66,12 +67,11 @@ class DocType:
|
|||||||
|
|
||||||
def validate_session_expiry(self):
|
def validate_session_expiry(self):
|
||||||
if self.doc.session_expiry:
|
if self.doc.session_expiry:
|
||||||
from datetime import datetime
|
parts = self.doc.session_expiry.split(":")
|
||||||
try:
|
if len(parts)!=2 or not (cint(parts[0]) or cint(parts[1])):
|
||||||
datetime.strptime(self.doc.session_expiry, "%H:%M")
|
|
||||||
except ValueError:
|
|
||||||
webnotes.msgprint("""Session Expiry must be in format hh:mm""",
|
webnotes.msgprint("""Session Expiry must be in format hh:mm""",
|
||||||
raise_exception=1)
|
raise_exception=1)
|
||||||
|
|
||||||
|
|
||||||
def get_defaults(self):
|
def get_defaults(self):
|
||||||
return webnotes.conn.get_defaults()
|
return webnotes.conn.get_defaults()
|
||||||
|
|||||||
@@ -20,11 +20,9 @@ cur_frm.fields_dict['delivery_note'].get_query = function(doc, cdt, cdn) {
|
|||||||
|
|
||||||
|
|
||||||
cur_frm.fields_dict['item_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
|
cur_frm.fields_dict['item_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
|
||||||
console.log(doc.delivery_note);
|
|
||||||
var query = 'SELECT name, description FROM `tabItem` WHERE name IN ( \
|
var query = 'SELECT name, description FROM `tabItem` WHERE name IN ( \
|
||||||
SELECT item_code FROM `tabDelivery Note Item` dnd \
|
SELECT item_code FROM `tabDelivery Note Item` dnd \
|
||||||
WHERE parent="' + doc.delivery_note + '" AND IFNULL(qty, 0) > IFNULL(packed_qty, 0)) AND %(key)s LIKE "%s" LIMIT 50';
|
WHERE parent="' + doc.delivery_note + '" AND IFNULL(qty, 0) > IFNULL(packed_qty, 0)) AND %(key)s LIKE "%s" LIMIT 50';
|
||||||
console.log(query);
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user