From 9be11afbdee128e422efd20e55460ab4755ff631 Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Tue, 30 Mar 2021 12:09:46 +0530 Subject: [PATCH] feat: price margin in buying (#25058) --- .../doctype/pricing_rule/pricing_rule.json | 1 - .../purchase_invoice_item.json | 55 +++++++++++++++++- .../sales_invoice_item.json | 3 +- .../purchase_order_item.json | 58 +++++++++++++++++-- erpnext/controllers/taxes_and_totals.py | 2 +- erpnext/public/js/controllers/buying.js | 23 -------- erpnext/public/js/controllers/transaction.js | 44 ++++++++++++-- .../quotation_item/quotation_item.json | 3 +- .../sales_order_item/sales_order_item.json | 3 +- erpnext/selling/sales_common.js | 34 ----------- .../delivery_note_item.json | 3 +- .../purchase_receipt_item.json | 56 +++++++++++++++++- 12 files changed, 207 insertions(+), 78 deletions(-) diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json index 81890d50b9..428989aa96 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json @@ -358,7 +358,6 @@ "reqd": 1 }, { - "depends_on": "eval: doc.selling == 1", "fieldname": "margin", "fieldtype": "Section Break", "label": "Margin" diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index 07e75acb41..96ad0fd785 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -28,10 +28,16 @@ "stock_qty", "sec_break1", "price_list_rate", - "discount_percentage", - "discount_amount", "col_break3", "base_price_list_rate", + "section_break_26", + "margin_type", + "margin_rate_or_amount", + "rate_with_margin", + "column_break_30", + "discount_percentage", + "discount_amount", + "base_rate_with_margin", "sec_break2", "rate", "amount", @@ -789,6 +795,7 @@ "fieldname": "stock_uom_rate", "fieldtype": "Currency", "label": "Rate of Stock UOM", + "no_copy": 1, "options": "currency", "read_only": 1 }, @@ -799,12 +806,54 @@ "no_copy": 1, "print_hide": 1, "read_only": 1 + }, + { + "collapsible": 1, + "fieldname": "section_break_26", + "fieldtype": "Section Break", + "label": "Discount and Margin" + }, + { + "depends_on": "price_list_rate", + "fieldname": "margin_type", + "fieldtype": "Select", + "label": "Margin Type", + "options": "\nPercentage\nAmount", + "print_hide": 1 + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate", + "fieldname": "margin_rate_or_amount", + "fieldtype": "Float", + "label": "Margin Rate or Amount", + "print_hide": 1 + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount", + "fieldname": "rate_with_margin", + "fieldtype": "Currency", + "label": "Rate With Margin", + "options": "currency", + "read_only": 1 + }, + { + "fieldname": "column_break_30", + "fieldtype": "Column Break" + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount", + "fieldname": "base_rate_with_margin", + "fieldtype": "Currency", + "label": "Rate With Margin (Company Currency)", + "options": "Company:company:default_currency", + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2021-01-30 21:43:21.488258", + "modified": "2021-02-23 00:59:52.614805", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index b403c7b237..8e6952a93c 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -818,6 +818,7 @@ "fieldname": "stock_uom_rate", "fieldtype": "Currency", "label": "Rate of Stock UOM", + "no_copy": 1, "options": "currency", "read_only": 1 } @@ -825,7 +826,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2021-01-30 21:42:37.796771", + "modified": "2021-02-23 01:05:22.123527", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", 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 75b2954ddd..5baf6939cd 100644 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json @@ -27,11 +27,17 @@ "stock_qty", "sec_break1", "price_list_rate", + "last_purchase_rate", + "col_break3", + "base_price_list_rate", + "discount_and_margin_section", + "margin_type", + "margin_rate_or_amount", + "rate_with_margin", + "column_break_28", "discount_percentage", "discount_amount", - "col_break3", - "last_purchase_rate", - "base_price_list_rate", + "base_rate_with_margin", "sec_break2", "rate", "amount", @@ -733,15 +739,59 @@ "fieldname": "stock_uom_rate", "fieldtype": "Currency", "label": "Rate of Stock UOM", + "no_copy": 1, "options": "currency", "read_only": 1 + }, + { + "collapsible": 1, + "fieldname": "discount_and_margin_section", + "fieldtype": "Section Break", + "label": "Discount and Margin" + }, + { + "depends_on": "price_list_rate", + "fieldname": "margin_type", + "fieldtype": "Select", + "label": "Margin Type", + "options": "\nPercentage\nAmount", + "print_hide": 1 + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate", + "fieldname": "margin_rate_or_amount", + "fieldtype": "Float", + "label": "Margin Rate or Amount", + "print_hide": 1 + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount", + "fieldname": "rate_with_margin", + "fieldtype": "Currency", + "label": "Rate With Margin", + "options": "currency", + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "column_break_28", + "fieldtype": "Column Break" + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount", + "fieldname": "base_rate_with_margin", + "fieldtype": "Currency", + "label": "Rate With Margin (Company Currency)", + "options": "Company:company:default_currency", + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-01-30 21:44:41.816974", + "modified": "2021-02-23 01:00:27.132705", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order Item", diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index f976b17ae6..eb33a47873 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -107,7 +107,7 @@ class calculate_taxes_and_totals(object): elif item.discount_amount and item.pricing_rules: item.rate = item.price_list_rate - item.discount_amount - if item.doctype in ['Quotation Item', 'Sales Order Item', 'Delivery Note Item', 'Sales Invoice Item', 'POS Invoice Item']: + if item.doctype in ['Quotation Item', 'Sales Order Item', 'Delivery Note Item', 'Sales Invoice Item', 'POS Invoice Item', 'Purchase Invoice Item', 'Purchase Order Item', 'Purchase Receipt Item']: item.rate_with_margin, item.base_rate_with_margin = self.calculate_margin(item) if flt(item.rate_with_margin) > 0: item.rate = flt(item.rate_with_margin * (1.0 - (item.discount_percentage / 100.0)), item.precision("rate")) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index c96386611b..67b12fbca4 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -141,29 +141,6 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ this.apply_price_list(); }, - price_list_rate: function(doc, cdt, cdn) { - var item = frappe.get_doc(cdt, cdn); - - frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]); - - let item_rate = item.price_list_rate; - if (doc.doctype == "Purchase Order" && item.blanket_order_rate) { - item_rate = item.blanket_order_rate; - } - - if (item.discount_percentage) { - item.discount_amount = flt(item_rate) * flt(item.discount_percentage) / 100; - } - - if (item.discount_amount) { - item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item)); - } else { - item.rate = item_rate; - } - - this.calculate_taxes_and_totals(); - }, - discount_percentage: function(doc, cdt, cdn) { var item = frappe.get_doc(cdt, cdn); item.discount_amount = 0.0; diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index e0b0b272f3..51e4905a93 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -648,6 +648,40 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }, + price_list_rate: function(doc, cdt, cdn) { + var item = frappe.get_doc(cdt, cdn); + frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]); + + // check if child doctype is Sales Order Item/Qutation Item and calculate the rate + if (in_list(["Quotation Item", "Sales Order Item", "Delivery Note Item", "Sales Invoice Item", "POS Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Purchase Receipt Item"]), cdt) + this.apply_pricing_rule_on_item(item); + else + item.rate = flt(item.price_list_rate * (1 - item.discount_percentage / 100.0), + precision("rate", item)); + + this.calculate_taxes_and_totals(); + }, + + margin_rate_or_amount: function(doc, cdt, cdn) { + // calculated the revised total margin and rate on margin rate changes + let item = frappe.get_doc(cdt, cdn); + this.apply_pricing_rule_on_item(item); + this.calculate_taxes_and_totals(); + cur_frm.refresh_fields(); + }, + + margin_type: function(doc, cdt, cdn) { + // calculate the revised total margin and rate on margin type changes + let item = frappe.get_doc(cdt, cdn); + if (!item.margin_type) { + frappe.model.set_value(cdt, cdn, "margin_rate_or_amount", 0); + } else { + this.apply_pricing_rule_on_item(item, doc, cdt, cdn); + this.calculate_taxes_and_totals(); + cur_frm.refresh_fields(); + } + }, + get_incoming_rate: function(item, posting_date, posting_time, voucher_type, company) { let item_args = { @@ -1023,7 +1057,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ }, set_margin_amount_based_on_currency: function(exchange_rate) { - if (in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]), this.frm.doc.doctype) { + if (in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "Purchase Invoice", "Purchase Order", "Purchase Receipt"]), this.frm.doc.doctype) { var me = this; $.each(this.frm.doc.items || [], function(i, d) { if(d.margin_type == "Amount") { @@ -1278,10 +1312,10 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ change_grid_labels: function(company_currency) { var me = this; - this.frm.set_currency_labels(["base_rate", "base_net_rate", "base_price_list_rate", "base_amount", "base_net_amount"], + this.frm.set_currency_labels(["base_rate", "base_net_rate", "base_price_list_rate", "base_amount", "base_net_amount", "base_rate_with_margin"], company_currency, "items"); - this.frm.set_currency_labels(["rate", "net_rate", "price_list_rate", "amount", "net_amount", "stock_uom_rate"], + this.frm.set_currency_labels(["rate", "net_rate", "price_list_rate", "amount", "net_amount", "stock_uom_rate", "rate_with_margin"], this.frm.doc.currency, "items"); if(this.frm.fields_dict["operations"]) { @@ -1319,7 +1353,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ // toggle columns var item_grid = this.frm.fields_dict["items"].grid; - $.each(["base_rate", "base_price_list_rate", "base_amount"], function(i, fname) { + $.each(["base_rate", "base_price_list_rate", "base_amount", "base_rate_with_margin"], function(i, fname) { if(frappe.meta.get_docfield(item_grid.doctype, fname)) item_grid.set_column_disp(fname, me.frm.doc.currency != company_currency); }); @@ -1466,7 +1500,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ }); // if doctype is Quotation Item / Sales Order Iten then add Margin Type and rate in item_list - if (in_list(["Quotation Item", "Sales Order Item", "Delivery Note Item", "Sales Invoice Item"]), d.doctype){ + if (in_list(["Quotation Item", "Sales Order Item", "Delivery Note Item", "Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Purchase Receipt Item"]), d.doctype) { item_list[0]["margin_type"] = d.margin_type; item_list[0]["margin_rate_or_amount"] = d.margin_rate_or_amount; } diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json index a6785f709a..8b53902d32 100644 --- a/erpnext/selling/doctype/quotation_item/quotation_item.json +++ b/erpnext/selling/doctype/quotation_item/quotation_item.json @@ -641,6 +641,7 @@ "fieldname": "stock_uom_rate", "fieldtype": "Currency", "label": "Rate of Stock UOM", + "no_copy": 1, "options": "currency", "read_only": 1 } @@ -648,7 +649,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2021-01-30 21:39:40.174551", + "modified": "2021-02-23 01:13:54.670763", "modified_by": "Administrator", "module": "Selling", "name": "Quotation 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 37e47a9d41..1e5590e748 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -786,6 +786,7 @@ "fieldname": "stock_uom_rate", "fieldtype": "Currency", "label": "Rate of Stock UOM", + "no_copy": 1, "options": "currency", "read_only": 1 } @@ -793,7 +794,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2021-01-30 21:35:07.617320", + "modified": "2021-02-23 01:15:05.803091", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order Item", diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index ce084646e1..04285735ab 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -127,20 +127,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ this.set_dynamic_labels(); }, - price_list_rate: function(doc, cdt, cdn) { - var item = frappe.get_doc(cdt, cdn); - frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]); - - // check if child doctype is Sales Order Item/Qutation Item and calculate the rate - if(in_list(["Quotation Item", "Sales Order Item", "Delivery Note Item", "Sales Invoice Item", "POS Invoice Item"]), cdt) - this.apply_pricing_rule_on_item(item); - else - item.rate = flt(item.price_list_rate * (1 - item.discount_percentage / 100.0), - precision("rate", item)); - - this.calculate_taxes_and_totals(); - }, - discount_percentage: function(doc, cdt, cdn) { var item = frappe.get_doc(cdt, cdn); item.discount_amount = 0.0; @@ -353,26 +339,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ refresh_field('product_bundle_help'); }, - margin_rate_or_amount: function(doc, cdt, cdn) { - // calculated the revised total margin and rate on margin rate changes - var item = locals[cdt][cdn]; - this.apply_pricing_rule_on_item(item) - this.calculate_taxes_and_totals(); - cur_frm.refresh_fields(); - }, - - margin_type: function(doc, cdt, cdn){ - // calculate the revised total margin and rate on margin type changes - var item = locals[cdt][cdn]; - if(!item.margin_type) { - frappe.model.set_value(cdt, cdn, "margin_rate_or_amount", 0); - } else { - this.apply_pricing_rule_on_item(item, doc,cdt, cdn) - this.calculate_taxes_and_totals(); - cur_frm.refresh_fields(); - } - }, - company_address: function() { var me = this; if(this.frm.doc.company_address) { diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json index 17996247c5..b05090a237 100644 --- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json +++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json @@ -750,6 +750,7 @@ "fieldname": "stock_uom_rate", "fieldtype": "Currency", "label": "Rate of Stock UOM", + "no_copy": 1, "options": "currency", "read_only": 1 } @@ -758,7 +759,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-01-30 21:42:03.767968", + "modified": "2021-02-23 01:04:08.588104", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Note Item", diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json index 8974ad9318..efe3642d23 100644 --- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json +++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -37,10 +37,16 @@ "returned_qty", "rate_and_amount", "price_list_rate", - "discount_percentage", - "discount_amount", "col_break3", "base_price_list_rate", + "discount_and_margin_section", + "margin_type", + "margin_rate_or_amount", + "rate_with_margin", + "column_break_37", + "discount_percentage", + "discount_amount", + "base_rate_with_margin", "sec_break1", "rate", "amount", @@ -880,6 +886,7 @@ "fieldname": "stock_uom_rate", "fieldtype": "Currency", "label": "Rate of Stock UOM", + "no_copy": 1, "options": "currency", "read_only": 1 }, @@ -890,12 +897,55 @@ "no_copy": 1, "print_hide": 1, "read_only": 1 + }, + { + "collapsible": 1, + "fieldname": "discount_and_margin_section", + "fieldtype": "Section Break", + "label": "Discount and Margin" + }, + { + "depends_on": "price_list_rate", + "fieldname": "margin_type", + "fieldtype": "Select", + "label": "Margin Type", + "options": "\nPercentage\nAmount", + "print_hide": 1 + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate", + "fieldname": "margin_rate_or_amount", + "fieldtype": "Float", + "label": "Margin Rate or Amount", + "print_hide": 1 + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount", + "fieldname": "rate_with_margin", + "fieldtype": "Currency", + "label": "Rate With Margin", + "options": "currency", + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "column_break_37", + "fieldtype": "Column Break" + }, + { + "depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount", + "fieldname": "base_rate_with_margin", + "fieldtype": "Currency", + "label": "Rate With Margin (Company Currency)", + "options": "Company:company:default_currency", + "print_hide": 1, + "read_only": 1 } ], "idx": 1, "istable": 1, "links": [], - "modified": "2021-01-30 21:44:06.918515", + "modified": "2021-02-23 00:59:14.360847", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt Item",