feat: price margin in buying (#24685)
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
index d08a854..3377164 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
@@ -357,7 +357,6 @@
"reqd": 1
},
{
- "depends_on": "eval: doc.selling == 1",
"fieldname": "margin",
"fieldtype": "Section Break",
"label": "Margin"
@@ -565,7 +564,7 @@
"icon": "fa fa-gift",
"idx": 1,
"links": [],
- "modified": "2020-12-04 00:36:24.698219",
+ "modified": "2021-03-01 23:18:38.717613",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule",
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 07e75ac..96ad0fd 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 b403c7b..8e6952a 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 75b2954..5baf693 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 10271cb..aab5770 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -109,7 +109,7 @@
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 c963866..67b12fb 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -141,29 +141,6 @@
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 9351f6d..1c0abdf 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -649,6 +649,40 @@
}
},
+ 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 = {
@@ -1030,7 +1064,7 @@
},
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") {
@@ -1280,10 +1314,10 @@
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"]) {
@@ -1321,7 +1355,7 @@
// 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);
});
@@ -1468,7 +1502,7 @@
});
// 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 a6785f7..8b53902 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 37e47a9..1e5590e 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 ce08464..0428573 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -127,20 +127,6 @@
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 @@
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 1799624..b05090a 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 8974ad9..efe3642 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",