diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.py b/erpnext/accounts/doctype/pos_profile/pos_profile.py index ef497bfe29f..f6484762bfa 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.py +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.py @@ -14,6 +14,7 @@ class POSProfile(Document): self.check_for_duplicate() self.validate_all_link_fields() self.validate_duplicate_groups() + self.check_default_payment() def check_for_duplicate(self): res = frappe.db.sql("""select name, user from `tabPOS Profile` @@ -48,6 +49,15 @@ class POSProfile(Document): if len(customer_groups) != len(set(customer_groups)): frappe.throw(_("Duplicate customer group found in the cutomer group table"), title = "Duplicate Customer Group") + def check_default_payment(self): + if self.payments: + default_mode_of_payment = [d.default for d in self.payments if d.default] + if not default_mode_of_payment: + frappe.throw(_("Set default mode of payment")) + + if len(default_mode_of_payment) > 1: + frappe.throw(_("Multiple default mode of payment is not allowed")) + def before_save(self): set_account_for_mode_of_payment(self) diff --git a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py index 9c6a11487c5..37828e16afb 100644 --- a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py +++ b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py @@ -31,6 +31,8 @@ class TestPOSProfile(unittest.TestCase): frappe.db.sql("delete from `tabPOS Profile`") def make_pos_profile(): + frappe.db.sql("delete from `tabPOS Profile`") + pos_profile = frappe.get_doc({ "company": "_Test Company", "cost_center": "_Test Cost Center - _TC", diff --git a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json index 13d7f15c7d5..531622d6ac5 100644 --- a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json +++ b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "beta": 0, @@ -11,16 +12,51 @@ "editable_grid": 1, "fields": [ { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, + "depends_on": "eval:parent.doctype == 'POS Profile'", + "fieldname": "default", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Default", + "length": 0, + "no_copy": 0, + "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_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, "fieldname": "mode_of_payment", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Mode of Payment", "length": 0, "no_copy": 0, @@ -30,6 +66,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -37,9 +74,11 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "0.0", "depends_on": "eval:parent.doctype == 'Sales Invoice'", "fieldname": "amount", @@ -48,7 +87,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": "Amount", "length": 0, "no_copy": 0, @@ -58,6 +99,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -65,16 +107,20 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "column_break_3", "fieldtype": "Column Break", "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, "length": 0, "no_copy": 0, "permlevel": 0, @@ -82,6 +128,7 @@ "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, @@ -89,16 +136,20 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "account", "fieldtype": "Link", "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": "Account", "length": 0, "no_copy": 0, @@ -108,6 +159,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -115,16 +167,20 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "type", "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": "Type", "length": 0, "no_copy": 0, @@ -134,6 +190,7 @@ "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, @@ -141,16 +198,20 @@ "unique": 0 }, { + "allow_bulk_edit": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "base_amount", "fieldtype": "Currency", "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": "Base Amount (Company Currency)", "length": 0, "no_copy": 1, @@ -160,6 +221,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -167,17 +229,17 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-07-11 03:28:07.779228", + "modified": "2017-07-24 17:25:03.765856", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Payment", @@ -187,7 +249,9 @@ "quick_entry": 1, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", + "track_changes": 0, "track_seen": 0 } \ No newline at end of file diff --git a/erpnext/accounts/page/pos/test_pos.js b/erpnext/accounts/page/pos/test_pos.js new file mode 100644 index 00000000000..62c6e31eb5d --- /dev/null +++ b/erpnext/accounts/page/pos/test_pos.js @@ -0,0 +1,60 @@ +QUnit.test("test:POS Profile", function(assert) { + assert.expect(1); + let done = assert.async(); + + frappe.run_serially([ + () => { + return frappe.tests.make("POS Profile", [ + {naming_series: "SINV"}, + {company: "_Test Company"}, + {country: "India"}, + {currency: "INR"}, + {write_off_account: "Write Off - _TC"}, + {write_off_cost_center: "Main - _TC"}, + {payments: [ + [ + {"default": 1}, + {"mode_of_payment": "Cash"} + ]] + } + ]); + }, + () => cur_frm.save(), + () => frappe.timeout(2), + () => { + assert.equal(cur_frm.doc.payments[0].default, 1, "Default mode of payment tested"); + }, + () => done() + ]); +}); + +QUnit.test("test:Sales Invoice", function(assert) { + assert.expect(2); + let done = assert.async(); + + frappe.run_serially([ + () => { + return frappe.tests.make("Sales Invoice", [ + {customer: "_Test Customer 2"}, + {company: "_Test Company"}, + {is_pos: 1}, + {posting_date: frappe.datetime.get_today()}, + {due_date: frappe.datetime.get_today()}, + {items: [ + [ + {"item_code": "_Test Item"}, + {"qty": 5} + ]] + } + ]); + }, + () => frappe.timeout(2), + () => cur_frm.save(), + () => frappe.timeout(2), + () => { + assert.equal(cur_frm.doc.payments[0].default, 1, "Default mode of payment tested"); + assert.equal(cur_frm.doc.payments[0].mode_of_payment, "Cash", "Default mode of payment tested"); + }, + () => done() + ]); +}); \ No newline at end of file diff --git a/erpnext/docs/assets/img/pos-setting/default_mop.png b/erpnext/docs/assets/img/pos-setting/default_mop.png new file mode 100644 index 00000000000..bd1e7a07e9d Binary files /dev/null and b/erpnext/docs/assets/img/pos-setting/default_mop.png differ diff --git a/erpnext/docs/assets/img/pos-setting/item_customer_group.png b/erpnext/docs/assets/img/pos-setting/item_customer_group.png new file mode 100644 index 00000000000..6117a8f2669 Binary files /dev/null and b/erpnext/docs/assets/img/pos-setting/item_customer_group.png differ diff --git a/erpnext/docs/assets/img/pos-setting/pos-setting.png b/erpnext/docs/assets/img/pos-setting/pos-setting.png deleted file mode 100644 index 606119921c6..00000000000 Binary files a/erpnext/docs/assets/img/pos-setting/pos-setting.png and /dev/null differ diff --git a/erpnext/docs/assets/img/pos-setting/pos_profile.png b/erpnext/docs/assets/img/pos-setting/pos_profile.png new file mode 100644 index 00000000000..a8bd4acaa07 Binary files /dev/null and b/erpnext/docs/assets/img/pos-setting/pos_profile.png differ diff --git a/erpnext/docs/user/manual/en/accounts/point-of-sale-pos-invoice.md b/erpnext/docs/user/manual/en/accounts/point-of-sale-pos-invoice.md index 78d2226361f..763c1421550 100644 --- a/erpnext/docs/user/manual/en/accounts/point-of-sale-pos-invoice.md +++ b/erpnext/docs/user/manual/en/accounts/point-of-sale-pos-invoice.md @@ -15,7 +15,7 @@ POS Invoices created in the offline mode will be saved locally in the browser. I In ERPNext all Sales and Purchase transactions, like Sales Invoice, Quotation, Sales Order, Purchase Order etc. can be edited via the POS. There two steps to Setup POS: 1. Enable POS View via (Setup > Customize > Feature Setup) -2. Create a [POS Setting]({{docs_base_url}}/user/manual/en/setting-up/pos-setting.html) record +2. Create a [POS Profile]({{docs_base_url}}/user/manual/en/setting-up/pos-setting.html) record #### Different sections of the POS diff --git a/erpnext/docs/user/manual/en/setting-up/pos-setting.md b/erpnext/docs/user/manual/en/setting-up/pos-setting.md index 9bfd8198f23..01e353b2c95 100644 --- a/erpnext/docs/user/manual/en/setting-up/pos-setting.md +++ b/erpnext/docs/user/manual/en/setting-up/pos-setting.md @@ -1,4 +1,4 @@ -# Point of Sale Setting +# Point of Sale Profile POS includes advanced features to cater to different functionality, such as inventory management, CRM, financials, warehousing, etc., all built into the @@ -10,11 +10,17 @@ If you are in retail operations, you want your Point of Sale to be as quick and efficient as possible. To do this, you can create a POS Setting for a user from: -> Accounts > Setup > Point-of-Sale Setting +> Accounts > Setup > Point-of-Sale Profile Set default values as defined. -POS Setting +POS Setting + +To set the default mode of payment, enabled the option default in the mode of payments table +POS Setting + +User can sale the particular products to the particular customers from the POS by adding item groups, customer groups in the POS Profile. +POS Setting > Important : If you specify a particular User, the POS setting will be applied only to that User. If the User option is left blank, the setting will diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 2aabfc646f1..af4eab5acd0 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -427,3 +427,4 @@ erpnext.patches.v8_1.set_delivery_date_in_so_item erpnext.patches.v8_5.fix_tax_breakup_for_non_invoice_docs erpnext.patches.v8_5.remove_quotations_route_in_sidebar erpnext.patches.v8_5.update_existing_data_in_project_type +erpnext.patches.v8_5.set_default_mode_of_payment \ No newline at end of file diff --git a/erpnext/patches/v8_5/set_default_mode_of_payment.py b/erpnext/patches/v8_5/set_default_mode_of_payment.py new file mode 100644 index 00000000000..34ecbb0a3c3 --- /dev/null +++ b/erpnext/patches/v8_5/set_default_mode_of_payment.py @@ -0,0 +1,17 @@ +# Copyright (c) 2017, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + frappe.reload_doctype("POS Profile") + frappe.reload_doctype("Sales Invoice Payment") + + frappe.db.sql(""" + update + `tabSales Invoice Payment` + set `tabSales Invoice Payment`.default = 1 + where + `tabSales Invoice Payment`.parenttype = 'POS Profile' + and `tabSales Invoice Payment`.idx=1""") \ No newline at end of file diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js index a54f30de584..83644db26c4 100644 --- a/erpnext/public/js/controllers/taxes_and_totals.js +++ b/erpnext/public/js/controllers/taxes_and_totals.js @@ -584,7 +584,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ var payment_status = true; if(this.frm.doc.is_pos && (update_paid_amount===undefined || update_paid_amount)){ $.each(this.frm.doc['payments'] || [], function(index, data){ - if(data.type == "Cash" && payment_status && total_amount_to_pay > 0) { + if(data.default && payment_status && total_amount_to_pay > 0) { data.base_amount = flt(total_amount_to_pay, precision("base_amount")); data.amount = flt(total_amount_to_pay / me.frm.doc.conversion_rate, precision("amount")); payment_status = false; diff --git a/erpnext/public/js/pos/pos_selected_item.html b/erpnext/public/js/pos/pos_selected_item.html index 0ed6c71fcc2..6f2772be219 100644 --- a/erpnext/public/js/pos/pos_selected_item.html +++ b/erpnext/public/js/pos/pos_selected_item.html @@ -17,6 +17,6 @@
{{ __("Amount") }}:
- +
\ No newline at end of file diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt index a8c1a7e5bb7..b87ff034c21 100644 --- a/erpnext/tests/ui/tests.txt +++ b/erpnext/tests/ui/tests.txt @@ -31,4 +31,5 @@ erpnext/schools/doctype/student_batch_name/test_student_batch_name.js erpnext/schools/doctype/student_category/test_student_category.js erpnext/schools/doctype/room/test_room.js erpnext/schools/doctype/instructor/test_instructor.js -erpnext/selling/doctype/product_bundle/test_product_bundle.js \ No newline at end of file +erpnext/accounts/page/pos/test_pos.js +erpnext/selling/doctype/product_bundle/test_product_bundle.js