From e48b47fc0c692a229325e0dd8bb977eeca84bf7f Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Wed, 16 May 2018 11:07:55 +0530 Subject: [PATCH] Production Plan, do not consider the sales orders against which work order has been created (#13800) * Production Plan, do not consider the sales orders against which work order has been created * Added test cases --- .../production_plan/production_plan.py | 104 ++++--- .../production_plan/test_production_plan.py | 49 +++- .../production_plan_item.json | 50 +++- .../doctype/work_order/work_order.json | 32 +++ .../doctype/work_order/work_order.py | 21 ++ .../sales_order_item/sales_order_item.json | 269 +++++++++++++----- 6 files changed, 408 insertions(+), 117 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 1d3104238a..ee64a1670c 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -28,42 +28,12 @@ class ProductionPlan(Document): def get_open_sales_orders(self): """ Pull sales orders which are pending to deliver based on criteria selected""" - so_filter = item_filter = "" - if self.from_date: - so_filter += " and so.transaction_date >= %(from_date)s" - if self.to_date: - so_filter += " and so.transaction_date <= %(to_date)s" - if self.customer: - so_filter += " and so.customer = %(customer)s" - if self.project: - so_filter += " and so.project = %(project)s" + open_so = get_sales_orders(self) - if self.item_code: - item_filter += " and so_item.item_code = %(item)s" - - open_so = frappe.db.sql(""" - select distinct so.name, so.transaction_date, so.customer, so.base_grand_total - from `tabSales Order` so, `tabSales Order Item` so_item - where so_item.parent = so.name - and so.docstatus = 1 and so.status not in ("Stopped", "Closed") - and so.company = %(company)s - and so_item.qty > so_item.delivered_qty {0} {1} - and (exists (select name from `tabBOM` bom where bom.item=so_item.item_code - and bom.is_active = 1) - or exists (select name from `tabPacked Item` pi - where pi.parent = so.name and pi.parent_item = so_item.item_code - and exists (select name from `tabBOM` bom where bom.item=pi.item_code - and bom.is_active = 1))) - """.format(so_filter, item_filter), { - "from_date": self.from_date, - "to_date": self.to_date, - "customer": self.customer, - "project": self.project, - "item": self.item_code, - "company": self.company - }, as_dict=1) - - self.add_so_in_table(open_so) + if open_so: + self.add_so_in_table(open_so) + else: + frappe.msgprint(_("Sales orders are not available for production")) def add_so_in_table(self, open_so): """ Add sales orders in the table""" @@ -136,23 +106,23 @@ class ProductionPlan(Document): item_condition = ' and so_item.item_code = "{0}"'.format(frappe.db.escape(self.item_code)) items = frappe.db.sql("""select distinct parent, item_code, warehouse, - (qty - delivered_qty)*conversion_factor as pending_qty + (qty - work_order_qty) * conversion_factor as pending_qty, name from `tabSales Order Item` so_item - where parent in (%s) and docstatus = 1 and qty > delivered_qty + where parent in (%s) and docstatus = 1 and qty > work_order_qty and exists (select name from `tabBOM` bom where bom.item=so_item.item_code and bom.is_active = 1) %s""" % \ (", ".join(["%s"] * len(so_list)), item_condition), tuple(so_list), as_dict=1) if self.item_code: - item_condition = ' and pi.item_code = "{0}"'.format(frappe.db.escape(self.item_code)) + item_condition = ' and so_item.item_code = "{0}"'.format(frappe.db.escape(self.item_code)) packed_items = frappe.db.sql("""select distinct pi.parent, pi.item_code, pi.warehouse as warehouse, - (((so_item.qty - so_item.delivered_qty) * pi.qty) / so_item.qty) - as pending_qty + (((so_item.qty - so_item.work_order_qty) * pi.qty) / so_item.qty) + as pending_qty, pi.parent_item, so_item.name from `tabSales Order Item` so_item, `tabPacked Item` pi where so_item.parent = pi.parent and so_item.docstatus = 1 and pi.parent_item = so_item.item_code - and so_item.parent in (%s) and so_item.qty > so_item.delivered_qty + and so_item.parent in (%s) and so_item.qty > so_item.work_order_qty and exists (select name from `tabBOM` bom where bom.item=pi.item_code and bom.is_active = 1) %s""" % \ (", ".join(["%s"] * len(so_list)), item_condition), tuple(so_list), as_dict=1) @@ -194,7 +164,8 @@ class ProductionPlan(Document): 'bom_no': item_details and item_details.bom_no or '', 'planned_qty': data.pending_qty, 'pending_qty': data.pending_qty, - 'planned_start_date': now_datetime() + 'planned_start_date': now_datetime(), + 'product_bundle_item': data.parent_item }) if self.get_items_from == "Sales Order": @@ -261,6 +232,9 @@ class ProductionPlan(Document): self.status = 'In Process' def update_requested_status(self): + if not self.mr_items: + return + update_status = True for d in self.mr_items: if d.quantity != d.requested_qty: @@ -276,6 +250,7 @@ class ProductionPlan(Document): "production_item" : d.item_code, "use_multi_level_bom" : d.include_exploded_items, "sales_order" : d.sales_order, + "sales_order_item" : d.sales_order_item, "material_request" : d.material_request, "material_request_item" : d.material_request_item, "bom_no" : d.bom_no, @@ -284,7 +259,8 @@ class ProductionPlan(Document): "company" : self.company, "fg_warehouse" : d.warehouse, "production_plan" : self.name, - "production_plan_item" : d.name + "production_plan_item" : d.name, + "product_bundle_item" : d.product_bundle_item } item_details.update({ @@ -375,10 +351,10 @@ class ProductionPlan(Document): requested_qty = 0 if self.ignore_existing_ordered_qty: requested_qty = total_qty - elif total_qty > projected_qty: + else: requested_qty = total_qty - projected_qty - if requested_qty and requested_qty < row.min_order_qty: + if requested_qty > 0 and requested_qty < row.min_order_qty: requested_qty = row.min_order_qty if requested_qty > 0: @@ -482,6 +458,44 @@ class ProductionPlan(Document): return item_details +def get_sales_orders(self): + so_filter = item_filter = "" + if self.from_date: + so_filter += " and so.transaction_date >= %(from_date)s" + if self.to_date: + so_filter += " and so.transaction_date <= %(to_date)s" + if self.customer: + so_filter += " and so.customer = %(customer)s" + if self.project: + so_filter += " and so.project = %(project)s" + + if self.item_code: + item_filter += " and so_item.item_code = %(item)s" + + open_so = frappe.db.sql(""" + select distinct so.name, so.transaction_date, so.customer, so.base_grand_total + from `tabSales Order` so, `tabSales Order Item` so_item + where so_item.parent = so.name + and so.docstatus = 1 and so.status not in ("Stopped", "Closed") + and so.company = %(company)s + and so_item.qty > so_item.work_order_qty {0} {1} + and (exists (select name from `tabBOM` bom where bom.item=so_item.item_code + and bom.is_active = 1) + or exists (select name from `tabPacked Item` pi + where pi.parent = so.name and pi.parent_item = so_item.item_code + and exists (select name from `tabBOM` bom where bom.item=pi.item_code + and bom.is_active = 1))) + """.format(so_filter, item_filter), { + "from_date": self.from_date, + "to_date": self.to_date, + "customer": self.customer, + "project": self.project, + "item": self.item_code, + "company": self.company + }, as_dict=1) + + return open_so + @frappe.whitelist() def get_bin_details(row): if isinstance(row, string_types): diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py index 0a17708fbe..7f753dbde7 100644 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py @@ -7,7 +7,9 @@ import frappe import unittest from frappe.utils import nowdate, now_datetime, flt from erpnext.stock.doctype.item.test_item import create_item +from erpnext.manufacturing.doctype.production_plan.production_plan import get_sales_orders from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation +from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order class TestProductionPlan(unittest.TestCase): def setUp(self): @@ -26,7 +28,6 @@ class TestProductionPlan(unittest.TestCase): 'Test Production Item 1': ['Raw Material Item 1', 'Subassembly Item 1', 'Test Non Stock Raw Material']}.items(): if not frappe.db.get_value('BOM', {'item': item}): - print(item, raw_materials) make_bom(item = item, raw_materials = raw_materials) def test_production_plan(self): @@ -95,6 +96,52 @@ class TestProductionPlan(unittest.TestCase): sr2.cancel() pln.cancel() + def test_production_plan_sales_orders(self): + item = 'Test Production Item 1' + so = make_sales_order(item_code=item, qty=5) + sales_order = so.name + sales_order_item = so.items[0].name + + pln = frappe.new_doc('Production Plan') + pln.company = so.company + pln.get_items_from = 'Sales Order' + + pln.append('sales_orders', { + 'sales_order': so.name, + 'sales_order_date': so.transaction_date, + 'customer': so.customer, + 'grand_total': so.grand_total + }) + + pln.get_so_items() + pln.submit() + pln.make_work_order() + + work_order = frappe.db.get_value('Work Order', {'sales_order': sales_order, + 'production_plan': pln.name, 'sales_order_item': sales_order_item}, 'name') + + wo_doc = frappe.get_doc('Work Order', work_order) + wo_doc.update({ + 'wip_warehouse': '_Test Warehouse 1 - _TC', + 'fg_warehouse': '_Test Warehouse - _TC' + }) + wo_doc.submit() + + so_wo_qty = frappe.db.get_value('Sales Order Item', sales_order_item, 'work_order_qty') + self.assertTrue(so_wo_qty, 5) + + pln = frappe.new_doc('Production Plan') + pln.update({ + 'from_date': so.transaction_date, + 'to_date': so.transaction_date, + 'customer': so.customer, + 'item_code': item + }) + sales_orders = get_sales_orders(pln) or {} + sales_orders = [d.get('name') for d in sales_orders if d.get('name') == sales_order] + + self.assertEqual(sales_orders, []) + def create_production_plan(**args): args = frappe._dict(args) diff --git a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json index 3a8bcd94fc..4e78f61f8f 100644 --- a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json +++ b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json @@ -39,6 +39,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -72,6 +73,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150px" }, @@ -106,6 +108,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -139,6 +142,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -171,6 +175,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -200,6 +205,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -231,6 +237,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -261,6 +268,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -293,6 +301,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -323,6 +332,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -354,6 +364,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -386,6 +397,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -420,6 +432,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "80px" }, @@ -453,6 +466,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "200px" }, @@ -484,6 +498,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -514,6 +529,39 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "product_bundle_item", + "fieldtype": "Link", + "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": "Product Bundle Item", + "length": 0, + "no_copy": 1, + "options": "Item", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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 } ], @@ -527,7 +575,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-02-16 12:13:41.513586", + "modified": "2018-04-25 17:19:24.572528", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Plan Item", diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json index 1cc2459ab2..29e0048242 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.json +++ b/erpnext/manufacturing/doctype/work_order/work_order.json @@ -1481,6 +1481,38 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "product_bundle_item", + "fieldtype": "Link", + "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": "Product Bundle Item", + "length": 0, + "no_copy": 1, + "options": "Item", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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_on_submit": 0, diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 90a714940d..a6d2baaed8 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -205,6 +205,7 @@ class WorkOrder(Document): if not self.fg_warehouse: frappe.throw(_("For Warehouse is required before Submit")) + self.update_work_order_qty_in_so() self.update_reserved_qty_for_production() self.update_completed_qty_in_material_request() self.update_planned_qty() @@ -214,6 +215,7 @@ class WorkOrder(Document): self.validate_cancel() frappe.db.set(self,'status', 'Cancelled') + self.update_work_order_qty_in_so() self.delete_timesheet() self.update_completed_qty_in_material_request() self.update_planned_qty() @@ -249,6 +251,25 @@ class WorkOrder(Document): doc.set_status() doc.db_set('status', doc.status) + def update_work_order_qty_in_so(self): + if not self.sales_order and not self.sales_order_item: + return + + total_bundle_qty = 1 + if self.product_bundle_item: + total_bundle_qty = frappe.db.sql(""" select sum(qty) from + `tabProduct Bundle Item` where parent = %s""", (frappe.db.escape(self.product_bundle_item)))[0][0] + + cond = "product_bundle_item = %s" if self.product_bundle_item else "production_item = %s" + + qty = frappe.db.sql(""" select sum(qty) from + `tabWork Order` where sales_order = %s and docstatus = 1 and {0} + """.format(cond), (self.sales_order, (self.product_bundle_item or self.production_item)), as_list=1) + + work_order_qty = qty[0][0] if qty and qty[0][0] else 0 + frappe.db.set_value('Sales Order Item', + self.sales_order_item, 'work_order_qty', flt(work_order_qty/total_bundle_qty, 2)) + def update_completed_qty_in_material_request(self): if self.material_request: frappe.get_doc("Material Request", self.material_request).update_completed_qty([self.material_request_item]) diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json index fe53e4d020..9639cf81c9 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -44,6 +44,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150px" }, @@ -74,6 +75,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -102,6 +104,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -134,6 +137,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150" }, @@ -165,6 +169,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -197,6 +202,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "300px" }, @@ -228,6 +234,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -257,6 +264,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -287,6 +295,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -318,6 +327,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -347,6 +357,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -379,6 +390,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -413,6 +425,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "70px" }, @@ -442,6 +455,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -473,6 +487,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -503,6 +518,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -533,6 +549,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -562,6 +579,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -595,6 +613,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "70px" }, @@ -629,6 +648,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -660,6 +680,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -692,6 +713,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -723,6 +745,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -755,6 +778,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -784,6 +808,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -817,6 +842,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "70px" }, @@ -850,6 +876,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -879,6 +906,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -913,6 +941,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -948,6 +977,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -977,6 +1007,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1010,6 +1041,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -1044,6 +1076,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, @@ -1075,6 +1108,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1104,6 +1138,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1135,6 +1170,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1166,6 +1202,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1195,6 +1232,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1226,6 +1264,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1257,6 +1296,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1288,6 +1328,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1318,6 +1359,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1349,6 +1391,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1379,6 +1422,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1409,6 +1453,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1439,6 +1484,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1468,6 +1514,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1499,6 +1546,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1528,6 +1576,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1562,6 +1611,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "150px" }, @@ -1595,6 +1645,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1627,6 +1678,7 @@ "reqd": 0, "search_index": 1, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1659,6 +1711,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1692,6 +1745,102 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "billed_amt", + "fieldtype": "Currency", + "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": "Billed Amt", + "length": 0, + "no_copy": 1, + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "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_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "valuation_rate", + "fieldtype": "Currency", + "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": "Valuation Rate", + "length": 0, + "no_copy": 1, + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 1, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "gross_profit", + "fieldtype": "Currency", + "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": "Gross Profit", + "length": 0, + "no_copy": 1, + "options": "Company:company:default_currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 1, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1723,6 +1872,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1751,6 +1901,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1783,6 +1934,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "70px" }, @@ -1814,6 +1966,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "70px" }, @@ -1845,6 +1998,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1877,9 +2031,41 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "work_order_qty", + "fieldtype": "Float", + "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": "Work Order Qty", + "length": 0, + "no_copy": 1, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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_on_submit": 0, @@ -1909,6 +2095,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -1917,8 +2104,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "billed_amt", - "fieldtype": "Currency", + "fieldname": "section_break_63", + "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -1926,81 +2113,19 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Billed Amt", "length": 0, - "no_copy": 1, - "options": "currency", + "no_copy": 0, "permlevel": 0, - "print_hide": 1, + "precision": "", + "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 1, + "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "valuation_rate", - "fieldtype": "Currency", - "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": "Valuation Rate", - "length": 0, - "no_copy": 1, - "options": "Company:company:default_currency", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "gross_profit", - "fieldtype": "Currency", - "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": "Gross Profit", - "length": 0, - "no_copy": 1, - "options": "Company:company:default_currency", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -2034,6 +2159,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "50px" }, @@ -2068,6 +2194,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "50px" }, @@ -2100,6 +2227,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -2132,6 +2260,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 } ], @@ -2146,7 +2275,7 @@ "istable": 1, "max_attachments": 0, "menu_index": 0, - "modified": "2017-11-30 14:05:39.173834", + "modified": "2018-04-25 19:33:10.338965", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order Item",