diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index e933f5a711..84252a07c1 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -81,7 +81,7 @@ class BOM(WebsiteGenerator): def get_item_det(self, item_code): item = frappe.db.sql("""select name, item_name, docstatus, description, image, - is_sub_contracted_item, stock_uom, default_bom, last_purchase_rate + is_sub_contracted_item, stock_uom, default_bom, last_purchase_rate, allow_transfer_for_manufacture from `tabItem` where name=%s""", item_code, as_dict = 1) if not item: @@ -134,8 +134,10 @@ class BOM(WebsiteGenerator): 'rate' : rate / self.conversion_rate if self.conversion_rate else rate, 'qty' : args.get("qty") or args.get("stock_qty") or 1, 'stock_qty' : args.get("qty") or args.get("stock_qty") or 1, - 'base_rate' : rate + 'base_rate' : rate, + 'allow_transfer_for_manufacture': item and args['allow_transfer_for_manufacture'] or 0 } + return ret_item def validate_bom_currecny(self, item): @@ -462,6 +464,7 @@ class BOM(WebsiteGenerator): 'stock_uom' : d.stock_uom, 'stock_qty' : flt(d.stock_qty), 'rate' : d.base_rate, + 'allow_transfer_for_manufacture': d.allow_transfer_for_manufacture })) def company_currency(self): @@ -478,7 +481,7 @@ class BOM(WebsiteGenerator): # Did not use qty_consumed_per_unit in the query, as it leads to rounding loss child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name, bom_item.description, bom_item.source_warehouse, - bom_item.stock_uom, bom_item.stock_qty, bom_item.rate, + bom_item.stock_uom, bom_item.stock_qty, bom_item.rate, bom_item.allow_transfer_for_manufacture, bom_item.stock_qty / ifnull(bom.quantity, 1) as qty_consumed_per_unit from `tabBOM Explosion Item` bom_item, tabBOM bom where bom_item.parent = bom.name and bom.name = %s and bom.docstatus = 1""", bom_no, as_dict = 1) @@ -492,6 +495,7 @@ class BOM(WebsiteGenerator): 'stock_uom' : d['stock_uom'], 'stock_qty' : d['qty_consumed_per_unit'] * stock_qty, 'rate' : flt(d['rate']), + 'allow_transfer_for_manufacture': d.get('allow_transfer_for_manufacture', 0) })) def add_exploded_items(self): @@ -565,14 +569,16 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite if cint(fetch_exploded): query = query.format(table="BOM Explosion Item", where_conditions="", - select_columns = ", bom_item.source_warehouse, (Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s ) as idx") + select_columns = """, bom_item.source_warehouse, bom_item.allow_transfer_for_manufacture, + (Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s ) as idx""") + items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True) elif fetch_scrap_items: query = query.format(table="BOM Scrap Item", where_conditions="", select_columns=", bom_item.idx") items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True) else: query = query.format(table="BOM Item", where_conditions="", - select_columns = ", bom_item.source_warehouse, bom_item.idx") + select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.allow_transfer_for_manufacture") items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True) for item in items: @@ -648,7 +654,6 @@ def get_children(doctype, parent=None, is_root=False, **filters): return bom_items - def get_boms_in_bottom_up_order(bom_no=None): def _get_parent(bom_no): return frappe.db.sql_list("""select distinct parent from `tabBOM Item` @@ -671,3 +676,21 @@ def get_boms_in_bottom_up_order(bom_no=None): count += 1 return bom_list + +def add_additional_cost(stock_entry, work_order): + # Add non stock items cost in the additional cost + bom = frappe.get_doc('BOM', work_order.bom_no) + table = 'exploded_items' if work_order.get('use_multi_level_bom') else 'items' + + items = {} + for d in bom.get(table): + items.setdefault(d.item_code, d.rate) + + non_stock_items = frappe.get_all('Item', + fields="name", filters={'name': ('in', items.keys()), 'ifnull(is_stock_item, 0)': 0}, as_list=1) + + for name in non_stock_items: + stock_entry.append('additional_costs', { + 'description': name[0], + 'amount': items.get(name[0]) + }) diff --git a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json index 16cba0cf96..8c7db8f8b1 100644 --- a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json +++ b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json @@ -15,6 +15,7 @@ "fields": [ { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -43,10 +44,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -72,10 +75,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -102,10 +107,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -133,10 +140,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -162,10 +171,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -194,11 +205,13 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "300px" }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -224,10 +237,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -254,10 +269,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -285,10 +302,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -314,10 +333,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -345,10 +366,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -377,10 +400,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -406,10 +431,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -435,10 +462,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -467,10 +496,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -499,6 +530,39 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow_transfer_for_manufacture", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Allow Transfer for Manufacture", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 } ], @@ -512,7 +576,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-07-04 17:51:18.151002", + "modified": "2018-07-12 16:29:55.464426", "modified_by": "Administrator", "module": "Manufacturing", "name": "BOM Explosion Item", @@ -523,5 +587,6 @@ "read_only_onload": 0, "show_name_in_global_search": 0, "track_changes": 1, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json index 3f1fef0f64..ceee2c1555 100644 --- a/erpnext/manufacturing/doctype/bom_item/bom_item.json +++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json @@ -13,6 +13,7 @@ "fields": [ { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -46,6 +47,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -77,6 +79,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -107,6 +110,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -142,6 +146,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -174,6 +179,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -205,6 +211,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -239,6 +246,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -268,6 +276,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -299,6 +308,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -331,6 +341,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -361,6 +372,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -393,6 +405,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -425,6 +438,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -454,6 +468,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -487,6 +502,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -520,6 +536,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -551,6 +568,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -582,6 +600,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -614,6 +633,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -646,6 +666,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -676,6 +697,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -711,6 +733,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -743,6 +766,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -773,6 +797,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -805,6 +830,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -837,6 +863,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -867,6 +894,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -898,6 +926,39 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow_transfer_for_manufacture", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Allow Transfer for Manufacture", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -939,7 +1000,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-04-17 11:01:32.458783", + "modified": "2018-07-12 16:16:16.815165", "modified_by": "Administrator", "module": "Manufacturing", "name": "BOM Item", @@ -952,5 +1013,6 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py index 7f753dbde7..7cf426858d 100644 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py @@ -188,7 +188,7 @@ def make_bom(**args): 'qty': 1, 'uom': item_doc.stock_uom, 'stock_uom': item_doc.stock_uom, - 'rate': item_doc.valuation_rate + 'rate': item_doc.valuation_rate or args.rate }) bom.insert(ignore_permissions=True) diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py index cb30fda4f6..b32db3b62f 100644 --- a/erpnext/manufacturing/doctype/work_order/test_work_order.py +++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py @@ -12,6 +12,8 @@ from erpnext.manufacturing.doctype.work_order.work_order \ from erpnext.stock.doctype.stock_entry import test_stock_entry from erpnext.stock.utils import get_bin from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order +from erpnext.stock.doctype.item.test_item import make_item +from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom class TestWorkOrder(unittest.TestCase): def setUp(self): @@ -314,6 +316,62 @@ class TestWorkOrder(unittest.TestCase): allow_overproduction("overproduction_percentage_for_sales_order", 0) + def test_work_order_with_non_stock_item(self): + items = {'Finished Good Test Item For non stock': 1, '_Test FG Item': 1, '_Test FG Non Stock Item': 0} + for item, is_stock_item in items.items(): + make_item(item, { + 'is_stock_item': is_stock_item + }) + + if not frappe.db.get_value('Item Price', {'item_code': '_Test FG Non Stock Item'}): + frappe.get_doc({ + 'doctype': 'Item Price', + 'item_code': '_Test FG Non Stock Item', + 'price_list_rate': 1000, + 'price_list': 'Standard Buying' + }).insert(ignore_permissions=True) + + fg_item = 'Finished Good Test Item For non stock' + test_stock_entry.make_stock_entry(item_code="_Test FG Item", + target="_Test Warehouse - _TC", qty=1, basic_rate=100) + + if not frappe.db.get_value('BOM', {'item': fg_item}): + make_bom(item=fg_item, rate=1000, raw_materials = ['_Test FG Item', '_Test FG Non Stock Item']) + + wo = make_wo_order_test_record(production_item = fg_item) + se = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture", 1)) + se.insert() + se.submit() + + ste = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1)) + ste.insert() + self.assertEqual(len(ste.additional_costs), 1) + self.assertEqual(ste.total_additional_costs, 1000) + + def test_work_order_with_non_transfer_item(self): + items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0} + for item, allow_transfer in items.items(): + make_item(item, { + 'allow_transfer_for_manufacture': allow_transfer + }) + + fg_item = 'Finished Good Transfer Item' + test_stock_entry.make_stock_entry(item_code="_Test FG Item", + target="_Test Warehouse - _TC", qty=1, basic_rate=100) + test_stock_entry.make_stock_entry(item_code="_Test FG Item 1", + target="_Test Warehouse - _TC", qty=1, basic_rate=100) + + if not frappe.db.get_value('BOM', {'item': fg_item}): + make_bom(item=fg_item, raw_materials = ['_Test FG Item', '_Test FG Item 1']) + + wo = make_wo_order_test_record(production_item = fg_item) + ste = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture", 1)) + ste.insert() + ste.submit() + self.assertEqual(len(ste.items), 1) + ste1 = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1)) + self.assertEqual(len(ste1.items), 3) + def get_scrap_item_details(bom_no): scrap_items = {} for item in frappe.db.sql("""select item_code, stock_qty from `tabBOM Scrap Item` diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 62091ffd69..6995829757 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -528,7 +528,8 @@ class WorkOrder(Document): 'description': item.description, 'allow_alternative_item': item.allow_alternative_item, 'required_qty': item.qty, - 'source_warehouse': item.source_warehouse or item.default_warehouse + 'source_warehouse': item.source_warehouse or item.default_warehouse, + 'allow_transfer_for_manufacture': item.allow_transfer_for_manufacture }) self.set_available_qty() diff --git a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json index 7dea50d900..badeb91478 100644 --- a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json +++ b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json @@ -1,19 +1,20 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-04-18 07:38:26.314642", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2016-04-18 07:38:26.314642", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -41,11 +42,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -73,11 +75,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -103,11 +106,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -134,11 +138,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -165,11 +170,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -196,11 +202,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -227,11 +234,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -264,6 +272,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -290,43 +299,108 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:!parent.skip_transfer", - "fieldname": "consumed_qty", - "fieldtype": "Float", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Consumed Qty", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow_transfer_for_manufacture", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Allow Transfer for Manufacture", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_11", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:!parent.skip_transfer", + "fieldname": "consumed_qty", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Consumed Qty", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -353,14 +427,15 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, "columns": 0, "fieldname": "available_qty_at_wip_warehouse", "fieldtype": "Float", @@ -398,19 +473,20 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-03-05 13:07:07.530725", + "modified": "2018-07-12 16:16:54.237829", "modified_by": "Administrator", - "module": "Manufacturing", - "name": "Work Order Item", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 + "module": "Manufacturing", + "name": "Work Order Item", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/patches.txt b/erpnext/patches.txt index dc729910f5..a7fc349adf 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -555,3 +555,4 @@ execute:frappe.db.sql("update `tabDesktop Icon` set type = 'module' where module erpnext.patches.v11_0.set_salary_component_properties erpnext.patches.v11_0.set_user_permissions_for_department erpnext.patches.v11_0.hr_ux_cleanups +erpnext.patches.v11_0.update_allow_transfer_for_manufacture \ No newline at end of file diff --git a/erpnext/patches/v11_0/update_allow_transfer_for_manufacture.py b/erpnext/patches/v11_0/update_allow_transfer_for_manufacture.py new file mode 100644 index 0000000000..9c94deee4b --- /dev/null +++ b/erpnext/patches/v11_0/update_allow_transfer_for_manufacture.py @@ -0,0 +1,20 @@ +# Copyright (c) 2018, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + frappe.reload_doc('stock', 'doctype', 'item') + frappe.db.sql(""" update `tabItem` set allow_transfer_for_manufacture = 1 + where ifnull(is_stock_item, 0) = 1""") + + for doctype in ['BOM Item', 'Work Order Item', 'BOM Explosion Item']: + frappe.reload_doc('manufacturing', 'doctype', frappe.scrub(doctype)) + + frappe.db.sql(""" update `tab{0}` child, tabItem item + set + child.allow_transfer_for_manufacture = 1 + where + child.item_code = item.name and ifnull(item.is_stock_item, 0) = 1 + """.format(doctype)) \ No newline at end of file diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index d0005b47d2..3941cd912c 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -112,7 +112,7 @@ "search_index": 0, "set_only_once": 0, "translatable": 0, - "unique": 0 + "unique": 1 }, { "allow_bulk_edit": 0, @@ -445,6 +445,39 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "1", + "fieldname": "allow_transfer_for_manufacture", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Allow Transfer for Manufacture", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -3918,7 +3951,7 @@ "issingle": 0, "istable": 0, "max_attachments": 1, - "modified": "2018-06-20 15:13:15.668050", + "modified": "2018-07-12 17:16:50.567598", "modified_by": "Administrator", "module": "Stock", "name": "Item", @@ -4086,5 +4119,6 @@ "sort_order": "DESC", "title_field": "item_name", "track_changes": 1, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 7d822a7676..011df70bb5 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -11,7 +11,7 @@ from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError, get from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos, get_batch_qty from erpnext.stock.doctype.item.item import get_item_defaults -from erpnext.manufacturing.doctype.bom.bom import validate_bom_no +from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, add_additional_cost from erpnext.stock.utils import get_bin import json @@ -703,6 +703,8 @@ class StockEntry(StockController): # fetch the serial_no of the first stock entry for the second stock entry if self.work_order and self.purpose == "Manufacture": self.set_serial_nos(self.work_order) + work_order = frappe.get_doc('Work Order', self.work_order) + add_additional_cost(self, work_order) # add finished goods item if self.purpose in ("Manufacture", "Repack"): @@ -955,7 +957,8 @@ class StockEntry(StockController): wip_warehouse = None for d in pro_order.get("required_items"): - if flt(d.required_qty) > flt(d.transferred_qty): + if (flt(d.required_qty) > flt(d.transferred_qty) and + (d.allow_transfer_for_manufacture or self.purpose != "Material Transfer for Manufacture")): item_row = d.as_dict() if d.source_warehouse and not frappe.db.get_value("Warehouse", d.source_warehouse, "is_group"): item_row["from_warehouse"] = d.source_warehouse