diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json index a25dd5198d..9232cd3a16 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.json +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "autoname": "hash", @@ -21,7 +22,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Applicable for User", "length": 0, "no_copy": 0, @@ -50,7 +53,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Series", "length": 0, "no_copy": 1, @@ -81,7 +86,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Update Stock", "length": 0, "no_copy": 0, @@ -108,7 +115,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Warehouse", "length": 0, "no_copy": 0, @@ -137,7 +146,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Campaign", "length": 0, "no_copy": 0, @@ -165,7 +176,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -191,7 +204,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Customer", "length": 0, "no_copy": 0, @@ -220,7 +235,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Company", "length": 0, "no_copy": 0, @@ -238,6 +255,36 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "country", + "fieldtype": "Read Only", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Country", + "length": 0, + "no_copy": 0, + "options": "company.country", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -249,7 +296,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Currency", "length": 0, "no_copy": 0, @@ -278,7 +327,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Ignore Pricing Rule", "length": 0, "no_copy": 0, @@ -305,7 +356,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Allow Delete", "length": 0, "no_copy": 0, @@ -332,7 +385,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Allow user to edit Rate", "length": 0, "no_copy": 0, @@ -359,7 +414,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -385,7 +442,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Sales Invoice Payment", "length": 0, "no_copy": 0, @@ -413,7 +472,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -439,7 +500,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Item Groups", "length": 0, "no_copy": 0, @@ -467,7 +530,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -493,7 +558,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Customer Groups", "length": 0, "no_copy": 0, @@ -521,7 +588,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -548,7 +617,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Print Format", "length": 0, "no_copy": 0, @@ -576,7 +647,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Letter Head", "length": 0, "no_copy": 0, @@ -605,7 +678,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Print Heading", "length": 0, "no_copy": 0, @@ -634,7 +709,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Terms and Conditions", "length": 0, "no_copy": 0, @@ -663,7 +740,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "oldfieldtype": "Column Break", @@ -690,7 +769,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Territory", "length": 0, "no_copy": 0, @@ -719,7 +800,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Price List", "length": 0, "no_copy": 0, @@ -748,7 +831,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Apply Discount", "length": 0, "no_copy": 0, @@ -777,7 +862,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Apply Discount On", "length": 0, "no_copy": 0, @@ -805,7 +892,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -832,7 +921,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Write Off Account", "length": 0, "no_copy": 0, @@ -860,7 +951,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Write Off Cost Center", "length": 0, "no_copy": 0, @@ -888,7 +981,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Account for Change Amount", "length": 0, "no_copy": 0, @@ -916,7 +1011,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Taxes and Charges", "length": 0, "no_copy": 0, @@ -945,7 +1042,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -971,7 +1070,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Income Account", "length": 0, "no_copy": 0, @@ -1001,7 +1102,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Expense Account", "length": 0, "no_copy": 0, @@ -1028,7 +1131,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Cost Center", "length": 0, "no_copy": 0, @@ -1047,18 +1152,18 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "icon-cog", "idx": 1, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-12-28 15:14:59.411457", + "modified": "2017-03-10 16:53:56.390210", "modified_by": "rohit@erpnext.com", "module": "Accounts", "name": "POS Profile", @@ -1074,7 +1179,6 @@ "export": 0, "if_owner": 0, "import": 0, - "is_custom": 0, "permlevel": 0, "print": 1, "read": 1, @@ -1095,7 +1199,6 @@ "export": 0, "if_owner": 0, "import": 0, - "is_custom": 0, "permlevel": 0, "print": 1, "read": 1, @@ -1110,8 +1213,10 @@ "quick_entry": 0, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", "title_field": "user", + "track_changes": 0, "track_seen": 0 } \ No newline at end of file diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py index 070dbeb2b8..cfbd1b2087 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 @@ -25,13 +26,15 @@ def get_pos_data(): update_multi_mode_option(doc, pos_profile) default_print_format = pos_profile.get('print_format') or "Point of Sale" print_template = frappe.db.get_value('Print Format', default_print_format, 'html') + customers = get_customers_list(pos_profile) return { 'doc': doc, 'default_customer': pos_profile.get('customer'), 'items': get_items_list(pos_profile), 'item_groups': get_item_group(pos_profile), - 'customers': get_customers_list(pos_profile), + 'customers': customers, + 'address': get_customers_address(customers), 'serial_no_data': get_serial_no_data(pos_profile, doc.company), 'batch_no_data': get_batch_no_data(), 'tax_data': get_item_tax_data(), @@ -60,6 +63,8 @@ def get_company_data(company): def update_pos_profile_data(doc, pos_profile, company_data): doc.campaign = pos_profile.get('campaign') + if not pos_profile.get('country'): + pos_profile["country"] = company_data.country doc.write_off_account = pos_profile.get('write_off_account') or \ company_data.write_off_account @@ -163,6 +168,19 @@ def get_customers_list(pos_profile): territory from tabCustomer where disabled = 0 and {cond}""".format(cond=cond), tuple(customer_groups), as_dict=1) or {} +def get_customers_address(customers): + customer_address = {} + for data in customers: + address = frappe.db.sql(""" select name, address_line1, address_line2, city, state, + email_id, phone, fax, pincode from `tabAddress` where is_primary_address =1 and name in + (select parent from `tabDynamic Link` where link_doctype = 'Customer' and link_name = %s + and parenttype = 'Address')""", data.name, as_dict=1) + if address: + address_data = address[0] + address_data.update({'full_name': data.customer_name}) + customer_address[data.name] = address_data + return customer_address + 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 @@ -257,12 +275,18 @@ def get_pricing_rule_data(doc): return pricing_rules @frappe.whitelist() -def make_invoice(doc_list): +def make_invoice(doc_list={}, email_queue_list={}, customers_list={}): if isinstance(doc_list, basestring): doc_list = json.loads(doc_list) - name_list = [] + if isinstance(email_queue_list, basestring): + email_queue_list = json.loads(email_queue_list) + if isinstance(customers_list, basestring): + customers_list = json.loads(customers_list) + + customers = make_customer_and_address(customers_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,49 +294,72 @@ 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_list) + return { + 'invoice': name_list, + 'email_queue': email_queue, + 'customers': customers + } def validate_records(doc): - validate_customer(doc) validate_item(doc) -def validate_customer(doc): - if not frappe.db.exists('Customer', doc.get('customer')): - customer_doc = frappe.new_doc('Customer') - customer_doc.customer_name = doc.get('customer') - customer_doc.customer_type = 'Company' - customer_doc.customer_group = frappe.db.get_single_value('Selling Settings', 'customer_group') - customer_doc.territory = frappe.db.get_single_value('Selling Settings', 'territory') - customer_doc.flags.ignore_mandatory = True - customer_doc.save(ignore_permissions = True) - frappe.db.commit() - doc['customer'] = customer_doc.name - if doc.get('contact_details'): - args = json.loads(doc.get("contact_details")) - make_address(doc, args, customer_doc.name) +def make_customer_and_address(customers): + customer_list = [] + for name, data in customers.items(): + if not frappe.db.exists('Customer', name): + name = add_customer(name) + data = json.loads(data) + make_address(data, name) + customer_list.append(name) + return customer_list -def make_address(doc, args, customer): - if args.get("address_line1"): +def add_customer(name): + customer_doc = frappe.new_doc('Customer') + customer_doc.customer_name = name + customer_doc.customer_type = 'Company' + customer_doc.customer_group = frappe.db.get_single_value('Selling Settings', 'customer_group') + customer_doc.territory = frappe.db.get_single_value('Selling Settings', 'territory') + customer_doc.flags.ignore_mandatory = True + customer_doc.save(ignore_permissions = True) + frappe.db.commit() + +def make_address(args, customer): + if args.get('name'): + address = frappe.get_doc('Address', args.get('name')) + else: address = frappe.new_doc('Address') - address.address_line1 = args.get('address_line1') - address.address_line2 = args.get('address_line2') - address.city = args.get('city') - address.state = args.get('state') - address.zip_code = args.get('zip_code') - address.email_id = args.get('email_id') - address.flags.ignore_mandatory = True - address.country = frappe.db.get_value('Company', doc.get('company'), 'country') + address.country = frappe.db.get_value('Company', args.get('company'), 'country') address.append('links',{ 'link_doctype': 'Customer', 'link_name': customer }) - address.save(ignore_permissions = True) - frappe.db.commit() + + address.is_primary_address = 1 + address.is_shipping_address = 1 + address.update(args) + address.save(ignore_permissions = True) + +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_item(doc): for item in doc.get('items'): @@ -328,7 +375,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/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 3dfe680883..f3d311b56d 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -558,7 +558,7 @@ class TestSalesInvoice(unittest.TestCase): {'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 330}] invoice_data = [{'09052016142': pos}] - si = make_invoice(invoice_data) + si = make_invoice(invoice_data).get('invoice') self.assertEquals(si[0], '09052016142') sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': '09052016142', 'docstatus': 1}) diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index ed54ab400e..b86f9e15bb 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -25,6 +25,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.set_indicator(); this.onload(); this.make_menu_list(); + this.bind_events(); this.si_docs = this.get_doc_from_localstorage(); }, @@ -95,19 +96,76 @@ 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 {} + } + }, + + get_customers_details: function () { + try { + return JSON.parse(localStorage.getItem('customer_details')) || {}; + } catch (e) { + return {} + } + }, + dialog_actions: function () { var me = this; - $(this.list_body).find('.list-column').click(function () { - me.name = $(this).parents().attr('invoice-name') - me.edit_record(); - }) - $(this.list_body).find('.list-select-all').click(function () { me.removed_items = []; $(me.list_body).find('.list-delete').prop("checked", $(this).is(":checked")) @@ -119,7 +177,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }) } - me.toggle_primary_action(); + me.toggle_delete_button(); }) $(this.list_body).find('.list-delete').click(function () { @@ -130,7 +188,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ me.removed_items.pop(me.name) } - me.toggle_primary_action(); + me.toggle_delete_button(); }) }, @@ -142,26 +200,39 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.frm.doc = doc_data[0][this.name]; this.set_missing_values(); this.refresh(false); - this.disable_input_field(); + this.toggle_input_field(); this.list_dialog && this.list_dialog.hide(); } }, delete_records: function () { var me = this; + this.validate_list() this.remove_doc_from_localstorage() this.update_localstorage(); - this.dialog_actions(); - this.toggle_primary_action(); + // this.dialog_actions(); + this.toggle_delete_button(); }, - toggle_primary_action: function () { + validate_list: function() { var me = this; - if(this.frm.doc.allow_delete) { + this.si_docs = this.get_submitted_invoice() + $.each(this.removed_items, function(index, name){ + $.each(me.si_docs, function(key, data){ + if(me.si_docs[key][name] && me.si_docs[key][name].offline_pos_name == name ){ + frappe.throw(__("Submitted orders can not be deleted")) + } + }) + }) + }, + + toggle_delete_button: function () { + var me = this; + if(this.pos_profile_data["allow_delete"]) { if (this.removed_items && this.removed_items.length > 0) { - $(this.wrapper).find('.btn-danger').show(); + $(this.page.wrapper).find('.btn-danger').show(); } else { - $(this.wrapper).find('.btn-danger').hide(); + $(this.page.wrapper).find('.btn-danger').hide(); } } }, @@ -215,8 +286,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ freeze: true, freeze_message: __("Master data syncing, it might take some time"), callback: function (r) { - me.init_master_data(r) localStorage.setItem('doc', JSON.stringify(r.message.doc)); + me.init_master_data(r) me.set_interval_for_si_sync(); me.check_internet_connection(); if (callback) { @@ -228,6 +299,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ init_master_data: function (r) { var me = this; + this.doc = JSON.parse(localStorage.getItem('doc')); this.meta = r.message.meta; this.item_data = r.message.items; this.item_groups = r.message.item_groups; @@ -235,6 +307,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.serial_no_data = r.message.serial_no_data; this.batch_no_data = r.message.batch_no_data; this.tax_data = r.message.tax_data; + this.address = r.message.address || {}; this.price_list_data = r.message.price_list_data; this.bin_data = r.message.bin_data; this.pricing_rules = r.message.pricing_rules; @@ -243,6 +316,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.default_customer = r.message.default_customer || null; this.print_settings = locals[":Print Settings"]["Print Settings"]; this.letter_head = (this.pos_profile_data.length > 0) ? frappe.boot.letter_heads[this.pos_profile_data[letter_head]] : {}; + this.make_control() }, save_previous_entry: function () { @@ -282,11 +356,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }, setup: function () { - this.frm.doc.allow_delete = this.pos_profile_data["allow_delete"]; - this.wrapper.html(frappe.render_template("pos", this.frm.doc)); - this.set_transaction_defaults("Customer"); this.make(); this.set_primary_action(); + this.party_field.$input.attr('disabled', false); + if(this.selected_row) { + this.selected_row.hide() + } }, set_transaction_defaults: function (party) { @@ -299,12 +374,20 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }, make: function () { - this.make_search(); - this.make_list_customers(); - this.make_customer(); this.make_item_list(); this.make_discount_field() }, + + make_control: function() { + this.frm = {} + this.frm.doc = this.doc + this.set_transaction_defaults("Customer"); + this.wrapper.html(frappe.render_template("pos", this.frm.doc)); + this.make_search(); + this.make_customer(); + this.make_list_customers(); + this.bind_numeric_keypad(); + }, make_search: function () { var me = this; @@ -327,68 +410,98 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }, 1000); }); - this.search_item_group = frappe.ui.form.make_control({ - df: { - "fieldtype": "Select", - "options": me.item_groups, - "label": __("Item Group"), - "fieldname": "item_group", - "placeholder": __("Item Group") - }, - parent: this.wrapper.find(".search-item-group"), - only_input: true, - }); + this.search_item_group = this.wrapper.find('.search-item-group'); + + var dropdown_html = me.item_groups.map(function(item_group) { + return "
  • "+item_group+"
  • "; + }).join(""); + + this.search_item_group.find('.dropdown-menu').html(dropdown_html); + + this.search_item_group.on('click', '.dropdown-menu a', function() { + me.selected_item_group = $(this).attr('data-value'); + me.search_item_group.find('.dropdown-text').text(me.selected_item_group); - this.search_item_group.make_input(); - this.search_item_group.$input.on("change", function () { me.page_len = 20; me.items = me.get_items(); 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, - }); + me.toggle_more_btn(); - this.party_field.make_input(); - setTimeout(this.set_focus.bind(this), 500); - - this.wrapper.find(".btn-more").on("click", function() { + this.wrapper.on("click", ".btn-more", function() { me.page_len += 20; me.items = me.get_items(); me.make_item_list(); + me.toggle_more_btn(); + }); + + this.page.wrapper.on("click", ".edit-customer-btn", function() { + me.update_customer() }) }, + toggle_more_btn: function() { + if(!this.items || this.items.length <= this.page_len) { + this.wrapper.find(".btn-more").hide(); + } else { + this.wrapper.find(".btn-more").show(); + } + }, + + toggle_totals_area: function(show) { + + if(show === undefined) { + show = this.is_totals_area_collapsed; + } + + var totals_area = this.wrapper.find('.totals-area'); + totals_area.find('.net-total-area, .tax-area, .discount-amount-area') + .toggle(show); + + if(show) { + totals_area.find('.collapse-btn i') + .removeClass('octicon-chevron-down') + .addClass('octicon-chevron-up'); + } else { + totals_area.find('.collapse-btn i') + .removeClass('octicon-chevron-up') + .addClass('octicon-chevron-down'); + } + + this.is_totals_area_collapsed = !show; + }, + make_list_customers: function () { var me = this; - this.list_customers_btn = this.wrapper.find('.list-customers-btn'); + this.list_customers_btn = this.page.wrapper.find('.list-customers-btn'); this.add_customer_btn = this.wrapper.find('.add-customer-btn'); - this.pos_bill = this.wrapper.find('.pos-bill').hide(); + this.pos_bill = this.wrapper.find('.pos-bill-wrapper').hide(); this.list_customers = this.wrapper.find('.list-customers'); + this.numeric_keypad = this.wrapper.find('.numeric_keypad'); - this.list_customers_btn.on('click', function () { + me.render_list_customers(); + me.toggle_totals_area(false); + + this.page.wrapper.on('click', '.list-customers-btn', function() { $(this).toggleClass("view_customer"); if($(this).hasClass("view_customer")) { me.render_list_customers(); - me.bind_delete_event() - me.party_field.$input.attr('disabled', true); me.list_customers.show(); me.pos_bill.hide(); + me.numeric_keypad.hide(); + me.toggle_delete_button() } else { if(me.frm.doc.docstatus == 0) { me.party_field.$input.attr('disabled', false); } me.pos_bill.show(); - me.list_customers.hide() + me.toggle_totals_area(false); + me.toggle_delete_button() + me.list_customers.hide(); + if(me.frm.doc.items.length > 0) { + me.numeric_keypad.show(); + } } }); this.add_customer_btn.on('click', function() { @@ -397,44 +510,86 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ me.refresh(); me.set_focus(); }); + this.pos_bill.on('click', '.collapse-btn', function() { + me.toggle_totals_area(); + }); + }, + + 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.numeric_id) { + me.selected_field = $(me.wrapper).find('.selected-item').find('.' + me.numeric_id) + } + + if(me.val && 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() + } + + if(me.numeric_id && $(this).hasClass('pos-operation')) { + me.numeric_keypad.find('button.pos-operation').removeClass('active'); + $(this).addClass('active'); + + me.selected_row.find('.pos-list-row').removeClass('active'); + me.selected_field.closest('.pos-list-row').addClass('active'); + } + }) + + $(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; this.removed_items = []; - this.list_customers.empty(); + // this.list_customers.empty(); this.si_docs = this.get_doc_from_localstorage(); - if (!this.si_docs.length) { - this.list_customers.append( - '
    ' + __("No offline records.") + '
    ' - ) return; } - var html = '
    \ -
    \ -
    Customer
    \ -
    Status
    \ -
    Paid Amount
    \ -
    Grand Total
    \ -
    '; - this.si_docs.forEach(function (data, i) { - for (key in data) { - html += frappe.render_template("pos_invoice_list", { - sr: i + 1, - name: key, - customer: data[key].customer, - paid_amount: format_currency(data[key].paid_amount, me.frm.doc.currency), - grand_total: format_currency(data[key].grand_total, me.frm.doc.currency), - data: me.get_doctype_status(data[key]) - }); - } - }); - this.list_customers.append(html); - this.list_customers.find('.list-column').click(function () { + var html = ""; + if(this.si_docs.length) { + this.si_docs.forEach(function (data, i) { + for (key in data) { + html += frappe.render_template("pos_invoice_list", { + sr: i + 1, + name: key, + customer: data[key].customer, + paid_amount: format_currency(data[key].paid_amount, me.frm.doc.currency), + grand_total: format_currency(data[key].grand_total, me.frm.doc.currency), + data: me.get_doctype_status(data[key]) + }); + } + }); + } + this.list_customers.find('.list-customers-table').html(html); + + this.list_customers.on('click', '.customer-row', function () { me.list_customers.hide(); + me.numeric_keypad.show(); me.list_customers_btn.toggleClass("view_customer"); me.pos_bill.show(); me.list_customers_btn.show(); @@ -454,7 +609,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }); } - me.toggle_primary_action(); + me.toggle_delete_button(); }); $(this.wrapper).find('.list-delete').click(function () { @@ -465,16 +620,17 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ me.removed_items.pop(me.name) } - me.toggle_primary_action(); + me.toggle_delete_button(); }); }, bind_delete_event: function() { var me = this; - $(this.wrapper).find('.btn-danger').click(function(){ + $(this.page.wrapper).on('click', '.btn-danger', function(){ frappe.confirm(__("Delete permanently?"), function () { me.delete_records(); + me.list_customers.find('.list-customers-table').html(""); me.render_list_customers(); }) }) @@ -491,6 +647,30 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ make_customer: function () { var me = this; + if(!this.party_field) { + if(this.page.wrapper.find('.pos-bill-toolbar').length === 0) { + $(frappe.render_template('customer_toolbar', { + allow_delete: this.pos_profile_data["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); + me.toggle_delete_button(); + } + if (this.default_customer && !this.frm.doc.customer) { this.party_field.$input.val(this.default_customer); this.frm.doc.customer = this.default_customer; @@ -533,7 +713,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ + __("Create a new Customer") + "", value: 'is_action', - action: me.new_customer + action: me.add_customer }); this.party_field.awesomeplete.list = customers; @@ -550,17 +730,23 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ customer.action.apply(me); return; } + me.toggle_list_customer(false); + me.toggle_edit_button(true); me.update_customer_data(customer); me.refresh(); me.set_focus(); }) - .on('change', function (e) { - if (!e.originalEvent.text) { - me.frm.doc.customer = $(this).val(); - } - }) .on('focus', function (e) { $(e.target).val('').trigger('input'); + me.toggle_edit_button(false); + + if(me.frm.doc.items.length) { + me.toggle_list_customer(false) + me.toggle_item_cart(true) + } else { + me.toggle_list_customer(true) + me.toggle_item_cart(false) + } }) .on("awesomplete-selectcomplete", function (e) { var item = me.party_field.awesomeplete @@ -572,7 +758,24 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }); }, - new_customer: function () { + toggle_edit_button: function(flag) { + this.page.wrapper.find('.edit-customer-btn').toggle(flag); + }, + + toggle_list_customer: function(flag) { + this.list_customers.toggle(flag); + }, + + toggle_item_cart: function(flag) { + this.wrapper.find('.pos-bill-wrapper').toggle(flag); + }, + + add_customer: function() { + this.frm.doc.customer = ""; + this.update_customer() + }, + + update_customer: function () { var me = this; if (!this.connection_status) return; @@ -598,12 +801,18 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }, { "label": __("Contact Number"), - "fieldname": "contact_no", + "fieldname": "phone", "fieldtype": "Data" }, { "fieldtype": "Section Break" }, + { + "label": __("Address Name"), + "read_only": 1, + "fieldname": "name", + "fieldtype": "Data" + }, { "label": __("Address Line 1"), "fieldname": "address_line1", @@ -629,13 +838,14 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }, { "label": __("ZIP Code"), - "fieldname": "zip_code", + "fieldname": "pincode", "fieldtype": "Data" } ] }) this.customer_doc.show() + this.render_address_data() this.customer_doc.set_primary_action(__("Save"), function () { me.make_offline_customer(); @@ -643,18 +853,41 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }); }, + render_address_data: function() { + var me = this; + this.address_data = this.address[this.frm.doc.customer] || this.get_address_from_localstorage(); + this.customer_doc.set_values(this.address_data) + + if(!this.customer_doc.fields_dict.full_name.$input.val()) { + this.customer_doc.set_value("full_name", this.frm.doc.customer) + } + }, + + get_address_from_localstorage: function() { + this.address_details = this.get_customers_details() + return this.address_details[this.frm.doc.customer] + }, + make_offline_customer: function() { - this.frm.doc.customer = this.customer_doc.get_values().full_name; - this.frm.doc.contact_details = JSON.stringify(this.customer_doc.get_values()); + this.frm.doc.customer = this.frm.doc.customer || this.customer_doc.get_values().full_name; + this.customer_details = this.get_customers_details(); + this.customer_details[this.frm.doc.customer] = this.get_prompt_details(); this.party_field.$input.val(this.frm.doc.customer); this.customers.push({ name: this.frm.doc.customer, customer_name: this.frm.doc.customer }); - + this.update_customer_in_localstorage() + this.update_customer_in_localstorage() this.customer_doc.hide() }, + get_prompt_details: function() { + this.prompt_details = this.customer_doc.get_values(); + this.prompt_details['country'] = this.pos_profile_data.country; + return JSON.stringify(this.prompt_details) + }, + update_customer_data: function (doc) { var me = this; this.frm.doc.customer = doc.label || doc.name; @@ -662,6 +895,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) { @@ -698,17 +932,28 @@ 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); } }); + + $wrap.append(` +
    +
    + +
    Load more items
    +
    +
    + `); + + me.toggle_more_btn(); } else { $("

    " +__("Not items found")+"

    ").appendTo($wrap) @@ -719,17 +964,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.serach_item.$input.val(""); this.add_to_cart(); } - - // if form is local then allow this function - $(me.wrapper).find("div.pos-item").on("click", function () { - if(me.list_customers_btn.hasClass("view_customer")) return; - - me.customer_validate(); - if (me.frm.doc.docstatus == 0) { - me.items = me.get_items($(this).attr("data-item-code")) - me.add_to_cart(); - } - }); }, get_items: function (item_code) { @@ -781,7 +1015,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ apply_category: function() { var me = this; - category = this.search_item_group.$input.val(); + category = this.selected_item_group || "All Item Groups"; if(category == 'All Item Groups') { return this.item_data @@ -791,14 +1025,30 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }); } }, + + bind_items_event: function() { + var me = this; + $(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"); + 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 () { - var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); + + $(this.wrapper).on("change", ".pos-item-qty", function () { + var item_code = $(this).parents(".pos-selected-item-action").attr("data-item-code"); var qty = $(this).val(); me.update_qty(item_code, qty) + me.render_selected_item() }) $(this.wrapper).find("[data-action='increase-qty']").on("click", function () { @@ -812,14 +1062,32 @@ 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 () { - var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); + + $(this.wrapper).on("change", ".pos-item-disc", function () { + var item_code = $(this).parents(".pos-selected-item-action").attr("data-item-code"); var discount = $(this).val(); me.update_discount(item_code, discount) + me.render_selected_item() }) }, + bind_events: function() { + var me = this; + // if form is local then allow this function + // $(me.wrapper).find(".pos-item-wrapper").on("click", function () { + $(this.wrapper).on("click", ".pos-item-wrapper", function () { + if(me.list_customers_btn.hasClass("view_customer")) return; + + me.customer_validate(); + if (me.frm.doc.docstatus == 0) { + me.items = me.get_items($(this).attr("data-item-code")) + me.add_to_cart(); + } + }); + + me.bind_delete_event() + }, + update_qty: function (item_code, qty) { var me = this; this.items = this.get_items(item_code); @@ -835,13 +1103,30 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ update_rate: function () { var me = this; - - $(this.wrapper).find(".pos-item-rate").on("change", function () { - var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); + $(this.wrapper).on("change", ".pos-item-price", function () { + var item_code = $(this).parents(".pos-selected-item-action").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; + 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; if (value < 0) { @@ -874,7 +1159,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ var me = this; idx = 0 this.items = [] - idx = 0 $.each(this.frm.doc["items"] || [], function (i, d) { if (!in_list(me.remove_item, d.idx)) { d.idx = idx; @@ -950,6 +1234,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-items").scrollTop(1000); }, add_new_item_to_grid: function () { @@ -959,6 +1244,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; @@ -986,8 +1272,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(); }, @@ -1013,8 +1298,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, @@ -1031,11 +1322,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(); }); }, @@ -1068,33 +1359,31 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ set_primary_action: function () { var me = this; + this.page.set_primary_action(__("New Cart"), function () { + me.make_new_cart() + }, "fa fa-plus") - if (this.frm.doc.docstatus == 0) { - this.page.set_primary_action(__("Pay"), function () { - me.validate(); - me.update_paid_amount_status(true); - me.create_invoice(); - me.make_payment(); - }, "fa fa-credit-card"); - } else if (this.frm.doc.docstatus == 1) { - this.page.set_primary_action(__("Print"), function () { + if (this.frm.doc.docstatus == 1) { + this.page.set_secondary_action(__("Print"), function () { html = frappe.render(me.print_template_data, me.frm.doc) me.print_document(html) }) - } else { - this.page.clear_primary_action() } + }, - // this.page.set_secondary_action(__("New"), function () { - // me.save_previous_entry(); - // me.create_new(); - // }, "fa fa-plus").addClass("btn-primary"); + make_new_cart: function (){ + this.save_previous_entry(); + this.create_new(); + this.refresh(); + this.toggle_input_field(); + this.render_list_customers(); + this.set_focus(); }, print_dialog: function () { var me = this; - msgprint = frappe.msgprint(format('{0}\ {1}', [ __('Print'), __('New') @@ -1106,8 +1395,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }) $('.new_doc').click(function () { - msgprint.hide() - me.create_new(); + me.msgprint.hide() + me.make_new_cart() }) }, @@ -1133,19 +1422,22 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ if (this.frm.doc.docstatus == 0) { this.frm.doc.docstatus = 1; this.update_invoice(); - this.disable_input_field(); + this.toggle_input_field(); } }, - disable_input_field: function () { + toggle_input_field: function () { var pointer_events = 'inherit' - $(this.wrapper).find('input').attr("disabled", false); - $(this.wrapper).find('select').attr("disabled", false); + disabled = this.frm.doc.docstatus == 1 ? true: false; + $(this.wrapper).find('input').attr("disabled", disabled); + $(this.wrapper).find('select').attr("disabled", disabled); + $(this.wrapper).find('input').attr("disabled", disabled); + $(this.wrapper).find('select').attr("disabled", disabled); + $(this.wrapper).find('button').attr("disabled", disabled); + this.party_field.$input.attr('disabled', disabled); if (this.frm.doc.docstatus == 1) { pointer_events = 'none'; - $(this.wrapper).find('input').attr("disabled", true); - $(this.wrapper).find('select').attr("disabled", true); } $(this.wrapper).find('.pos-bill').css('pointer-events', pointer_events); @@ -1210,18 +1502,26 @@ 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() || {}; + this.customers_list = this.get_customers_details() || {}; - if (this.si_docs.length) { + if (this.si_docs.length || this.email_queue_list || this.customers_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, + customers_list: me.customers_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.removed_customers = r.message.customers me.remove_doc_from_localstorage(); + me.remove_email_queue_from_localstorage(); + me.remove_customer_from_localstorage(); } } }) @@ -1259,11 +1559,38 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ } } }) + this.removed_items = []; this.si_docs = this.new_si_docs; this.update_localstorage(); } }, + 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(); + } + }, + + remove_customer_from_localstorage: function() { + var me = this; + this.customer_details = this.get_customers_details() + if (this.removed_customers) { + $.each(this.customers_list, function (index, data) { + if (in_list(me.removed_customers, index)) { + delete me.customer_details[index] + } + }) + this.update_customer_in_localstorage(); + } + }, + validate: function () { var me = this; this.customer_validate(); @@ -1350,13 +1677,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) }) }, @@ -1443,5 +1775,14 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ } return this.actual_qty + }, + + update_customer_in_localstorage: function() { + var me = this; + try { + localStorage.setItem('customer_details', JSON.stringify(this.customer_details)); + } catch (e) { + frappe.throw(__("LocalStorage is full , did not save")) + } } }) \ No newline at end of file diff --git a/erpnext/public/build.json b/erpnext/public/build.json index c4056813b6..393e90c052 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -20,8 +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 cfe9f63ac8..697c078289 100644 --- a/erpnext/public/css/erpnext.css +++ b/erpnext/public/css/erpnext.css @@ -12,113 +12,11 @@ height: 32px; margin: -10px auto; } -/* pos */ -.pos-item-area { - padding: 0px 10px; -} -.pos-item-wrapper { - padding: 5px; -} -.pos-item { - overflow: hidden; - text-overflow: ellipsis; - cursor: pointer; - padding: 5px; - padding-bottom: 15px; - border: 1px solid #d1d8dd; - margin-bottom: 5px; -} -.pos-item-text { - padding: 0px 5px; -} -.pos-item .item-code { - margin-bottom: 0px; -} -.pos-item .no-image { - background-color: #fafbfc; - border: 1px dashed #d1d8dd; -} -.pos-item-image { - width: 100%; - height: 0px; - padding: 50% 0; - text-align: center; - line-height: 0; - color: #d1d8dd; - font-size: 30px; - background-size: contain; - border: 1px solid transparent; - background-position: center; - background-repeat: no-repeat; -} -.pos-item-area { - border: 1px solid #d1d8dd; - border-top: none; -} -.pos-item-toolbar { - padding: 10px 0px; - border-bottom: 1px solid #d1d8dd; -} -.item-list-area { - padding: 15px 0px; - overflow-y: scroll; - height: calc(100vh - 162px); -} -.pos-toolbar, -.pos-bill-toolbar { - padding: 10px 0px; - height: 51px; -} -.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; -} -.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; -} -.pos-qty-row > div { - padding: 5px 0px; -} -.pos-qty-btn { - margin-top: 3px; - cursor: pointer; - font-size: 120%; -} -.pos .search-area .form-group { - max-width: 100% !important; -} -.pos .tax-table { - margin-bottom: 10px; -} .erpnext-icon { width: 24px; - ackmargin-right: 0px; + margin-right: 0px; margin-top: -3px; } -.pos .discount-amount-area .discount-field-col { - padding-left: 0px; -} -.pos .discount-amount-area .input-group { - margin-top: 2px; -} .dashboard-list-item { background-color: inherit; padding: 5px 0px; @@ -130,91 +28,6 @@ .dashboard-list-item:last-child { border-bottom: none; } -.payment-toolbar .row { - width: 323px; - margin: 0 auto; -} -.payment-mode { - cursor: pointer; - font-family: sans-serif; - font-size: 15px; -} -.pos-payment-row .col-xs-6 { - padding: 15px; -} -.pos-payment-row { - border-bottom: 1px solid #d1d8dd; - margin: 2px 0px 5px 0px; - height: 60px; - margin-top: 0px; - margin-bottom: 0px; -} -.pos-payment-row:hover, -.pos-keyboard-key:hover { - background-color: #FAFBFC; - cursor: pointer; -} -.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; -} -.multimode-payments { - padding-left: 30px; -} -.payment-toolbar { - padding-right: 30px; -} -.list-row-head.pos-invoice-list { - border-top: 1px solid #d1d8dd; -} -body[data-route="pos"] .modal-dialog { - width: 750px; -} -@media (max-width: 767px) { - body[data-route="pos"] .modal-dialog { - width: auto; - } - body[data-route="pos"] .modal-dialog .modal-content { - height: auto; - } -} -@media (max-width: 767px) { - .amount-row h3 { - font-size: 15px; - } - .pos-keyboard-key, - .delete-btn { - height: 50px; - } - .multimode-payments { - padding-left: 15px; - } - .payment-toolbar { - padding-right: 15px; - } -} -.amount-label { - font-size: 16px; -} -.selected-payment-mode { - background-color: #FAFBFC; - cursor: pointer; -} -.pos-invoice-list { - padding: 15px 10px; -} -.write_off_amount, -.change_amount { - margin: 15px; - width: 130px; -} .frappe-control[data-fieldname='result_html'] { overflow: scroll; } @@ -237,3 +50,281 @@ body[data-route="pos"] .modal-dialog { .assessment-result-tool .score { text-align: right; } +/* pos */ +body[data-route="pos"] .pos-bill-toolbar { + padding: 10px 0px; + height: 51px; +} +body[data-route="pos"] .pos-bill-item:hover, +body[data-route="pos"] .list-customers-table > .pos-list-row:hover { + background-color: #f5f7fa; + cursor: pointer; +} +body[data-route="pos"] .pos-item-qty { + display: inline-block; +} +body[data-route="pos"] .pos-qty-row > div { + padding: 5px 0px; +} +body[data-route="pos"] .pos-qty-btn { + margin-top: 3px; + cursor: pointer; + font-size: 120%; +} +body[data-route="pos"] .search-area .form-group { + max-width: 100% !important; +} +body[data-route="pos"] .tax-table { + margin-bottom: 10px; +} +body[data-route="pos"] .discount-field-col { + padding-left: 24px; +} +body[data-route="pos"] .discount-amount-area .input-group:first-child { + margin-bottom: 2px; +} +body[data-route="pos"] .payment-toolbar .row { + width: 323px; + margin: 0 auto; +} +body[data-route="pos"] .payment-mode { + cursor: pointer; + font-family: sans-serif; + font-size: 15px; +} +body[data-route="pos"] .pos-payment-row .col-xs-6 { + padding: 15px; +} +body[data-route="pos"] .pos-payment-row { + border-bottom: 1px solid #d1d8dd; + margin: 2px 0px 5px 0px; + height: 60px; + margin-top: 0px; + margin-bottom: 0px; +} +body[data-route="pos"] .pos-payment-row:hover, +body[data-route="pos"] .pos-keyboard-key:hover { + background-color: #FAFBFC; + cursor: pointer; +} +body[data-route="pos"] .pos-keyboard-key, +body[data-route="pos"] .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; +} +body[data-route="pos"] .numeric-keypad { + border: 1px solid #d1d8dd; + height: 69px; + width: 69px; + font-size: 20px; + font-weight: 200; + background-color: #FDFDFD; + border-color: #e8e8e8; + margin-left: -4px; +} +body[data-route="pos"] .pos-pay { + height: 69px; + width: 69px; + font-size: 17px; + font-weight: 200; + margin-left: -4px; +} +body[data-route="pos"] .numeric-keypad { + height: 60px; + width: 60px; + font-size: 20px; + font-weight: 200; + border-radius: 0; + background-color: #fff; + margin-left: -4px; +} +body[data-route="pos"] .numeric_keypad { + margin-left: -15px; +} +body[data-route="pos"] .numeric_keypad > .row > button { + border: none; + border-right: 1px solid #d1d8dd; + border-bottom: 1px solid #d1d8dd; +} +body[data-route="pos"] .numeric_keypad > .row > button:first-child { + border-left: 1px solid #d1d8dd; +} +body[data-route="pos"] .numeric_keypad > .row:first-child > button { + border-top: 1px solid #d1d8dd; +} +body[data-route="pos"] .pos-pay { + background-color: #5E64FF; + border: none; +} +body[data-route="pos"] .multimode-payments { + padding-left: 30px; +} +body[data-route="pos"] .payment-toolbar { + padding-right: 30px; +} +body[data-route="pos"] .list-row-head.pos-invoice-list { + border-top: 1px solid #d1d8dd; +} +body[data-route="pos"] .modal-dialog { + width: 750px; +} +@media (max-width: 767px) { + body[data-route="pos"] .modal-dialog { + width: auto; + } + body[data-route="pos"] .modal-dialog .modal-content { + height: auto; + } +} +@media (max-width: 767px) { + body[data-route="pos"] .amount-row h3 { + font-size: 15px; + } + body[data-route="pos"] .pos-keyboard-key, + body[data-route="pos"] .delete-btn { + height: 50px; + } + body[data-route="pos"] .multimode-payments { + padding-left: 15px; + } + body[data-route="pos"] .payment-toolbar { + padding-right: 15px; + } +} +body[data-route="pos"] .amount-label { + font-size: 16px; +} +body[data-route="pos"] .selected-payment-mode { + background-color: #FAFBFC; + cursor: pointer; +} +body[data-route="pos"] .pos-invoice-list { + padding: 15px 10px; +} +body[data-route="pos"] .write_off_amount, +body[data-route="pos"] .change_amount { + margin: 15px; + width: 130px; +} +body[data-route="pos"] .pos-list-row { + display: table; + table-layout: fixed; + width: 100%; + padding: 9px 15px; + font-size: 12px; + margin: 0px; + border-bottom: 1px solid #d1d8dd; +} +body[data-route="pos"] .pos-list-row .cell { + display: table-cell; + vertical-align: middle; +} +body[data-route="pos"] .pos-list-row .cell.price-cell { + width: 50%; +} +body[data-route="pos"] .pos-list-row .subject { + width: 40%; +} +body[data-route="pos"] .pos-list-row .list-row-checkbox, +body[data-route="pos"] .pos-list-row .list-select-all { + margin-right: 7px; +} +body[data-route="pos"] .pos-bill-header { + background-color: #f5f7fa; + border: 1px solid #d1d8dd; + padding: 13px 15px; +} +body[data-route="pos"] .pos-list-row.active { + background-color: #fffce7; +} +body[data-route="pos"] .totals-area { + border-right: 1px solid #d1d8dd; + border-left: 1px solid #d1d8dd; + margin-bottom: 15px; +} +body[data-route="pos"] .tax-area .pos-list-row { + border: none; +} +body[data-route="pos"] .item-cart-items { + height: calc(100vh - 526px); + overflow: auto; + border: 1px solid #d1d8dd; + border-top: none; +} +body[data-route="pos"] .no-items-message { + min-height: 200px; + display: flex; + align-items: center; + justify-content: center; + height: 100%; +} +body[data-route="pos"] .pos-list-row:last-child { + border-bottom: none; +} +body[data-route="pos"] .form-section-heading { + padding: 0; +} +body[data-route="pos"] .item-list { + border: 1px solid #d1d8dd; + border-top: none; + max-height: calc(100vh - 190px); + overflow: auto; +} +@media (max-width: 767px) { + body[data-route="pos"] .item-list { + max-height: initial; + } +} +body[data-route="pos"] .item-list .image-field { + height: 140px; +} +body[data-route="pos"] .item-list .pos-item-wrapper { + position: relative; +} +body[data-route="pos"] .item-list .price-info { + position: absolute; + left: 0; + bottom: 0; + margin: 0 0 15px 15px; + background-color: rgba(141, 153, 166, 0.6); + padding: 5px 9px; + border-radius: 3px; + color: #fff; +} +body[data-route="pos"] .pos-bill-toolbar { + margin-top: 10px; +} +body[data-route="pos"] .search-item .form-group { + margin: 0; +} +body[data-route="pos"] .item-list-area .pos-bill-header { + padding: 5px; + padding-left: 15px; +} +body[data-route="pos"] .pos-selected-item-action > .pos-list-row { + border: none; +} +body[data-route="pos"] .edit-customer-btn { + position: absolute; + right: 57px; + top: 15px; + z-index: 100; +} +body[data-route="pos"] .btn-more { + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + background-color: #fafbfc; + min-height: 200px; +} +body[data-route="pos"] .collapse-btn { + cursor: pointer; +} + diff --git a/erpnext/public/js/pos/customer_toolbar.html b/erpnext/public/js/pos/customer_toolbar.html new file mode 100644 index 0000000000..3ba5ccbc67 --- /dev/null +++ b/erpnext/public/js/pos/customer_toolbar.html @@ -0,0 +1,16 @@ +
    +
    + + + + + +
    + + {% 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 44e42d79b1..e356d8768e 100644 --- a/erpnext/public/js/pos/pos.html +++ b/erpnext/public/js/pos/pos.html @@ -1,86 +1,127 @@
    -
    -
    -
    -
    - - - {% if (allow_delete) { %} - - {% } %} -
    -
    -
    -
    -
    {%= __("Item") %}
    -
    {%= __("Quantity") %}
    -
    {%= __("Discount") %}
    -
    {%= __("Rate") %}
    -
    -
    -
    -
    -
    -
    {%= __("Net Total") %}
    -
    -
    -
    -
    -
    {%= __("Taxes") %}
    -
    +
    +
    +
    {{ __("Item Cart") }}
    +
    +
    +
    + + + {{ __("Item Name")}} + + {{ __("Quantity") }} + {{ __("Discount") }} + {{ __("Rate") }} +
    +
    +
    + + +

    Tap items to add them here

    +
    -
    - {% if (apply_discount_on) { %} -
    -
    {%= __("Discount") %}
    -
    -
    - % - -
    -
    -
    -
    - {%= get_currency_symbol(currency) %} - -
    -
    -
    - {% } %} -
    -
    {%= __("Grand Total") %}
    -
    -
    -
    -
    -
    - +
    +
    +
    +
    -
    -
    -
    - +
    +
    +
    +
    {%= __("Net Total") %}
    +
    +
    +
    +
    +
    {%= __("Taxes") %}
    +
    +
    +
    + {% if (apply_discount_on) { %} +
    +
    +
    {%= __("Discount") %}
    +
    +
    + % + +
    +
    + {%= get_currency_symbol(currency) %} + +
    +
    +
    + {% } %} +
    +
    + + + +
    +
    {%= __("Grand Total") %}
    +
    +
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - +
    +
    + +
    +
    -
    -
    +
    +
    +
    {{ __("Customers in Queue") }}
    +
    +
    {{ __("Customer") }}
    +
    {{ __("Status") }}
    +
    {{ __("Amount") }}
    +
    {{ __("Grand Total") }}
    +
    +
    +
    + + +

    No Customers yet!

    +
    +
    +
    +
    +
    +
    {{ __("Stock Items") }}
    +
    + +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    \ No newline at end of file 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_bill_item_new.html b/erpnext/public/js/pos/pos_bill_item_new.html new file mode 100644 index 0000000000..80a33d49fc --- /dev/null +++ b/erpnext/public/js/pos/pos_bill_item_new.html @@ -0,0 +1,9 @@ +
    + +
    {%= qty %}
    +
    {%= discount_percentage %}
    +
    {%= format_currency(rate) %}
    +
    diff --git a/erpnext/public/js/pos/pos_invoice_list.html b/erpnext/public/js/pos/pos_invoice_list.html index 67110a7470..13aa52055a 100644 --- a/erpnext/public/js/pos/pos_invoice_list.html +++ b/erpnext/public/js/pos/pos_invoice_list.html @@ -1,7 +1,9 @@ -
    -
    -
    {%= customer %}
    -
    {{ data.status }}
    -
    {%= paid_amount %}
    -
    {%= grand_total %}
    +
    + +
    {{ data.status }}
    +
    {%= paid_amount %}
    +
    {%= grand_total %}
    diff --git a/erpnext/public/js/pos/pos_item.html b/erpnext/public/js/pos/pos_item.html index b33076dc6a..fbc380be19 100644 --- a/erpnext/public/js/pos/pos_item.html +++ b/erpnext/public/js/pos/pos_item.html @@ -1,13 +1,32 @@ -
    -
    -
    - {% if (!item_image) { %}{{ abbr }}{% } %} -
    -
    -
    {%= item_name ? (item_name + " (" + item_code + ")") : item_code %}
    -
    {%= item_price %}
    + \ No newline at end of file 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..30cf0f00d7 --- /dev/null +++ b/erpnext/public/js/pos/pos_selected_item.html @@ -0,0 +1,21 @@ +
    +
    + {{item_name}} +
    +
    +
    Quantity:
    + +
    +
    +
    Discount:
    + +
    +
    +
    Price:
    + +
    +
    +
    Amount:
    + +
    +
    \ No newline at end of file diff --git a/erpnext/public/js/pos/pos_tax_row.html b/erpnext/public/js/pos/pos_tax_row.html index 788eb1f337..3752a89bbd 100644 --- a/erpnext/public/js/pos/pos_tax_row.html +++ b/erpnext/public/js/pos/pos_tax_row.html @@ -1,4 +1,4 @@ -
    -
    {%= description %}
    -
    {%= tax_amount %}
    +
    +
    {%= description %}
    +
    {%= tax_amount %}
    diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less index 495e618f7e..0a48970704 100644 --- a/erpnext/public/less/erpnext.less +++ b/erpnext/public/less/erpnext.less @@ -17,140 +17,12 @@ margin: -10px auto; } -/* pos */ - -.pos-item-area { - padding: 0px 10px; -} - -.pos-item-wrapper { - padding: 5px; -} - -.pos-item { - overflow: hidden; - text-overflow: ellipsis; - cursor: pointer; - padding: 5px; - padding-bottom: 15px; - border: 1px solid #d1d8dd; - margin-bottom: 5px; -} - -.pos-item-text { - padding: 0px 5px; -} - -.pos-item .item-code { - margin-bottom: 0px; -} - -.pos-item .no-image { - background-color: #fafbfc; - border: 1px dashed #d1d8dd; -} - -.pos-item-image { - width: 100%; - height: 0px; - padding: 50% 0; - text-align: center; - line-height: 0; - color: @text-extra-muted; - font-size: 30px; - background-size: contain; - border: 1px solid transparent; - background-position: center; - background-repeat: no-repeat; -} - -.pos-item-area { - border: 1px solid #d1d8dd; - border-top: none; -} - -.pos-item-toolbar { - padding: 10px 0px; - border-bottom: 1px solid #d1d8dd; -} - -.item-list-area { - padding: 15px 0px; - overflow-y: scroll; - height: ~"calc(100vh - 162px)"; -} - -.pos-toolbar, .pos-bill-toolbar { - padding: 10px 0px; - // border-bottom: 1px solid #d1d8dd; - height: 51px; -} - -.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 @border-color; - margin-left: -15px; - margin-right: -15px; -} - -.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; -} - -.pos-qty-row > div { - padding: 5px 0px; -} - -.pos-qty-btn { - margin-top: 3px; - cursor: pointer; - font-size: 120%; -} - -.pos .search-area .form-group { - max-width: 100% !important; -} - -.pos .tax-table { - margin-bottom: 10px; -} - .erpnext-icon { - width: 24px;ack + width: 24px; margin-right: 0px; margin-top: -3px; } -.pos .discount-amount-area { - .discount-field-col { - padding-left: 0px; - } - - .input-group { - margin-top: 2px; - } -} - .dashboard-list-item { background-color: inherit; padding: 5px 0px; @@ -165,104 +37,6 @@ border-bottom: none; } -.payment-toolbar { - .row { - width: 323px; - margin: 0 auto; - } -} - -.payment-mode { - cursor: pointer; - font-family: sans-serif; - font-size: 15px; -} - -.pos-payment-row .col-xs-6 { - padding :15px; -} - -.pos-payment-row { - border-bottom:1px solid #d1d8dd; - margin: 2px 0px 5px 0px; - height: 60px; - margin-top: 0px; - margin-bottom: 0px; -} - -.pos-payment-row:hover, .pos-keyboard-key:hover{ - background-color: #FAFBFC; - cursor: pointer; -} - -.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; -} - -.multimode-payments { - padding-left: 30px; -} - -.payment-toolbar { - padding-right: 30px; -} - -.list-row-head.pos-invoice-list { - border-top: 1px solid @border-color; -} - -body[data-route="pos"] .modal-dialog { - width: 750px; - - @media (max-width: @screen-xs) { - width: auto; - - .modal-content { - height: auto; - } - } -} - -@media (max-width: @screen-xs) { - .amount-row h3 { - font-size: 15px; - } - .pos-keyboard-key, .delete-btn { - height: 50px; - } - .multimode-payments { - padding-left: 15px; - } - .payment-toolbar { - padding-right: 15px; - } -} - -.amount-label { - font-size: 16px; -} - -.selected-payment-mode { - background-color: #FAFBFC; - cursor: pointer; -} - -.pos-invoice-list { - padding: 15px 10px; -} - -.write_off_amount, .change_amount { - margin: 15px; - width: 130px; -} - // assessment tool .frappe-control[data-fieldname='result_html'] { overflow: scroll; @@ -286,4 +60,338 @@ body[data-route="pos"] .modal-dialog { .total-score, .grade, .score { text-align: right; } +} + +/* pos */ + +body[data-route="pos"] { + + .pos-bill-toolbar { + padding: 10px 0px; + height: 51px; + } + + .pos-bill-item:hover, .list-customers-table > .pos-list-row:hover { + background-color: #f5f7fa; + cursor: pointer; + } + + .pos-item-qty { + display: inline-block; + } + + .pos-qty-row > div { + padding: 5px 0px; + } + + .pos-qty-btn { + margin-top: 3px; + cursor: pointer; + font-size: 120%; + } + + .search-area .form-group { + max-width: 100% !important; + } + + .tax-table { + margin-bottom: 10px; + } + + .discount-field-col { + padding-left: 24px; + } + + .discount-amount-area { + .input-group:first-child { + margin-bottom: 2px; + } + } + + .payment-toolbar { + .row { + width: 323px; + margin: 0 auto; + } + } + + .payment-mode { + cursor: pointer; + font-family: sans-serif; + font-size: 15px; + } + + .pos-payment-row .col-xs-6 { + padding :15px; + } + + .pos-payment-row { + border-bottom:1px solid #d1d8dd; + margin: 2px 0px 5px 0px; + height: 60px; + margin-top: 0px; + margin-bottom: 0px; + } + + .pos-payment-row:hover, .pos-keyboard-key:hover{ + background-color: #FAFBFC; + cursor: pointer; + } + + .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; + 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; + } + + .numeric-keypad { + height: 60px; + width: 60px; + font-size: 20px; + font-weight: 200; + border-radius: 0; + background-color: #fff; + margin-left:-4px; + } + + .numeric_keypad { + margin-left: -15px; + + & > .row > button { + border: none; + border-right: 1px solid @border-color; + border-bottom: 1px solid @border-color; + + &:first-child { + border-left: 1px solid @border-color; + } + } + + & > .row:first-child > button { + border-top: 1px solid @border-color; + } + } + + .pos-pay { + background-color: @brand-primary; + border: none; + } + + .multimode-payments { + padding-left: 30px; + } + + .payment-toolbar { + padding-right: 30px; + } + + .list-row-head.pos-invoice-list { + border-top: 1px solid @border-color; + } + + .modal-dialog { + width: 750px; + + @media (max-width: @screen-xs) { + width: auto; + + .modal-content { + height: auto; + } + } + } + + @media (max-width: @screen-xs) { + .amount-row h3 { + font-size: 15px; + } + .pos-keyboard-key, .delete-btn { + height: 50px; + } + .multimode-payments { + padding-left: 15px; + } + .payment-toolbar { + padding-right: 15px; + } + } + + .amount-label { + font-size: 16px; + } + + .selected-payment-mode { + background-color: #FAFBFC; + cursor: pointer; + } + + .pos-invoice-list { + padding: 15px 10px; + } + + .write_off_amount, .change_amount { + margin: 15px; + width: 130px; + } + + .pos-list-row { + display: table; + table-layout: fixed; + width: 100%; + padding: 9px 15px; + font-size: 12px; + margin: 0px; + border-bottom: 1px solid @border-color; + + .cell { + display: table-cell; + vertical-align: middle; + + &.price-cell { + width: 50%; + } + } + + .subject { + width: 40% + } + + .list-row-checkbox, .list-select-all { + margin-right: 7px; + } + } + + .pos-bill-header { + background-color: #f5f7fa; + border: 1px solid @border-color; + padding: 13px 15px; + } + + .pos-list-row.active { + background-color: @light-yellow; + } + + .totals-area { + border-right: 1px solid @border-color; + border-left: 1px solid @border-color; + margin-bottom: 15px; + } + + .tax-area .pos-list-row { + border: none; + } + + .item-cart-items { + height: ~"calc(100vh - 526px)"; + overflow: auto; + border: 1px solid @border-color; + border-top: none; + } + + .no-items-message { + min-height: 200px; + display: flex; + align-items: center; + justify-content: center; + height: 100%; + } + + .pos-list-row:last-child { + border-bottom: none; + } + + .form-section-heading { + padding: 0; + } + + .item-list { + border: 1px solid @border-color; + border-top: none; + max-height: ~"calc(100vh - 190px)"; + overflow: auto; + + @media (max-width: @screen-xs) { + max-height: initial; + } + + .image-field { + height: 140px; + } + + .pos-item-wrapper { + position: relative; + } + + .price-info { + position: absolute; + left: 0; + bottom: 0; + margin: 0 0 15px 15px; + background-color: rgba(141, 153, 166, 0.6); + padding: 5px 9px; + border-radius: 3px; + color: #fff; + } + } + + .pos-bill-toolbar { + margin-top: 10px; + } + + .search-item .form-group { + margin: 0; + } + + .item-list-area .pos-bill-header { + padding: 5px; + padding-left: 15px; + } + + .pos-selected-item-action > .pos-list-row { + border: none; + } + + .edit-customer-btn { + position: absolute; + right: 57px; + top: 15px; + z-index: 100; + } + + .btn-more { + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + background-color: @light-bg; + min-height: 200px; + } + + .collapse-btn { + cursor: pointer; + } } \ No newline at end of file