def set_required_items(self, reset_only_qty=False): '''set required_items for production to keep track of reserved qty''' if not reset_only_qty: self.required_items = [] if self.bom_no and self.qty: item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty, fetch_exploded = self.use_multi_level_bom) if reset_only_qty: for d in self.get("required_items"): if item_dict.get(d.item_code): d.required_qty = item_dict.get(d.item_code).get("qty") else: # Attribute a big number (999) to idx for sorting putpose in case idx is NULL # For instance in BOM Explosion Item child table, the items coming from sub assembly items for item in sorted(item_dict.values(), key=lambda d: d['idx'] or 9999): self.append('required_items', { 'operation': item.operation, 'item_code': item.item_code, 'item_name': item.item_name, 'description': item.description, 'allow_alternative_item': item.allow_alternative_item, 'required_qty': item.qty, 'source_warehouse': item.source_warehouse or item.default_warehouse, 'include_item_in_manufacturing': item.include_item_in_manufacturing }) self.set_available_qty()
def test_get_items(self): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict items_dict = get_bom_items_as_dict(bom=get_default_bom(), company="_Test Company", qty=1, fetch_exploded=0) self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict) self.assertTrue(test_records[2]["items"][1]["item_code"] in items_dict) self.assertEqual(len(items_dict.values()), 2)
def test_get_items_exploded(self): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict items_dict = get_bom_items_as_dict(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=1) self.assertTrue(test_records[2]["bom_materials"][0]["item_code"] in items_dict) self.assertFalse(test_records[2]["bom_materials"][1]["item_code"] in items_dict) self.assertTrue(test_records[0]["bom_materials"][0]["item_code"] in items_dict) self.assertTrue(test_records[0]["bom_materials"][1]["item_code"] in items_dict) self.assertEquals(len(items_dict.values()), 3)
def set_required_items(self): '''set required_items for production to keep track of reserved qty''' if self.source_warehouse: item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty, fetch_exploded = self.use_multi_level_bom) for item in item_dict.values(): self.append('required_items', {'item_code': item.item_code, 'required_qty': item.qty})
def get_bom_raw_materials(self, qty): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict # item dict = { item_code: {qty, description, stock_uom} } item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty, fetch_exploded=self.use_multi_level_bom) for item in item_dict.values(): item.from_warehouse = self.from_warehouse or item.default_warehouse return item_dict
def set_required_items(self, reset_only_qty=False): '''set required_items for production to keep track of reserved qty''' if not reset_only_qty: self.required_items = [] operation = None if self.get('operations') and len(self.operations) == 1: operation = self.operations[0].operation if self.bom_no and self.qty: item_dict = get_bom_items_as_dict( self.bom_no, self.company, qty=self.qty, fetch_exploded=self.use_multi_level_bom) if reset_only_qty: for d in self.get("required_items"): if item_dict.get(d.item_code): d.required_qty = item_dict.get(d.item_code).get("qty") if not d.operation: d.operation = operation else: # Attribute a big number (999) to idx for sorting putpose in case idx is NULL # For instance in BOM Explosion Item child table, the items coming from sub assembly items for item in sorted(item_dict.values(), key=lambda d: d['idx'] or 9999): self.append( 'required_items', { 'rate': item.rate, 'amount': item.amount, 'operation': item.operation or operation, 'item_code': item.item_code, 'item_name': item.item_name, 'description': item.description, 'allow_alternative_item': item.allow_alternative_item, 'required_qty': item.qty, 'source_warehouse': item.source_warehouse or item.default_warehouse, 'include_item_in_manufacturing': item.include_item_in_manufacturing }) if not self.project: self.project = item.get("project") self.set_available_qty()
def get_bom_raw_materials(self, qty): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict # item dict = { item_code: {qty, description, stock_uom} } item_dict = get_bom_items_as_dict(self.bom_no, qty=qty, fetch_exploded = self.use_multi_level_bom) for item in item_dict.values(): item.from_warehouse = self.from_warehouse or item.default_warehouse return item_dict
def get_bom_scrap_material(self, qty): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict # item dict = { item_code: {qty, description, stock_uom} } item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty, fetch_exploded = 0, fetch_scrap_items = 1) for item in item_dict.values(): item.from_warehouse = "" return item_dict
def test_get_items(self): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict items_dict = get_bom_items_as_dict(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=0) self.assertTrue( test_records[2]["bom_materials"][0]["item_code"] in items_dict) self.assertTrue( test_records[2]["bom_materials"][1]["item_code"] in items_dict) self.assertEquals(len(items_dict.values()), 2)
def create_operations(doc, method): bom = doc.get('bom_no') bom_obj = frappe.get_doc('BOM', bom) item = doc.get('production_item') qty = doc.get('qty') uom = doc.get('stock_uom') description = doc.get('description') bom_ops = bom_obj.get('bom_operations') #creare production operations from bom operations for op in bom_ops: production_op = frappe.new_doc('Production Operations') production_op.op_name = op.operation_no production_op.op_desc = op.opn_description production_op.workstation = op.workstation production_op.planned_time = op.time_in_mins production_op.item = item production_op.qty = qty production_op.item_desc = description production_op.uom = uom production_op.p_order = doc.name production_op.bom = bom #fetch items required for each operation and add raw material lines material_dict = frappe.db.sql( """select bom_no, qty_consumed_per_unit, item_code, stock_uom from `tabBOM Item` where operation_no=%s""", op.operation_no, as_dict=1) for material in material_dict: #if raw material has BOM, fetch and add the exploded items if material.bom_no and doc.use_multi_level_bom: from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict exploded_items = get_bom_items_as_dict( material.bom_no, qty=qty * material.qty_consumed_per_unit, fetch_exploded=1) for d in exploded_items: line = production_op.append('raw_materials') line.item_code = cstr(d) line.item_qty = flt(exploded_items[d]["qty"]) line.uom = exploded_items[d]["stock_uom"] else: line = production_op.append('raw_materials') line.item_code = material.item_code line.item_qty = qty * material.qty_consumed_per_unit line.uom = material.stock_uom production_op.save()
def get_items_from_bom(self): self.items = [] if self.bom_no and self.qty: item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty, fetch_exploded = 1) for item in sorted(item_dict.values(), key=lambda d: d['idx']): self.append('items', { 'item_code': item.item_code, 'item_name': item.item_name, 'description': item.description, 'qty': item.qty, 'conversion_factor': 1, 'stock_qty': item.qty, 'uom': item.stock_uom }) return True
def set_required_items(self, reset_only_qty=False): """set required_items for production to keep track of reserved qty""" if not reset_only_qty: self.required_items = [] operation = None if self.get("operations") and len(self.operations) == 1: operation = self.operations[0].operation if self.bom_no and self.qty: item_dict = get_bom_items_as_dict( self.bom_no, self.company, qty=self.qty, fetch_exploded=self.use_multi_level_bom ) if reset_only_qty: for d in self.get("required_items"): if item_dict.get(d.item_code): d.required_qty = item_dict.get(d.item_code).get("qty") if not d.operation: d.operation = operation else: for item in sorted(item_dict.values(), key=lambda d: d["idx"] or float("inf")): self.append( "required_items", { "rate": item.rate, "amount": item.rate * item.qty, "operation": item.operation or operation, "item_code": item.item_code, "item_name": item.item_name, "description": item.description, "allow_alternative_item": item.allow_alternative_item, "required_qty": item.qty, "source_warehouse": item.source_warehouse or item.default_warehouse, "include_item_in_manufacturing": item.include_item_in_manufacturing, }, ) if not self.project: self.project = item.get("project") self.set_available_qty()
def create_operations(doc, method): bom = doc.get('bom_no') bom_obj = frappe.get_doc('BOM', bom) item = doc.get('production_item') qty = doc.get('qty') uom = doc.get('stock_uom') description= doc.get('description') bom_ops = bom_obj.get('bom_operations') #creare production operations from bom operations for op in bom_ops: production_op = frappe.new_doc('Production Operations') production_op.op_name = op.operation_no production_op.op_desc = op.opn_description production_op.workstation = op.workstation production_op.planned_time = op.time_in_mins production_op.item = item production_op.qty = qty production_op.item_desc = description production_op.uom = uom production_op.p_order = doc.name production_op.bom = bom #fetch items required for each operation and add raw material lines material_dict = frappe.db.sql("""select bom_no, qty_consumed_per_unit, item_code, stock_uom from `tabBOM Item` where operation_no=%s""", op.operation_no, as_dict=1) for material in material_dict: #if raw material has BOM, fetch and add the exploded items if material.bom_no and doc.use_multi_level_bom: from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict exploded_items = get_bom_items_as_dict(material.bom_no, qty=qty*material.qty_consumed_per_unit, fetch_exploded = 1) for d in exploded_items: line = production_op.append('raw_materials') line.item_code = cstr(d) line.item_qty = flt(exploded_items[d]["qty"]) line.uom = exploded_items[d]["stock_uom"] else: line = production_op.append('raw_materials') line.item_code = material.item_code line.item_qty = qty*material.qty_consumed_per_unit line.uom = material.stock_uom production_op.save()
def add_required_items(source, target): from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict from erpnext.selling.doctype.sales_order.sales_order import get_default_bom_item required_items = [] for i in target.products: bom = get_default_bom_item(i.item_code) item_dict = get_bom_items_as_dict( bom, source.company, qty=i.produced_qty, fetch_exploded=True) #self.use_multi_level_bom) for item in sorted(item_dict.values(), key=lambda d: d['idx']): required_items.append( dict(item_code=item.item_code, required_qty=item.qty, transferred_qty=item.qty, bom=bom, source_warehouse=item.source_warehouse or item.default_warehouse)) target.set('required_items', required_items)
def set_required_items(self, reset_only_qty=False): '''set required_items for production to keep track of reserved qty''' if not reset_only_qty: self.required_items = [] if self.bom_no and self.qty: item_dict = get_bom_items_as_dict( self.bom_no, self.company, qty=self.qty, fetch_exploded=self.use_multi_level_bom) if reset_only_qty: for d in self.get("required_items"): if item_dict.get(d.item_code): d.required_qty = item_dict.get(d.item_code).get("qty") else: for item in sorted(item_dict.values(), key=lambda d: d['idx']): self.append( 'required_items', { 'operation': item.operation, 'item_code': item.item_code, 'item_name': item.item_name, 'description': item.description, 'allow_alternative_item': item.allow_alternative_item, 'required_qty': item.qty, 'source_warehouse': item.source_warehouse or item.default_warehouse, 'allow_transfer_for_manufacture': item.allow_transfer_for_manufacture }) self.set_available_qty()
def set_required_items(self): '''set required_items for production to keep track of reserved qty''' self.required_items = [] if self.bom_no and self.qty: item_dict = get_bom_items_as_dict( self.bom_no, self.company, qty=self.qty, fetch_exploded=self.use_multi_level_bom) for item in sorted(item_dict.values(), key=lambda d: d['idx']): self.append( 'required_items', { 'item_code': item.item_code, 'required_qty': item.qty, 'source_warehouse': item.source_warehouse or item.default_warehouse }) self.set_available_qty()
def set_items(self,change_qty=0): self.set("sales_order_detail_item",[]) for i in self.get('items'): if i.item_code: # i.rate=0 if i.qty==0: i.qty=1 bom_no = get_default_bom_item(i.item_code) if bom_no: i.detail_id=i.idx from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict item_dict = get_bom_items_as_dict(bom_no, self.company, qty=i.qty,fetch_exploded = 1) for item in sorted(item_dict.values(), key=lambda d: d['idx']): if item.idx is None: # items_parent = frappe.db.sql("""select item_name from `tabBOM Item` where bom_no=(select name from `tabBOM` where item_name = %s and is_default=1 and docstatus != 2)""", item.item_name,as_dict=True) # items_parent = frappe.db.sql("""select item_name from `tabBOM Item` where bom_no=(select parent from `tabBOM Item` where item_name = %s and docstatus != 2)""", item.item_name,as_dict=True) #items_parent =frappe.db.sql("""select item_name from `tabBOM Item` where item_name = %s and docstatus != 2 and bom_no=(select name from `tabBOM` where item_name = %s and is_default=1 )""", (item.item_name,item.item_name),as_dict=True) print(bom_no) print("---------") items_parent=bom_no+":"+item.item_name else: items_parent=item.item_name self.append('sales_order_detail_item', { 'bom_id':i.idx, 'display_name':items_parent, 'bom_code':i.item_code, 'item_code': item.item_code, 'item_name': item.item_name, 'description': item.description, 'qty': item.qty, 'rate':item.rate, 'amount':item.amount, 'uom':item.stock_uom, 'conversion_factor':'1' }) self.set_missing_item_details()
def set_required_items(self, reset_only_qty=False): '''set required_items for production to keep track of reserved qty''' if not reset_only_qty: self.required_items = [] operation = None if self.get('operations') and len(self.operations) == 1: operation = self.operations[0].operation if self.bom_no and self.qty: item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty, fetch_exploded = self.use_multi_level_bom) if reset_only_qty: for d in self.get("required_items"): if item_dict.get(d.item_code): d.required_qty = item_dict.get(d.item_code).get("qty") if not d.operation: d.operation = operation else: for item in sorted(item_dict.values(), key=lambda d: d['idx'] or float('inf')): self.append('required_items', { 'rate': item.rate, 'amount': item.rate * item.qty, 'operation': item.operation or operation, 'item_code': item.item_code, 'item_name': item.item_name, 'description': item.description, 'allow_alternative_item': item.allow_alternative_item, 'required_qty': item.qty, 'source_warehouse': item.source_warehouse or item.default_warehouse, 'include_item_in_manufacturing': item.include_item_in_manufacturing }) if not self.project: self.project = item.get("project") self.set_available_qty()
def set_required_items(self, reset_only_qty=False): '''set required_items for production to keep track of reserved qty''' if not reset_only_qty: self.required_items = [] if self.bom_no and self.qty: item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty, fetch_exploded = self.use_multi_level_bom) if reset_only_qty: for d in self.get("required_items"): if item_dict.get(d.item_code): d.required_qty = item_dict.get(d.item_code).get("qty") else: for item in sorted(item_dict.values(), key=lambda d: d['idx']): self.append('required_items', { 'item_code': item.item_code, 'item_name': item.item_name, 'description': item.description, 'required_qty': item.qty, 'source_warehouse': item.source_warehouse or item.default_warehouse }) self.set_available_qty()