From d7de3c606b2448fe0df93f0b566ca90c07c283c6 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 17 Apr 2017 13:36:08 +0530 Subject: [PATCH] [fix] Pricing rule for pos --- erpnext/accounts/doctype/sales_invoice/pos.py | 21 +++++++---- erpnext/accounts/page/pos/pos.js | 37 +++++++++++++++++-- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py index 419c5579e0..f1f997a7f6 100644 --- a/erpnext/accounts/doctype/sales_invoice/pos.py +++ b/erpnext/accounts/doctype/sales_invoice/pos.py @@ -32,7 +32,7 @@ def get_pos_data(): 'doc': doc, 'default_customer': pos_profile.get('customer'), 'items': get_items_list(pos_profile), - 'item_groups': get_item_group(pos_profile), + 'item_groups': get_item_groups(pos_profile), 'customers': customers, 'address': get_customers_address(customers), 'serial_no_data': get_serial_no_data(pos_profile, doc.company), @@ -132,7 +132,7 @@ def get_items_list(pos_profile): if pos_profile.get('item_groups'): # Get items based on the item groups defined in the POS profile for d in pos_profile.get('item_groups'): - item_groups.extend(get_child_nodes('Item Group', d.item_group)) + item_groups.extend([d.name for d in get_child_nodes('Item Group', d.item_group)]) cond = "item_group in (%s)"%(', '.join(['%s']*len(item_groups))) return frappe.db.sql(""" @@ -146,14 +146,19 @@ def get_items_list(pos_profile): disabled = 0 and has_variants = 0 and is_sales_item = 1 and {cond} """.format(cond=cond), tuple(item_groups), as_dict=1) -def get_item_group(pos_profile): +def get_item_groups(pos_profile): + item_group_dict = {} if pos_profile.get('item_groups'): item_groups = [] for d in pos_profile.get('item_groups'): item_groups.extend(get_child_nodes('Item Group', d.item_group)) - return item_groups else: - return frappe.db.sql_list("""Select name from `tabItem Group` order by name""") + item_groups = frappe.db.sql("""Select name, + lft, rgt from `tabItem Group` order by lft""", as_dict=1) + + for data in item_groups: + item_group_dict[data.name] = [data.lft, data.rgt] + return item_group_dict def get_customers_list(pos_profile): cond = "1=1" @@ -161,7 +166,7 @@ def get_customers_list(pos_profile): if pos_profile.get('customer_groups'): # Get customers based on the customer groups defined in the POS profile for d in pos_profile.get('customer_groups'): - customer_groups.extend(get_child_nodes('Customer Group', d.customer_group)) + customer_groups.extend([d.name for d in get_child_nodes('Customer Group', d.customer_group)]) cond = "customer_group in (%s)"%(', '.join(['%s']*len(customer_groups))) return frappe.db.sql(""" select name, customer_name, customer_group, @@ -187,8 +192,8 @@ def get_customers_address(customers): def get_child_nodes(group_type, root): lft, rgt = frappe.db.get_value(group_type, root, ["lft", "rgt"]) - return frappe.db.sql_list(""" Select name from `tab{tab}` where - lft >= {lft} and rgt <= {rgt}""".format(tab=group_type, lft=lft, rgt=rgt)) + return frappe.db.sql(""" Select name, lft, rgt from `tab{tab}` where + lft >= {lft} and rgt <= {rgt} order by lft""".format(tab=group_type, lft=lft, rgt=rgt), as_dict=1) def get_serial_no_data(pos_profile, company): # get itemwise serial no data diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index 670a577c4e..70067614b6 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -407,8 +407,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }); this.search_item_group = this.wrapper.find('.search-item-group'); - - var dropdown_html = me.item_groups.map(function(item_group) { + sorted_item_groups = this.get_sorted_item_groups() + var dropdown_html = sorted_item_groups.map(function(item_group) { return "
  • "+item_group+"
  • "; }).join(""); @@ -437,6 +437,15 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }) }, + get_sorted_item_groups: function() { + list = {} + $.each(this.item_groups, function(i, data) { + list[i] = data[0] + }) + + return Object.keys(list).sort(function(a,b){return list[a]-list[b]}) + }, + toggle_more_btn: function() { if(!this.items || this.items.length <= this.page_len) { this.wrapper.find(".btn-more").hide(); @@ -1091,9 +1100,9 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ // $(me.wrapper).find(".pos-item-wrapper").on("click", function () { $(this.wrapper).on("click", ".pos-item-wrapper", function () { me.item_code = ''; + me.customer_validate(); if($(me.pos_bill).is(":hidden")) return; - me.customer_validate(); if (me.frm.doc.docstatus == 0) { me.items = me.get_items($(this).attr("data-item-code")) me.add_to_cart(); @@ -1768,7 +1777,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ var me = this; return $.grep(this.pricing_rules, function (data) { if (item.qty >= data.min_qty && (item.qty <= (data.max_qty ? data.max_qty : item.qty))) { - if (data.item_code == item.item_code || in_list(['All Item Groups', item.item_group], data.item_group) || item.brand == data.brand) { + if (me.validate_item_condition(data, item)) { if (in_list(['Customer', 'Customer Group', 'Territory', 'Campaign'], data.applicable_for)) { return me.validate_condition(data) } else { @@ -1779,6 +1788,26 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }) }, + validate_item_condition: function (data, item) { + var apply_on = frappe.model.scrub(data.apply_on); + + return (data.apply_on == 'Item Group') + ? this.validate_item_group(data.item_group, item.item_group) : (data[apply_on] == item[apply_on]); + }, + + validate_item_group: function (pr_item_group, cart_item_group) { + //pr_item_group = pricing rule's item group + //cart_item_group = cart item's item group + //this.item_groups has information about item group's lft and rgt + //for example: {'Foods': [12, 19]} + + pr_item_group = this.item_groups[pr_item_group] + cart_item_group = this.item_groups[cart_item_group] + + return (cart_item_group[0] >= pr_item_group[0] && + cart_item_group[1] <= pr_item_group[1]) + }, + validate_condition: function (data) { //This method check condition based on applicable for condition = this.get_mapper_for_pricing_rule(data)[data.applicable_for]