From e30f83a8afe06b389cbb2854c2fb5f37a623c0df Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 24 Feb 2017 18:02:50 +0530 Subject: [PATCH 01/16] [Enhancement] POS, numeric keypad --- erpnext/accounts/page/pos/pos.js | 25 ++++++++++++++ erpnext/public/build.json | 1 + erpnext/public/css/erpnext.css | 31 ++++++++++++++--- erpnext/public/js/pos/pos.html | 35 ++++++++++++++++---- erpnext/public/js/pos/pos_selected_item.html | 27 +++++++++++++++ erpnext/public/less/erpnext.less | 34 ++++++++++++++++--- 6 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 erpnext/public/js/pos/pos_selected_item.html diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index ed54ab400e..961b2a112c 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -374,6 +374,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.add_customer_btn = this.wrapper.find('.add-customer-btn'); this.pos_bill = this.wrapper.find('.pos-bill').hide(); this.list_customers = this.wrapper.find('.list-customers'); + this.numeric_keypad = this.wrapper.find('.numeric_keypad'); this.list_customers_btn.on('click', function () { $(this).toggleClass("view_customer"); @@ -383,12 +384,16 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ me.party_field.$input.attr('disabled', true); me.list_customers.show(); me.pos_bill.hide(); + me.numeric_keypad.hide(); } else { if(me.frm.doc.docstatus == 0) { me.party_field.$input.attr('disabled', false); } me.pos_bill.show(); me.list_customers.hide() + if(me.frm.doc.items.length > 0) { + me.numeric_keypad.show(); + } } }); this.add_customer_btn.on('click', function() { @@ -662,6 +667,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.frm.doc.customer_group = doc.customer_group; this.frm.doc.territory = doc.territory; this.pos_bill.show(); + this.numeric_keypad.show(); }, get_customers: function (key) { @@ -835,12 +841,29 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ update_rate: function () { var me = this; + + $(this.wrapper).find(".pos-bill-item").click(function() { + var item_code = $(this).attr("data-item-code"); + doc = me.get_child_item(item_code); + html_data = frappe.render_template("pos_selected_item", doc[0]) + $(me.wrapper).find('.selected-item').html(html_data) + me.bind_qty_event() + }) $(this.wrapper).find(".pos-item-rate").on("change", function () { var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); me.set_item_details(item_code, "rate", $(this).val()); }) }, + + get_child_item: function(item_code) { + var me = this; + return $.map(me.frm.doc.items, function(doc){ + if(doc.item_code == item_code) { + return doc + } + }) + }, set_item_details: function (item_code, field, value) { var me = this; @@ -950,6 +973,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.add_new_item_to_grid(); this.update_paid_amount_status(false) + this.wrapper.find(".item-cart").scrollTop(1000); }, add_new_item_to_grid: function () { @@ -959,6 +983,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.child.item_name = this.items[0].item_name; this.child.stock_uom = this.items[0].stock_uom; this.child.description = this.items[0].description; + this.child.discount_percentage = 0.0; this.child.qty = 1; this.child.item_group = this.items[0].item_group; this.child.cost_center = this.pos_profile_data['cost_center'] || this.items[0].cost_center; diff --git a/erpnext/public/build.json b/erpnext/public/build.json index c4056813b6..858514edfe 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -20,6 +20,7 @@ "public/js/controllers/transaction.js", "public/js/pos/pos.html", "public/js/pos/pos_bill_item.html", + "public/js/pos/pos_selected_item.html", "public/js/pos/pos_item.html", "public/js/pos/pos_tax_row.html", "public/js/pos/pos_invoice_list.html", diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css index cfe9f63ac8..b1f1985fd3 100644 --- a/erpnext/public/css/erpnext.css +++ b/erpnext/public/css/erpnext.css @@ -59,7 +59,8 @@ padding: 10px 0px; border-bottom: 1px solid #d1d8dd; } -.item-list-area { +.item-list-area, +.list-customers { padding: 15px 0px; overflow-y: scroll; height: calc(100vh - 162px); @@ -82,6 +83,19 @@ margin-left: -15px; margin-right: -15px; } +.item-cart { + overflow-y: scroll; + height: calc(100vh - 60vh); +} +.edit-pos-item { + height: 40px; + font-size: 14px; + border-top: 1px solid #d1d8dd; +} +.pos-bill-item:hover { + background-color: #f5f7fa; + cursor: pointer; +} .pos-bill-row { margin: 0px; padding: 7px 0px; @@ -157,13 +171,20 @@ .pos-keyboard-key, .delete-btn { border: 1px solid #d1d8dd; - height: 85px; - width: 85px; - margin: 10px 10px; - font-size: 24px; + height: 69px; + width: 69px; + font-size: 20px; font-weight: 200; background-color: #FDFDFD; border-color: #e8e8e8; + margin-left: -4px; +} +.pos-pay { + height: 69px; + width: 69px; + font-size: 17px; + font-weight: 200; + margin-left: -4px; } .multimode-payments { padding-left: 30px; diff --git a/erpnext/public/js/pos/pos.html b/erpnext/public/js/pos/pos.html index 44e42d79b1..c6341353fa 100644 --- a/erpnext/public/js/pos/pos.html +++ b/erpnext/public/js/pos/pos.html @@ -17,12 +17,12 @@
-
+
@@ -54,15 +54,38 @@
{% } %} -
+
{%= __("Grand Total") %}
-
+ + +
+
+ +
+ +
@@ -77,10 +100,10 @@
-
+
diff --git a/erpnext/public/js/pos/pos_selected_item.html b/erpnext/public/js/pos/pos_selected_item.html new file mode 100644 index 0000000000..491938e5c8 --- /dev/null +++ b/erpnext/public/js/pos/pos_selected_item.html @@ -0,0 +1,27 @@ +
Item {%= item_name %}
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
\ No newline at end of file diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less index 495e618f7e..34ea901650 100644 --- a/erpnext/public/less/erpnext.less +++ b/erpnext/public/less/erpnext.less @@ -74,7 +74,7 @@ border-bottom: 1px solid #d1d8dd; } -.item-list-area { +.item-list-area, .list-customers { padding: 15px 0px; overflow-y: scroll; height: ~"calc(100vh - 162px)"; @@ -102,6 +102,22 @@ margin-right: -15px; } +.item-cart { + overflow-y: scroll; + height: ~"calc(100vh - 60vh)"; +} + +.edit-pos-item { + height: 40px; + font-size: 14px; + border-top: 1px solid @border-color; +} + +.pos-bill-item:hover { + background-color: #f5f7fa; + cursor: pointer; +} + .pos-bill-row { margin: 0px; padding: 7px 0px; @@ -197,13 +213,21 @@ .pos-keyboard-key, .delete-btn { border: 1px solid #d1d8dd; - height:85px; - width:85px; - margin:10px 10px; - font-size:24px; + height:69px; + width:69px; + font-size:20px; font-weight:200; background-color: #FDFDFD; border-color: #e8e8e8; + margin-left:-4px; +} + +.pos-pay { + height:69px; + width:69px; + font-size:17px; + font-weight:200; + margin-left:-4px; } .multimode-payments { From f0c7ba4b1f26697ab5ddc763767deeb3d21b26d8 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 28 Feb 2017 16:51:17 +0530 Subject: [PATCH 02/16] added event on numeric keypad --- erpnext/accounts/page/pos/pos.js | 94 +++++++++++++++----- erpnext/public/css/erpnext.css | 15 +++- erpnext/public/js/pos/pos.html | 10 +-- erpnext/public/js/pos/pos_bill_item.html | 4 +- erpnext/public/js/pos/pos_selected_item.html | 8 +- erpnext/public/less/erpnext.less | 16 +++- 6 files changed, 111 insertions(+), 36 deletions(-) diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index 961b2a112c..e405ae038f 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -303,6 +303,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.make_list_customers(); this.make_customer(); this.make_item_list(); + this.bind_numeric_keypad(); this.make_discount_field() }, @@ -403,6 +404,40 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ me.set_focus(); }); }, + + bind_numeric_keypad: function() { + var me = this; + $(this.numeric_keypad).find('.pos-operation').on('click', function(){ + me.numeric_val = ''; + }) + + $(this.numeric_keypad).find('.numeric-keypad').on('click', function(){ + me.numeric_id = $(this).attr("id") || me.numeric_id; + me.val = $(this).attr("val") + if(me.val && me.numeric_id) { + me.selected_field = $(me.wrapper).find('.selected-item').find('.' + me.numeric_id) + me.numeric_val += me.val; + me.selected_field.val(flt(me.numeric_val)) + me.selected_field.trigger("change") + me.render_selected_item() + } + }) + + $(this.numeric_keypad).find('.numeric-del').click(function(){ + me.selected_field = $(me.wrapper).find('.selected-item').find('.' + me.numeric_id) + me.numeric_val = cstr(flt(me.selected_field.val())).slice(0, -1); + me.selected_field.val(me.numeric_val); + me.selected_field.trigger("change") + me.render_selected_item() + }) + + $(this.numeric_keypad).find('.pos-pay').click(function(){ + me.validate(); + me.update_paid_amount_status(true); + me.create_invoice(); + me.make_payment(); + }) + }, render_list_customers: function () { var me = this; @@ -797,11 +832,24 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }); } }, + + bind_items_event: function() { + var me = this; + $(this.wrapper).find(".pos-bill-item").click(function() { + me.numeric_val = ""; + me.numeric_id = "" + me.item_code = $(this).attr("data-item-code"); + me.render_selected_item() + me.bind_qty_event() + me.update_rate() + $(me.wrapper).find(".selected-item").scrollTop(1000); + }) + }, bind_qty_event: function () { var me = this; - - $(this.wrapper).find(".pos-item-qty").on("change", function () { + + $(this.wrapper).on("change", ".pos-item-qty", function () { var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); var qty = $(this).val(); me.update_qty(item_code, qty) @@ -818,8 +866,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) - 1; me.update_qty(item_code, qty) }) - - $(this.wrapper).find(".pos-item-discount").on("change", function () { + + $(this.wrapper).on("change", ".pos-item-disc", function () { var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); var discount = $(this).val(); me.update_discount(item_code, discount) @@ -841,20 +889,20 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ update_rate: function () { var me = this; - - $(this.wrapper).find(".pos-bill-item").click(function() { - var item_code = $(this).attr("data-item-code"); - doc = me.get_child_item(item_code); - html_data = frappe.render_template("pos_selected_item", doc[0]) - $(me.wrapper).find('.selected-item').html(html_data) - me.bind_qty_event() - }) - - $(this.wrapper).find(".pos-item-rate").on("change", function () { + $(this.wrapper).on("change", ".pos-item-price", function () { var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); me.set_item_details(item_code, "rate", $(this).val()); }) }, + + render_selected_item: function() { + doc = this.get_child_item(this.item_code); + $(this.wrapper).find('.selected-item').empty(); + if(doc.length) { + this.selected_row = frappe.render_template("pos_selected_item", doc[0]) + $(this.wrapper).find('.selected-item').html(this.selected_row) + } + }, get_child_item: function(item_code) { var me = this; @@ -1011,8 +1059,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ refresh: function (update_paid_amount) { var me = this; this.refresh_fields(update_paid_amount); - this.bind_qty_event(); - this.update_rate(); + this.bind_items_event(); this.set_primary_action(); }, @@ -1056,11 +1103,11 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ $(this).select(); }); - this.wrapper.find("input.pos-item-discount").on("focus", function () { + this.wrapper.find("input.pos-item-disc").on("focus", function () { $(this).select(); }); - this.wrapper.find("input.pos-item-rate").on("focus", function () { + this.wrapper.find("input.pos-item-price").on("focus", function () { $(this).select(); }); }, @@ -1375,13 +1422,18 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ item.price_list_rate = pricing_rule[0].price || item.price_list_rate; item.margin_rate_or_amount = pricing_rule[0].margin_rate_or_amount; item.discount_percentage = pricing_rule[0].discount_percentage || 0.0; - } else if ((item.discount_percentage > 0 || item.margin_rate_or_amount > 0) && item.pricing_rule) { + me.apply_pricing_rule_on_item(item) + } else if (item.pricing_rule) { + item.price_list_rate = me.price_list_data[item.item_code] item.margin_rate_or_amount = 0.0; item.discount_percentage = 0.0; item.pricing_rule = null; + me.apply_pricing_rule_on_item(item) + } + + if(item.discount_percentage > 0) { + me.apply_pricing_rule_on_item(item) } - - me.apply_pricing_rule_on_item(item) }) }, diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css index b1f1985fd3..1db761ec79 100644 --- a/erpnext/public/css/erpnext.css +++ b/erpnext/public/css/erpnext.css @@ -85,12 +85,13 @@ } .item-cart { overflow-y: scroll; - height: calc(100vh - 60vh); + height: calc(100vh - 72vh); } .edit-pos-item { - height: 40px; + height: 50px; font-size: 14px; border-top: 1px solid #d1d8dd; + padding-top: 12px; } .pos-bill-item:hover { background-color: #f5f7fa; @@ -170,6 +171,16 @@ } .pos-keyboard-key, .delete-btn { + border: 1px solid #d1d8dd; + height: 85px; + width: 85px; + margin: 10px 10px; + font-size: 24px; + font-weight: 200; + background-color: #FDFDFD; + border-color: #e8e8e8; +} +.numeric-keypad { border: 1px solid #d1d8dd; height: 69px; width: 69px; diff --git a/erpnext/public/js/pos/pos.html b/erpnext/public/js/pos/pos.html index c6341353fa..1019647cdb 100644 --- a/erpnext/public/js/pos/pos.html +++ b/erpnext/public/js/pos/pos.html @@ -73,15 +73,15 @@ {% for(var i=0; i<3; i++) { %}
{% for(var j=i*3; j<(i+1)*3; j++) { %} - + {% } %} - +
{% } %}
- - - + + +
diff --git a/erpnext/public/js/pos/pos_bill_item.html b/erpnext/public/js/pos/pos_bill_item.html index 1a1f1e2a5b..21868a6cae 100644 --- a/erpnext/public/js/pos/pos_bill_item.html +++ b/erpnext/public/js/pos/pos_bill_item.html @@ -18,13 +18,13 @@
- +
{% if(enabled) { %} - + {% } else { %}
{%= format_currency(rate) %}
{% } %} diff --git a/erpnext/public/js/pos/pos_selected_item.html b/erpnext/public/js/pos/pos_selected_item.html index 491938e5c8..833cdd9211 100644 --- a/erpnext/public/js/pos/pos_selected_item.html +++ b/erpnext/public/js/pos/pos_selected_item.html @@ -3,25 +3,25 @@
- +
- +
- +
- +
\ No newline at end of file diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less index 34ea901650..3ad8a0b8da 100644 --- a/erpnext/public/less/erpnext.less +++ b/erpnext/public/less/erpnext.less @@ -104,13 +104,14 @@ .item-cart { overflow-y: scroll; - height: ~"calc(100vh - 60vh)"; + height: ~"calc(100vh - 72vh)"; } .edit-pos-item { - height: 40px; + height: 50px; font-size: 14px; border-top: 1px solid @border-color; + padding-top: 12px; } .pos-bill-item:hover { @@ -212,6 +213,17 @@ } .pos-keyboard-key, .delete-btn { + border: 1px solid #d1d8dd; + height:85px; + width:85px; + margin:10px 10px; + font-size:24px; + font-weight:200; + background-color: #FDFDFD; + border-color: #e8e8e8; +} + +.numeric-keypad { border: 1px solid #d1d8dd; height:69px; width:69px; From b5097ec161bdd3fcf6d83c6ec4eb0d62a7f3c231 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 1 Mar 2017 01:13:09 +0530 Subject: [PATCH 03/16] offline email for POS --- erpnext/accounts/doctype/sales_invoice/pos.py | 34 ++++++-- erpnext/accounts/page/pos/pos.js | 83 +++++++++++++++++-- erpnext/public/js/pos/pos.html | 8 +- erpnext/public/js/pos/pos_selected_item.html | 1 - 4 files changed, 110 insertions(+), 16 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py index 070dbeb2b8..476ce45a1a 100644 --- a/erpnext/accounts/doctype/sales_invoice/pos.py +++ b/erpnext/accounts/doctype/sales_invoice/pos.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import frappe, json from frappe.utils import nowdate from erpnext.setup.utils import get_exchange_rate +from frappe.core.doctype.communication.email import make from erpnext.stock.get_item_details import get_pos_profile from erpnext.accounts.party import get_party_account_currency from erpnext.controllers.accounts_controller import get_taxes_and_charges @@ -257,12 +258,14 @@ def get_pricing_rule_data(doc): return pricing_rules @frappe.whitelist() -def make_invoice(doc_list): +def make_invoice(doc_list, email_queue_list): if isinstance(doc_list, basestring): doc_list = json.loads(doc_list) - name_list = [] + if isinstance(email_queue_list, basestring): + email_queue = json.loads(email_queue_list) + name_list = [] for docs in doc_list: for name, doc in docs.items(): if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}): @@ -270,17 +273,37 @@ def make_invoice(doc_list): si_doc = frappe.new_doc('Sales Invoice') si_doc.offline_pos_name = name si_doc.update(doc) - submit_invoice(si_doc, name) + submit_invoice(si_doc, name, doc) name_list.append(name) else: name_list.append(name) - return name_list + email_queue = make_email_queue(email_queue) + return { + 'invoice': name_list, + 'email_queue': email_queue + } def validate_records(doc): validate_customer(doc) validate_item(doc) +def make_email_queue(email_queue): + name_list = [] + for key, data in email_queue.items(): + name = frappe.db.get_value('Sales Invoice', {'offline_pos_name': key}, 'name') + data = json.loads(data) + sender = frappe.session.user + print_format = "POS Invoice" + attachments = [frappe.attach_print('Sales Invoice', name, print_format= print_format)] + + make(subject = data.get('subject'), content = data.get('content'), recipients = data.get('recipients'), + sender=sender,attachments = attachments, send_email=True, + doctype='Sales Invoice', name=name) + name_list.append(key) + + return name_list + def validate_customer(doc): if not frappe.db.exists('Customer', doc.get('customer')): customer_doc = frappe.new_doc('Customer') @@ -328,7 +351,8 @@ def validate_item(doc): item_doc.save(ignore_permissions=True) frappe.db.commit() -def submit_invoice(si_doc, name): + +def submit_invoice(si_doc, name, doc): try: si_doc.insert() si_doc.submit() diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index e405ae038f..064c5f7621 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -95,11 +95,65 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ me.sync_sales_invoice() }); + this.page.add_menu_item(__("Email"), function () { + if(me.frm.doc.docstatus == 1) { + me.email_prompt() + } + }); + this.page.add_menu_item(__("POS Profile"), function () { frappe.set_route('List', 'POS Profile'); }); }, + email_prompt: function() { + var me = this; + fields = [{label:__("To"), fieldtype:"Data", reqd: 0, fieldname:"recipients",length:524288}, + {fieldtype: "Section Break", collapsible: 1, label: "CC & Standard Reply"}, + {fieldtype: "Section Break"}, + {label:__("Subject"), fieldtype:"Data", reqd: 1, + fieldname:"subject",length:524288}, + {fieldtype: "Section Break"}, + {label:__("Message"), fieldtype:"Text Editor", reqd: 1, + fieldname:"content"}, + {fieldtype: "Section Break"}, + {fieldtype: "Column Break"}]; + + this.email_dialog = new frappe.ui.Dialog({ + title: "Email", + fields: fields, + primary_action_label: __("Send"), + primary_action: function() { + me.send_action(); + } + }); + + this.email_dialog.show() + }, + + send_action: function() { + this.email_queue = this.get_email_queue() + this.email_queue[this.frm.doc.offline_pos_name] = JSON.stringify(this.email_dialog.get_values()) + this.update_email_queue() + this.email_dialog.hide() + }, + + update_email_queue: function () { + try { + localStorage.setItem('email_queue', JSON.stringify(this.email_queue)); + } catch (e) { + frappe.throw(__("LocalStorage is full , did not save")) + } + }, + + get_email_queue: function () { + try { + return JSON.parse(localStorage.getItem('email_queue')) || {}; + } catch (e) { + return {} + } + }, + dialog_actions: function () { var me = this; @@ -1282,18 +1336,22 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ sync_sales_invoice: function () { var me = this; - this.si_docs = this.get_submitted_invoice(); + this.si_docs = this.get_submitted_invoice() || []; + this.email_queue_list = this.get_email_queue() || {}; - if (this.si_docs.length) { + if (this.si_docs.length || this.email_queue_list) { frappe.call({ method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice", args: { - doc_list: me.si_docs + doc_list: me.si_docs, + email_queue_list: me.email_queue_list }, callback: function (r) { if (r.message) { - me.removed_items = r.message; + me.removed_items = r.message.invoice; + me.removed_email = r.message.email_queue me.remove_doc_from_localstorage(); + me.remove_email_queue_from_localstorage(); } } }) @@ -1323,10 +1381,10 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ var me = this; this.si_docs = this.get_doc_from_localstorage(); this.new_si_docs = []; - if (this.removed_items) { + if (this.removed_email) { $.each(this.si_docs, function (index, data) { for (key in data) { - if (!in_list(me.removed_items, key)) { + if (!in_list(me.removed_email, key)) { me.new_si_docs.push(data); } } @@ -1336,6 +1394,19 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ } }, + remove_email_queue_from_localstorage: function() { + var me = this; + this.email_queue = this.get_email_queue() + if (this.removed_email) { + $.each(this.email_queue_list, function (index, data) { + if (in_list(me.removed_email, index)) { + delete me.email_queue[index] + } + }) + this.update_email_queue(); + } + }, + validate: function () { var me = this; this.customer_validate(); diff --git a/erpnext/public/js/pos/pos.html b/erpnext/public/js/pos/pos.html index 1019647cdb..8a08a8b590 100644 --- a/erpnext/public/js/pos/pos.html +++ b/erpnext/public/js/pos/pos.html @@ -65,10 +65,10 @@
-
+
-
diff --git a/erpnext/public/js/pos/pos_selected_item.html b/erpnext/public/js/pos/pos_selected_item.html index 833cdd9211..4260cf7c8d 100644 --- a/erpnext/public/js/pos/pos_selected_item.html +++ b/erpnext/public/js/pos/pos_selected_item.html @@ -1,4 +1,3 @@ -
Item {%= item_name %}
From 1f261a8695b7ba5329ce475b132638edbfcf4128 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 6 Mar 2017 18:01:58 +0530 Subject: [PATCH 04/16] UI changes --- erpnext/accounts/page/pos/pos.js | 54 +++-- erpnext/public/build.json | 2 + erpnext/public/css/erpnext.css | 127 +++++++----- erpnext/public/js/pos/customer_toolbar.html | 12 ++ erpnext/public/js/pos/pos.html | 206 ++++++++++--------- erpnext/public/js/pos/pos_bill_item_new.html | 9 + erpnext/public/js/pos/pos_item.html | 39 +++- erpnext/public/js/pos/pos_selected_item.html | 37 ++-- erpnext/public/less/erpnext.less | 171 +++++++++++---- 9 files changed, 413 insertions(+), 244 deletions(-) create mode 100644 erpnext/public/js/pos/customer_toolbar.html create mode 100644 erpnext/public/js/pos/pos_bill_item_new.html diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index 064c5f7621..862b98744e 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -142,7 +142,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ try { localStorage.setItem('email_queue', JSON.stringify(this.email_queue)); } catch (e) { - frappe.throw(__("LocalStorage is full , did not save")) + frappe.throw(__("LocalStorage is full, did not save")) } }, @@ -401,21 +401,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ me.make_item_list(); }); - this.party_field = frappe.ui.form.make_control({ - df: { - "fieldtype": "Data", - "options": this.party, - "label": this.party, - "fieldname": this.party.toLowerCase(), - "placeholder": __("Select or add new customer") - }, - parent: this.wrapper.find(".party-area"), - only_input: true, - }); - - this.party_field.make_input(); - setTimeout(this.set_focus.bind(this), 500); - this.wrapper.find(".btn-more").on("click", function() { me.page_len += 20; me.items = me.get_items(); @@ -585,6 +570,25 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ make_customer: function () { var me = this; + $(frappe.render_template('customer_toolbar', { + allow_delete: this.frm.doc.allow_delete + })).insertAfter(this.page.$title_area.hide()); + + this.party_field = frappe.ui.form.make_control({ + df: { + "fieldtype": "Data", + "options": this.party, + "label": this.party, + "fieldname": this.party.toLowerCase(), + "placeholder": __("Select or add new customer") + }, + parent: this.page.wrapper.find(".party-area"), + only_input: true, + }); + + this.party_field.make_input(); + setTimeout(this.set_focus.bind(this), 500); + if (this.default_customer && !this.frm.doc.customer) { this.party_field.$input.val(this.default_customer); this.frm.doc.customer = this.default_customer; @@ -793,12 +797,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ if (this.items.length > 0) { $.each(this.items, function(index, obj) { - if(index < me.page_len){ + if(index < me.page_len) { $(frappe.render_template("pos_item", { item_code: obj.name, item_price: format_currency(me.price_list_data[obj.name], me.frm.doc.currency), item_name: obj.name === obj.item_name ? "" : obj.item_name, - item_image: obj.image ? "url('" + obj.image + "')" : null, + item_image: obj.image, color: frappe.get_palette(obj.item_name), abbr: frappe.get_abbr(obj.item_name) })).tooltip().appendTo($wrap); @@ -816,7 +820,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ } // if form is local then allow this function - $(me.wrapper).find("div.pos-item").on("click", function () { + $(me.wrapper).on("click", ".pos-item-wrapper", function () { if(me.list_customers_btn.hasClass("view_customer")) return; me.customer_validate(); @@ -889,7 +893,9 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ bind_items_event: function() { var me = this; - $(this.wrapper).find(".pos-bill-item").click(function() { + $(this.wrapper).on('click', '.pos-bill-item', function() { + $(me.wrapper).find('.pos-bill-item').removeClass('active'); + $(this).addClass('active'); me.numeric_val = ""; me.numeric_id = "" me.item_code = $(this).attr("data-item-code"); @@ -1139,8 +1145,14 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ show_items_in_item_cart: function () { var me = this; var $items = this.wrapper.find(".items").empty(); + var $no_items_message = this.wrapper.find(".no-items-message"); + $no_items_message.toggle(this.frm.doc.items.length === 0); + + var $totals_area = this.wrapper.find('.totals-area'); + $totals_area.toggle(this.frm.doc.items.length > 0); + $.each(this.frm.doc.items || [], function (i, d) { - $(frappe.render_template("pos_bill_item", { + $(frappe.render_template("pos_bill_item_new", { item_code: d.item_code, item_name: (d.item_name === d.item_code || !d.item_name) ? "" : ("
" + d.item_name), qty: d.qty, diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 858514edfe..393e90c052 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -20,9 +20,11 @@ "public/js/controllers/transaction.js", "public/js/pos/pos.html", "public/js/pos/pos_bill_item.html", + "public/js/pos/pos_bill_item_new.html", "public/js/pos/pos_selected_item.html", "public/js/pos/pos_item.html", "public/js/pos/pos_tax_row.html", + "public/js/pos/customer_toolbar.html", "public/js/pos/pos_invoice_list.html", "public/js/payment/pos_payment.html", "public/js/payment/payment_details.html", diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css index 1db761ec79..838d2604e4 100644 --- a/erpnext/public/css/erpnext.css +++ b/erpnext/public/css/erpnext.css @@ -13,9 +13,6 @@ margin: -10px auto; } /* pos */ -.pos-item-area { - padding: 0px 10px; -} .pos-item-wrapper { padding: 5px; } @@ -51,20 +48,11 @@ background-position: center; background-repeat: no-repeat; } -.pos-item-area { - border: 1px solid #d1d8dd; - border-top: none; -} .pos-item-toolbar { + height: 51px; padding: 10px 0px; border-bottom: 1px solid #d1d8dd; } -.item-list-area, -.list-customers { - padding: 15px 0px; - overflow-y: scroll; - height: calc(100vh - 162px); -} .pos-toolbar, .pos-bill-toolbar { padding: 10px 0px; @@ -73,20 +61,6 @@ .pos-item-toolbar .form-group { margin-bottom: 0px; } -.pos-bill-wrapper { - border: 1px solid #d1d8dd; - border-top: none; - margin-right: -1px; -} -.pos-bill { - border-top: 1px solid #d1d8dd; - margin-left: -15px; - margin-right: -15px; -} -.item-cart { - overflow-y: scroll; - height: calc(100vh - 72vh); -} .edit-pos-item { height: 50px; font-size: 14px; @@ -97,15 +71,6 @@ background-color: #f5f7fa; cursor: pointer; } -.pos-bill-row { - margin: 0px; - padding: 7px 0px; - border-top: 1px solid #d1d8dd; -} -.pos-bill-header { - border: none !important; - background-color: #f5f7fa; -} .pos-item-qty { display: inline-block; } @@ -181,21 +146,31 @@ border-color: #e8e8e8; } .numeric-keypad { - border: 1px solid #d1d8dd; - height: 69px; - width: 69px; + height: 60px; + width: 60px; font-size: 20px; font-weight: 200; - background-color: #FDFDFD; - border-color: #e8e8e8; + border-radius: 0; + background-color: #fff; margin-left: -4px; } +.numeric_keypad { + margin-left: -15px; +} +.numeric_keypad > .row > button { + border: none; + border-right: 1px solid #d1d8dd; + border-bottom: 1px solid #d1d8dd; +} +.numeric_keypad > .row > button:first-child { + border-left: 1px solid #d1d8dd; +} +.numeric_keypad > .row:first-child > button { + border-top: 1px solid #d1d8dd; +} .pos-pay { - height: 69px; - width: 69px; - font-size: 17px; - font-weight: 200; - margin-left: -4px; + background-color: #5E64FF; + border: none; } .multimode-payments { padding-left: 30px; @@ -269,3 +244,63 @@ body[data-route="pos"] .modal-dialog { .assessment-result-tool .score { text-align: right; } +.pos-list-row { + display: table; + table-layout: fixed; + width: 100%; + padding: 9px 15px; + font-size: 12px; + margin: 0px; + border-bottom: 1px solid #d1d8dd; +} +.pos-list-row .cell { + display: table-cell; + vertical-align: middle; +} +.pos-list-row .subject { + width: 50%; +} +.pos-list-row .list-row-checkbox, +.pos-list-row .list-select-all { + margin-right: 7px; +} +.pos-bill-header { + background-color: #f5f7fa; + border: 1px solid #d1d8dd; +} +.pos-bill-item.active { + background-color: #fffce7; +} +.totals-area { + border-right: 1px solid #d1d8dd; + border-left: 1px solid #d1d8dd; + margin-bottom: 15px; +} +body[data-route="pos"] .page-body { + height: calc(100vh - 40px); +} +.item-cart-items { + height: 30vh; + overflow: auto; + border: 1px solid #d1d8dd; + border-top: none; +} +.item-cart-items .no-items-message { + display: flex; + align-items: center; + justify-content: center; + height: 100%; +} +.pos .items .pos-list-row:last-child { + border-bottom: none; +} +.pos .form-section-heading { + padding: 0; +} +.pos { + overflow: hidden; +} +.pos .item-list { + border-left: 1px solid #d1d8dd; + border-right: 1px solid #d1d8dd; +} diff --git a/erpnext/public/js/pos/customer_toolbar.html b/erpnext/public/js/pos/customer_toolbar.html new file mode 100644 index 0000000000..a32c157220 --- /dev/null +++ b/erpnext/public/js/pos/customer_toolbar.html @@ -0,0 +1,12 @@ +
+
+ + {% if (allow_delete) { %} + {% } %} +
\ No newline at end of file diff --git a/erpnext/public/js/pos/pos.html b/erpnext/public/js/pos/pos.html index 8a08a8b590..17d1a5fd91 100644 --- a/erpnext/public/js/pos/pos.html +++ b/erpnext/public/js/pos/pos.html @@ -1,109 +1,111 @@
-
-
-
-
- - - {% if (allow_delete) { %} - - {% } %} -
-
-
- -
-
-
-
-
{%= __("Net Total") %}
-
-
-
-
-
{%= __("Taxes") %}
-
-
-
- {% if (apply_discount_on) { %} -
-
{%= __("Discount") %}
-
-
- % - -
-
-
-
- {%= get_currency_symbol(currency) %} - -
-
-
- {% } %} -
-
{%= __("Grand Total") %}
-
-
-
-
- - -
-
- -
-