Pricing Rule
This commit is contained in:
parent
62ec60188b
commit
a3dd72a759
64
erpnext/accounts/doctype/pricing_rule/pricing_rule.js
Normal file
64
erpnext/accounts/doctype/pricing_rule/pricing_rule.js
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Pricing Rule", "refresh", function(frm) {
|
||||
var help_content = ['<table class="table table-bordered" style="background-color: #f9f9f9;">',
|
||||
'<tr><td>',
|
||||
'<h4><i class="icon-hand-right"></i> ',
|
||||
__('Notes'),
|
||||
':</h4>',
|
||||
'<ul>',
|
||||
'<li>',
|
||||
__("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria."),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__("If selected Pricing Rule is made for 'Price', it will overwrite Price List. Pricing Rule price is the final price, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field."),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Discount Percentage can be applied either against a Price List or for all Price List.'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.'),
|
||||
'</li>',
|
||||
'</ul>',
|
||||
'</td></tr>',
|
||||
'<tr><td>',
|
||||
'<h4><i class="icon-question-sign"></i> ',
|
||||
__('How Pricing Rule is applied?'),
|
||||
'</h4>',
|
||||
'<ol>',
|
||||
'<li>',
|
||||
__("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand."),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__("Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc."),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Pricing Rules are further filtered based on quantity.'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('If two or more Pricing Rules are found based on the above conditions, Priority is applied. Priority is a number between 0 to 20 while default value is zero (blank). Higher number means it will take precedence if there are multiple Pricing Rules with same conditions.'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:'),
|
||||
'<ul>',
|
||||
'<li>',
|
||||
__('Item Code > Item Group > Brand'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Customer > Customer Group > Territory'),
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('Supplier > Supplier Type'),
|
||||
'</li>',
|
||||
'</ul>',
|
||||
'</li>',
|
||||
'<li>',
|
||||
__('If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict.'),
|
||||
'</li>',
|
||||
'</ol>',
|
||||
'</td></tr>',
|
||||
'</table>'].join("\n");
|
||||
|
||||
set_field_options("pricing_rule_help", help_content);
|
||||
});
|
@ -131,6 +131,13 @@
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "valid_from",
|
||||
@ -198,12 +205,25 @@
|
||||
"label": "For Price List",
|
||||
"options": "Price List",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "help_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"options": "Simple",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_help",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Pricing Rule Help",
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"icon": "icon-gift",
|
||||
"idx": 1,
|
||||
"istable": 0,
|
||||
"modified": "2014-05-12 16:24:52.005162",
|
||||
"modified": "2014-05-27 15:14:34.849671",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Pricing Rule",
|
||||
|
@ -15,7 +15,6 @@ class PricingRule(Document):
|
||||
self.validate_min_max_qty()
|
||||
self.cleanup_fields_value()
|
||||
|
||||
|
||||
def validate_mandatory(self):
|
||||
for field in ["apply_on", "applicable_for", "price_or_discount"]:
|
||||
tocheck = frappe.scrub(self.get(field) or "")
|
||||
@ -26,7 +25,6 @@ class PricingRule(Document):
|
||||
if self.min_qty and self.max_qty and flt(self.min_qty) > flt(self.max_qty):
|
||||
throw(_("Min Qty can not be greater than Max Qty"))
|
||||
|
||||
|
||||
def cleanup_fields_value(self):
|
||||
for logic_field in ["apply_on", "applicable_for", "price_or_discount"]:
|
||||
fieldname = frappe.scrub(self.get(logic_field) or "")
|
||||
|
@ -77,16 +77,19 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
},
|
||||
|
||||
supplier: function() {
|
||||
var me = this;
|
||||
if(this.frm.updating_party_details)
|
||||
return;
|
||||
erpnext.utils.get_party_details(this.frm,
|
||||
"erpnext.accounts.party.get_party_details", {
|
||||
erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details",
|
||||
{
|
||||
posting_date: this.frm.doc.posting_date,
|
||||
party: this.frm.doc.supplier,
|
||||
party_type: "Supplier",
|
||||
account: this.frm.doc.debit_to,
|
||||
price_list: this.frm.doc.buying_price_list,
|
||||
})
|
||||
}, function() {
|
||||
me.apply_pricing_rule();
|
||||
})
|
||||
},
|
||||
|
||||
credit_to: function() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "EVD.######",
|
||||
"creation": "2013-05-22 12:43:10.000000",
|
||||
"creation": "2013-05-22 12:43:10",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@ -193,17 +193,9 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@ -429,9 +421,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:27:53.000000",
|
||||
"modified": "2014-05-28 12:43:40.647183",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -155,8 +155,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
},
|
||||
|
||||
customer: function() {
|
||||
if(this.frm.updating_party_details)
|
||||
return;
|
||||
var me = this;
|
||||
if(this.frm.updating_party_details) return;
|
||||
|
||||
erpnext.utils.get_party_details(this.frm,
|
||||
"erpnext.accounts.party.get_party_details", {
|
||||
posting_date: this.frm.doc.posting_date,
|
||||
@ -164,7 +165,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
party_type: "Customer",
|
||||
account: this.frm.doc.debit_to,
|
||||
price_list: this.frm.doc.selling_price_list,
|
||||
})
|
||||
}, function() {
|
||||
me.apply_pricing_rule();
|
||||
})
|
||||
},
|
||||
|
||||
debit_to: function() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "INVD.######",
|
||||
"creation": "2013-06-04 11:02:19.000000",
|
||||
"creation": "2013-06-04 11:02:19",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@ -201,17 +201,9 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@ -456,9 +448,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:04:19.000000",
|
||||
"modified": "2014-05-28 12:42:28.209942",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -7,9 +7,11 @@ from frappe.utils import flt
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
if not filters.get("account"): return
|
||||
|
||||
columns = get_columns()
|
||||
|
||||
if not filters.get("account"): return columns, []
|
||||
|
||||
data = get_entries(filters)
|
||||
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
|
@ -62,7 +62,8 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
||||
},
|
||||
|
||||
supplier: function() {
|
||||
erpnext.utils.get_party_details(this.frm);
|
||||
var me = this;
|
||||
erpnext.utils.get_party_details(this.frm, null, null, function(){me.apply_pricing_rule()});
|
||||
},
|
||||
|
||||
supplier_address: function() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "POD/.#####",
|
||||
"creation": "2013-05-24 19:29:06.000000",
|
||||
"creation": "2013-05-24 19:29:06",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@ -252,17 +252,9 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@ -474,9 +466,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:26:25.000000",
|
||||
"modified": "2014-05-28 12:42:53.018610",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "SQI-.#####",
|
||||
"creation": "2013-05-22 12:43:10.000000",
|
||||
"creation": "2013-05-22 12:43:10",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@ -195,17 +195,9 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@ -354,9 +346,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:25:38.000000",
|
||||
"modified": "2014-05-28 12:44:17.347236",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -97,11 +97,17 @@ class AccountsController(TransactionBase):
|
||||
args = item.as_dict()
|
||||
args.update(parent_dict)
|
||||
ret = get_item_details(args)
|
||||
|
||||
for fieldname, value in ret.items():
|
||||
if item.meta.get_field(fieldname) and \
|
||||
item.get(fieldname) is None and value is not None:
|
||||
item.set(fieldname, value)
|
||||
|
||||
if ret.get("pricing_rule"):
|
||||
for field in ["base_price_list_rate", "price_list_rate",
|
||||
"discount_percentage", "base_rate", "rate"]:
|
||||
item.set(field, ret.get(field))
|
||||
|
||||
def set_taxes(self, tax_parentfield, tax_master_field):
|
||||
if not self.meta.get_field(tax_parentfield):
|
||||
return
|
||||
|
@ -194,6 +194,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
}
|
||||
|
||||
this.frm.script_manager.trigger("currency");
|
||||
this.apply_pricing_rule()
|
||||
}
|
||||
},
|
||||
|
||||
@ -225,7 +226,9 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
this.frm.doc.plc_conversion_rate !== this.frm.doc.conversion_rate) {
|
||||
this.frm.set_value("plc_conversion_rate", this.frm.doc.conversion_rate);
|
||||
}
|
||||
if(flt(this.frm.doc.conversion_rate)>0.0) this.calculate_taxes_and_totals();
|
||||
if(flt(this.frm.doc.conversion_rate)>0.0) {
|
||||
this.apply_pricing_rule();
|
||||
}
|
||||
},
|
||||
|
||||
get_price_list_currency: function(buying_or_selling) {
|
||||
@ -278,12 +281,12 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
}
|
||||
if(this.frm.doc.price_list_currency === this.frm.doc.currency) {
|
||||
this.frm.set_value("conversion_rate", this.frm.doc.plc_conversion_rate);
|
||||
this.calculate_taxes_and_totals();
|
||||
this.apply_pricing_rule();
|
||||
}
|
||||
},
|
||||
|
||||
qty: function(doc, cdt, cdn) {
|
||||
this.calculate_taxes_and_totals();
|
||||
this.apply_pricing_rule(frappe.get_doc(cdt, cdn));
|
||||
},
|
||||
|
||||
// tax rate
|
||||
@ -326,6 +329,52 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
this.calculate_taxes_and_totals();
|
||||
},
|
||||
|
||||
apply_pricing_rule: function(item) {
|
||||
var me = this;
|
||||
|
||||
var _apply_pricing_rule = function(item) {
|
||||
return me.frm.call({
|
||||
method: "erpnext.stock.get_item_details.apply_pricing_rule",
|
||||
child: item,
|
||||
args: {
|
||||
args: {
|
||||
item_code: item.item_code,
|
||||
item_group: item.item_group,
|
||||
brand: item.brand,
|
||||
qty: item.qty,
|
||||
customer: me.frm.doc.customer,
|
||||
customer_group: me.frm.doc.customer_group,
|
||||
territory: me.frm.doc.territory,
|
||||
supplier: me.frm.doc.supplier,
|
||||
supplier_type: me.frm.doc.supplier_type,
|
||||
currency: me.frm.doc.currency,
|
||||
conversion_rate: me.frm.doc.conversion_rate,
|
||||
price_list: me.frm.doc.selling_price_list ||
|
||||
me.frm.doc.buying_price_list,
|
||||
plc_conversion_rate: me.frm.doc.plc_conversion_rate,
|
||||
company: me.frm.doc.company,
|
||||
transaction_date: me.frm.doc.transaction_date || me.frm.doc.posting_date,
|
||||
campaign: me.frm.doc.campaign,
|
||||
sales_partner: me.frm.doc.sales_partner
|
||||
}
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
me.frm.script_manager.trigger("price_list_rate", item.doctype, item.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if(item) _apply_pricing_rule(item);
|
||||
else {
|
||||
$.each(this.get_item_doclist(), function(n, item) {
|
||||
_apply_pricing_rule(item);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
included_in_print_rate: function(doc, cdt, cdn) {
|
||||
var tax = frappe.get_doc(cdt, cdn);
|
||||
try {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.provide("erpnext.utils");
|
||||
erpnext.utils.get_party_details = function(frm, method, args) {
|
||||
erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||
if(!method) {
|
||||
method = "erpnext.accounts.party.get_party_details";
|
||||
}
|
||||
@ -33,6 +33,7 @@ erpnext.utils.get_party_details = function(frm, method, args) {
|
||||
frm.updating_party_details = true;
|
||||
frm.set_value(r.message);
|
||||
frm.updating_party_details = false;
|
||||
if(callback) callback()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "QUOD/.#####",
|
||||
"creation": "2013-03-07 11:42:57.000000",
|
||||
"creation": "2013-03-07 11:42:57",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@ -231,17 +231,9 @@
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@ -353,9 +345,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:20:34.000000",
|
||||
"modified": "2014-05-28 12:41:40.811916",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "SOD/.#####",
|
||||
"creation": "2013-03-07 11:42:58.000000",
|
||||
"creation": "2013-03-07 11:42:58",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@ -217,17 +217,9 @@
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@ -439,9 +431,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:20:05.000000",
|
||||
"modified": "2014-05-27 14:41:14.996650",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -104,7 +104,8 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
},
|
||||
|
||||
customer: function() {
|
||||
erpnext.utils.get_party_details(this.frm);
|
||||
var me = this;
|
||||
erpnext.utils.get_party_details(this.frm, null, null, function(){me.apply_pricing_rule()});
|
||||
},
|
||||
|
||||
customer_address: function() {
|
||||
@ -119,6 +120,14 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
erpnext.utils.get_contact_details(this.frm);
|
||||
},
|
||||
|
||||
sales_partner: function() {
|
||||
this.apply_pricing_rule();
|
||||
},
|
||||
|
||||
campaign: function() {
|
||||
this.apply_pricing_rule();
|
||||
},
|
||||
|
||||
barcode: function(doc, cdt, cdn) {
|
||||
this.item_code(doc, cdt, cdn);
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "DND/.#######",
|
||||
"creation": "2013-04-22 13:15:44.000000",
|
||||
"creation": "2013-04-22 13:15:44",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@ -225,17 +225,9 @@
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@ -437,9 +429,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:20:58.000000",
|
||||
"modified": "2014-05-28 12:42:05.788579",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"autoname": "GRND/.#######",
|
||||
"creation": "2013-05-24 19:29:10.000000",
|
||||
"creation": "2013-05-24 19:29:10",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
@ -256,17 +256,9 @@
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_price",
|
||||
"fieldname": "pricing_rule",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Price",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_for_discount",
|
||||
"fieldtype": "Link",
|
||||
"label": "Pricing Rule For Discount",
|
||||
"label": "Pricing Rule",
|
||||
"options": "Pricing Rule",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
@ -553,9 +545,12 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2014-02-28 11:27:09.000000",
|
||||
"modified": "2014-05-28 12:43:16.669040",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt Item",
|
||||
"owner": "Administrator"
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -68,7 +68,12 @@ def get_item_details(args):
|
||||
if args.transaction_type == "selling" and cint(args.is_pos):
|
||||
out.update(get_pos_settings_item_details(args.company, args))
|
||||
|
||||
apply_pricing_rule(out, args)
|
||||
# update args with out, if key or value not exists
|
||||
for key, value in out.iteritems():
|
||||
if args.get(key) is None:
|
||||
args[key] = value
|
||||
|
||||
out.update(apply_pricing_rule(args))
|
||||
|
||||
if args.get("doctype") in ("Sales Invoice", "Delivery Note"):
|
||||
if item_doc.has_serial_no == "Yes" and not args.serial_no:
|
||||
@ -243,36 +248,50 @@ def get_pos_settings(company):
|
||||
|
||||
return pos_settings and pos_settings[0] or None
|
||||
|
||||
def apply_pricing_rule(out, args):
|
||||
args_dict = frappe._dict().update(args)
|
||||
args_dict.update(out)
|
||||
all_pricing_rules = get_pricing_rules(args_dict)
|
||||
@frappe.whitelist()
|
||||
def apply_pricing_rule(args):
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
|
||||
rule_for_price = False
|
||||
for rule_for in ["price", "discount_percentage"]:
|
||||
pricing_rules = filter(lambda x: x[rule_for] > 0.0, all_pricing_rules)
|
||||
if rule_for_price:
|
||||
pricing_rules = filter(lambda x: not x["for_price_list"], pricing_rules)
|
||||
args = frappe._dict(args)
|
||||
out = frappe._dict()
|
||||
|
||||
pricing_rule = filter_pricing_rules(args_dict, pricing_rules)
|
||||
if not args.get("item_group") or not args.get("brand"):
|
||||
args.item_group, args.brand = frappe.db.get_value("Item",
|
||||
args.item_code, ["item_group", "brand"])
|
||||
|
||||
if pricing_rule:
|
||||
if rule_for == "discount_percentage":
|
||||
out["discount_percentage"] = pricing_rule["discount_percentage"]
|
||||
out["pricing_rule_for_discount"] = pricing_rule["name"]
|
||||
else:
|
||||
out["base_price_list_rate"] = pricing_rule["price"]
|
||||
out["price_list_rate"] = pricing_rule["price"] * \
|
||||
flt(args_dict.plc_conversion_rate) / flt(args_dict.conversion_rate)
|
||||
out["pricing_rule_for_price"] = pricing_rule["name"]
|
||||
rule_for_price = True
|
||||
if not args.get("customer_group") or not args.get("territory"):
|
||||
args.customer_group, args.territory = frappe.db.get_value("Customer",
|
||||
args.customer, ["customer_group", "territory"])
|
||||
|
||||
def get_pricing_rules(args_dict):
|
||||
if not args.get("supplier_type"):
|
||||
args.supplier_type = frappe.db.get_value("Supplier", args.supplier, "supplier_type")
|
||||
|
||||
pricing_rules = get_pricing_rules(args)
|
||||
pricing_rule = filter_pricing_rules(args, pricing_rules)
|
||||
|
||||
if pricing_rule:
|
||||
out.pricing_rule = pricing_rule.name
|
||||
if pricing_rule.price_or_discount == "Price":
|
||||
out.base_price_list_rate = pricing_rule.price
|
||||
out.price_list_rate = pricing_rule.price*flt(args.plc_conversion_rate)/flt(args.conversion_rate)
|
||||
out.base_rate = out.base_price_list_rate
|
||||
out.rate = out.price_list_rate
|
||||
out.discount_percentage = 0.0
|
||||
else:
|
||||
out.discount_percentage = pricing_rule.discount_percentage
|
||||
else:
|
||||
out.pricing_rule = None
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def get_pricing_rules(args):
|
||||
def _get_tree_conditions(doctype, allow_blank=True):
|
||||
field = frappe.scrub(doctype)
|
||||
condition = ""
|
||||
if args_dict.get(field):
|
||||
lft, rgt = frappe.db.get_value(doctype, args_dict[field], ["lft", "rgt"])
|
||||
if args.get(field):
|
||||
lft, rgt = frappe.db.get_value(doctype, args[field], ["lft", "rgt"])
|
||||
parent_groups = frappe.db.sql_list("""select name from `tab%s`
|
||||
where lft<=%s and rgt>=%s""" % (doctype, '%s', '%s'), (lft, rgt))
|
||||
|
||||
@ -284,8 +303,8 @@ def get_pricing_rules(args_dict):
|
||||
|
||||
|
||||
conditions = ""
|
||||
for field in ["customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
|
||||
if args_dict.get(field):
|
||||
for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
|
||||
if args.get(field):
|
||||
conditions += " and ifnull("+field+", '') in (%("+field+")s, '')"
|
||||
else:
|
||||
conditions += " and ifnull("+field+", '') = ''"
|
||||
@ -297,8 +316,7 @@ def get_pricing_rules(args_dict):
|
||||
|
||||
conditions += " and ifnull(for_price_list, '') in (%(price_list)s, '')"
|
||||
|
||||
|
||||
if args_dict.get("transaction_date"):
|
||||
if args.get("transaction_date"):
|
||||
conditions += """ and %(transaction_date)s between ifnull(valid_from, '2000-01-01')
|
||||
and ifnull(valid_upto, '2500-12-31')"""
|
||||
|
||||
@ -307,13 +325,13 @@ def get_pricing_rules(args_dict):
|
||||
and docstatus < 2 and ifnull(disable, 0) = 0 {conditions}
|
||||
order by priority desc, name desc""".format(
|
||||
item_group_condition=_get_tree_conditions("Item Group", False), conditions=conditions),
|
||||
args_dict, as_dict=1)
|
||||
args, as_dict=1)
|
||||
|
||||
def filter_pricing_rules(args_dict, pricing_rules):
|
||||
def filter_pricing_rules(args, pricing_rules):
|
||||
# filter for qty
|
||||
if pricing_rules and args_dict.get("qty"):
|
||||
pricing_rules = filter(lambda x: (args_dict.qty>=flt(x.min_qty)
|
||||
and (args_dict.qty<=x.max_qty if x.max_qty else True)), pricing_rules)
|
||||
if pricing_rules and args.get("qty"):
|
||||
pricing_rules = filter(lambda x: (args.qty>=flt(x.min_qty)
|
||||
and (args.qty<=x.max_qty if x.max_qty else True)), pricing_rules)
|
||||
|
||||
# find pricing rule with highest priority
|
||||
if pricing_rules:
|
||||
@ -323,15 +341,19 @@ def filter_pricing_rules(args_dict, pricing_rules):
|
||||
|
||||
# apply internal priority
|
||||
all_fields = ["item_code", "item_group", "brand", "customer", "customer_group", "territory",
|
||||
"supplier", "supplier_type", "campaign", "for_price_list", "sales_partner"]
|
||||
"supplier", "supplier_type", "campaign", "sales_partner"]
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
for field_set in [["item_code", "item_group", "brand"],
|
||||
["customer", "customer_group", "territory"], ["supplier", "supplier_type"]]:
|
||||
remaining_fields = list(set(all_fields) - set(field_set))
|
||||
if if_all_rules_same(pricing_rules, remaining_fields):
|
||||
pricing_rules = apply_internal_priority(pricing_rules, field_set, args_dict)
|
||||
pricing_rules = apply_internal_priority(pricing_rules, field_set, args)
|
||||
break
|
||||
if len(pricing_rules) > 1:
|
||||
price_or_discount = list(set([d.price_or_discount for d in pricing_rules]))
|
||||
if len(price_or_discount) == 1 and price_or_discount[0] == "Discount Percentage":
|
||||
pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules)
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
frappe.throw(_("Multiple Price Rule exists with same criteria, please resolve \
|
||||
@ -350,11 +372,11 @@ def if_all_rules_same(pricing_rules, fields):
|
||||
|
||||
return all_rules_same
|
||||
|
||||
def apply_internal_priority(pricing_rules, field_set, args_dict):
|
||||
def apply_internal_priority(pricing_rules, field_set, args):
|
||||
filtered_rules = []
|
||||
for field in field_set:
|
||||
if args_dict.get(field):
|
||||
filtered_rules = filter(lambda x: x[field]==args_dict[field], pricing_rules)
|
||||
if args.get(field):
|
||||
filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
|
||||
if filtered_rules: break
|
||||
|
||||
return filtered_rules or pricing_rules
|
||||
|
Loading…
x
Reference in New Issue
Block a user