From 370cdc017022252bf6a5faaee8abc9f8d7dca23f Mon Sep 17 00:00:00 2001 From: ronelvcabrera <44422325+ronelvcabrera@users.noreply.github.com> Date: Wed, 4 Dec 2019 18:37:11 +0800 Subject: [PATCH] feat(Sales/Purchase Order): optional to reference a Blanket Order (#19612) --- .../purchase_order/test_purchase_order.py | 26 ++++++++++++++++++- .../purchase_order_item.json | 12 ++++----- .../doctype/blanket_order/blanket_order.py | 4 +++ erpnext/public/js/controllers/transaction.js | 8 ++++++ .../doctype/sales_order/test_sales_order.py | 23 +++++++++++++++- .../sales_order_item/sales_order_item.json | 11 +++++++- erpnext/stock/get_item_details.py | 13 ++++++---- 7 files changed, 83 insertions(+), 14 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index a0a1e8ed5c..08f5d8b4d0 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -17,6 +17,8 @@ from erpnext.stock.doctype.material_request.material_request import make_purchas from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.controllers.accounts_controller import update_child_qty_rate from erpnext.controllers.status_updater import OverAllowanceError +from erpnext.manufacturing.doctype.blanket_order.test_blanket_order import make_blanket_order + class TestPurchaseOrder(unittest.TestCase): def test_make_purchase_receipt(self): @@ -620,6 +622,27 @@ class TestPurchaseOrder(unittest.TestCase): po.save() self.assertEqual(po.schedule_date, add_days(nowdate(), 2)) + + def test_po_optional_blanket_order(self): + """ + Expected result: Blanket order Ordered Quantity should only be affected on Purchase Order with against_blanket_order = 1. + Second Purchase Order should not add on to Blanket Orders Ordered Quantity. + """ + + bo = make_blanket_order(blanket_order_type = "Purchasing", quantity = 10, rate = 10) + + po = create_purchase_order(item_code= "_Test Item", qty = 5, against_blanket_order = 1) + po_doc = frappe.get_doc('Purchase Order', po.get('name')) + # To test if the PO has a Blanket Order + self.assertTrue(po_doc.items[0].blanket_order) + + po = create_purchase_order(item_code= "_Test Item", qty = 5, against_blanket_order = 0) + po_doc = frappe.get_doc('Purchase Order', po.get('name')) + # To test if the PO does NOT have a Blanket Order + self.assertEqual(po_doc.items[0].blanket_order, None) + + + def make_pr_against_po(po, received_qty=0): pr = make_purchase_receipt(po) @@ -693,7 +716,8 @@ def create_purchase_order(**args): "qty": args.qty or 10, "rate": args.rate or 500, "schedule_date": add_days(nowdate(), 1), - "include_exploded_items": args.get('include_exploded_items', 1) + "include_exploded_items": args.get('include_exploded_items', 1), + "against_blanket_order": args.against_blanket_order }) if not args.do_not_save: po.insert() diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json index c409c1f46e..15bc97c2a4 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -43,7 +43,6 @@ "base_amount", "pricing_rules", "is_free_item", - "is_fixed_asset", "section_break_29", "net_rate", "net_amount", @@ -67,6 +66,7 @@ "supplier_quotation", "supplier_quotation_item", "col_break5", + "against_blanket_order", "blanket_order", "blanket_order_rate", "item_group", @@ -511,6 +511,7 @@ "read_only": 1 }, { + "depends_on": "eval:doc.against_blanket_order", "fieldname": "blanket_order", "fieldtype": "Link", "label": "Blanket Order", @@ -518,6 +519,7 @@ "options": "Blanket Order" }, { + "depends_on": "eval:doc.against_blanket_order", "fieldname": "blanket_order_rate", "fieldtype": "Currency", "label": "Blanket Order Rate", @@ -703,16 +705,14 @@ }, { "default": "0", - "fetch_from": "item_code.is_fixed_asset", - "fieldname": "is_fixed_asset", + "fieldname": "against_blanket_order", "fieldtype": "Check", - "label": "Is Fixed Asset", - "read_only": 1 + "label": "Against Blanket Order" } ], "idx": 1, "istable": 1, - "modified": "2019-11-07 17:19:12.090355", + "modified": "2019-11-19 14:10:52.865006", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order Item", diff --git a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py index faed707d60..38118bd78d 100644 --- a/erpnext/manufacturing/doctype/blanket_order/blanket_order.py +++ b/erpnext/manufacturing/doctype/blanket_order/blanket_order.py @@ -44,6 +44,8 @@ def make_sales_order(source_name): target.item_name = item.get("item_name") target.description = item.get("description") target.uom = item.get("stock_uom") + target.against_blanket_order = 1 + target.blanket_order = source_name target_doc = get_mapped_doc("Blanket Order", source_name, { "Blanket Order": { @@ -71,6 +73,8 @@ def make_purchase_order(source_name): target.description = item.get("description") target.uom = item.get("stock_uom") target.warehouse = item.get("default_warehouse") + target.against_blanket_order = 1 + target.blanket_order = source_name target_doc = get_mapped_doc("Blanket Order", source_name, { "Blanket Order": { diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 5da949320a..46a58fba7c 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1716,6 +1716,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }, + against_blanket_order: function(doc, cdt, cdn) { + var item = locals[cdt][cdn]; + if(!item.against_blanket_order) { + frappe.model.set_value(this.frm.doctype + " Item", item.name, "blanket_order", null); + frappe.model.set_value(this.frm.doctype + " Item", item.name, "blanket_order_rate", 0.00); + } + }, + blanket_order: function(doc, cdt, cdn) { var me = this; var item = locals[cdt][cdn]; diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index bd07841488..feb6b76c4d 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -12,6 +12,7 @@ from erpnext.selling.doctype.sales_order.sales_order import make_work_orders from erpnext.controllers.accounts_controller import update_child_qty_rate import json from erpnext.selling.doctype.sales_order.sales_order import make_raw_material_request +from erpnext.manufacturing.doctype.blanket_order.test_blanket_order import make_blanket_order class TestSalesOrder(unittest.TestCase): def tearDown(self): @@ -819,6 +820,25 @@ class TestSalesOrder(unittest.TestCase): mr_doc = frappe.get_doc('Material Request',mr.get('name')) self.assertEqual(mr_doc.items[0].sales_order, so.name) + def test_so_optional_blanket_order(self): + """ + Expected result: Blanket order Ordered Quantity should only be affected on Sales Order with against_blanket_order = 1. + Second Sales Order should not add on to Blanket Orders Ordered Quantity. + """ + + bo = make_blanket_order(blanket_order_type = "Selling", quantity = 10, rate = 10) + + so = make_sales_order(item_code= "_Test Item", qty = 5, against_blanket_order = 1) + so_doc = frappe.get_doc('Sales Order', so.get('name')) + # To test if the SO has a Blanket Order + self.assertTrue(so_doc.items[0].blanket_order) + + so = make_sales_order(item_code= "_Test Item", qty = 5, against_blanket_order = 0) + so_doc = frappe.get_doc('Sales Order', so.get('name')) + # To test if the SO does NOT have a Blanket Order + self.assertEqual(so_doc.items[0].blanket_order, None) + + def make_sales_order(**args): so = frappe.new_doc("Sales Order") args = frappe._dict(args) @@ -845,7 +865,8 @@ def make_sales_order(**args): "warehouse": args.warehouse, "qty": args.qty or 10, "uom": args.uom or None, - "rate": args.rate or 100 + "rate": args.rate or 100, + "against_blanket_order": args.against_blanket_order }) so.delivery_date = add_days(so.transaction_date, 10) 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 3fd1e6461e..86b09c2814 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -68,6 +68,7 @@ "target_warehouse", "prevdoc_docname", "col_break4", + "against_blanket_order", "blanket_order", "blanket_order_rate", "planning_section", @@ -574,6 +575,7 @@ "report_hide": 1 }, { + "depends_on": "eval:doc.against_blanket_order", "fieldname": "blanket_order", "fieldtype": "Link", "label": "Blanket Order", @@ -581,6 +583,7 @@ "options": "Blanket Order" }, { + "depends_on": "eval:doc.against_blanket_order", "fieldname": "blanket_order_rate", "fieldtype": "Currency", "label": "Blanket Order Rate", @@ -741,11 +744,17 @@ "fieldname": "image_section", "fieldtype": "Section Break", "label": "Image" + }, + { + "default": "0", + "fieldname": "against_blanket_order", + "fieldtype": "Check", + "label": "Against Blanket Order" } ], "idx": 1, "istable": 1, - "modified": "2019-10-10 08:46:26.244823", + "modified": "2019-11-19 14:19:29.491945", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order Item", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 55f4be136b..76644ed846 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -213,7 +213,8 @@ def get_basic_details(args, item, overwrite_warehouse=True): project: "", qty: "", stock_qty: "", - conversion_factor: "" + conversion_factor: "", + against_blanket_order: 0/1 } :param item: `item_code` of Item object :return: frappe._dict @@ -302,7 +303,8 @@ def get_basic_details(args, item, overwrite_warehouse=True): "weight_per_unit":item.weight_per_unit, "weight_uom":item.weight_uom, "last_purchase_rate": item.last_purchase_rate if args.get("doctype") in ["Purchase Order"] else 0, - "transaction_date": args.get("transaction_date") + "transaction_date": args.get("transaction_date"), + "against_blanket_order": args.get("against_blanket_order") }) if item.get("enable_deferred_revenue") or item.get("enable_deferred_expense"): @@ -996,9 +998,10 @@ def get_serial_no(args, serial_nos=None, sales_order=None): def update_party_blanket_order(args, out): - blanket_order_details = get_blanket_order_details(args) - if blanket_order_details: - out.update(blanket_order_details) + if out["against_blanket_order"]: + blanket_order_details = get_blanket_order_details(args) + if blanket_order_details: + out.update(blanket_order_details) @frappe.whitelist() def get_blanket_order_details(args):