From 8ac56b26e06ec30d7541bbdb7f4d325bd49c6d66 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 29 Sep 2017 16:15:15 +0530 Subject: [PATCH 1/6] [Enhancement] Allow Multiple users in POS Profile --- .../doctype/pos_profile/pos_profile.json | 99 ++++++++++++++++++- .../doctype/pos_profile/pos_profile.py | 43 +++++++- .../add_user_to_child_table_in_pos_profile.py | 21 ++++ .../page/point_of_sale/point_of_sale.js | 61 +++++++++--- 4 files changed, 207 insertions(+), 17 deletions(-) create mode 100644 erpnext/patches/v9_0/add_user_to_child_table_in_pos_profile.py diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json index 187454ef33..a7c2c3df37 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.json +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json @@ -3,7 +3,7 @@ "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, - "autoname": "hash", + "autoname": "field:pos_profile_name", "beta": 0, "creation": "2013-05-24 12:15:51", "custom": 0, @@ -11,6 +11,36 @@ "doctype": "DocType", "editable_grid": 0, "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "pos_profile_name", + "fieldtype": "Data", + "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": "POS Profile Name", + "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": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -416,6 +446,67 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_15", + "fieldtype": "Section 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, + "label": "Applicable for Users", + "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": "applicable_for_users", + "fieldtype": "Table", + "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": "Applicable for Users", + "length": 0, + "no_copy": 0, + "options": "POS Profile User", + "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, @@ -1322,8 +1413,8 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-09-01 15:55:14.890452", - "modified_by": "Administrator", + "modified": "2017-09-29 14:39:22.280700", + "modified_by": "faris@erpnext.com", "module": "Accounts", "name": "POS Profile", "owner": "Administrator", @@ -1375,7 +1466,7 @@ "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", - "title_field": "user", + "title_field": "pos_profile_name", "track_changes": 0, "track_seen": 0 } \ No newline at end of file diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.py b/erpnext/accounts/doctype/pos_profile/pos_profile.py index 8d6a2db470..3e3728592c 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.py +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.py @@ -11,7 +11,7 @@ from frappe.model.document import Document class POSProfile(Document): def validate(self): - self.check_for_duplicate() + # self.check_for_duplicate() self.validate_all_link_fields() self.validate_duplicate_groups() self.check_default_payment() @@ -94,3 +94,44 @@ class POSProfile(Document): @frappe.whitelist() def get_series(): return frappe.get_meta("Sales Invoice").get_field("naming_series").options or "" + +@frappe.whitelist() +def get_pos_profiles_for_user(user=None): + out = [] + if not user: + user = frappe.session.user + + res = frappe.db.sql(''' + select + parent + from + `tabPOS Profile User` + where + user = %s + ''', (user), as_dict=1) + + if not res: + company = frappe.defaults.get_user_default('company') + res = frappe.db.sql(''' + select + pos_profile_name + from + `tabPOS Profile` + where + company = %s + ''', (company), as_dict=1) + + out = [r.pos_profile_name for r in res] + + return out + + for r in res: + name = frappe.db.get_value('POS Profile', r.parent, 'pos_profile_name') + out.append(name) + + return out + +@frappe.whitelist() +def get_pos_profile(pos_profile_name): + name = frappe.db.get_value('POS Profile', { 'pos_profile_name': pos_profile_name }) + return frappe.get_doc('POS Profile', name) diff --git a/erpnext/patches/v9_0/add_user_to_child_table_in_pos_profile.py b/erpnext/patches/v9_0/add_user_to_child_table_in_pos_profile.py new file mode 100644 index 0000000000..b2093c6c6f --- /dev/null +++ b/erpnext/patches/v9_0/add_user_to_child_table_in_pos_profile.py @@ -0,0 +1,21 @@ +# Copyright (c) 2017, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + doctype = 'POS Profile' + frappe.reload_doctype(doctype) + + for doc in frappe.get_all(doctype): + _doc = frappe.get_doc(doctype, doc.name) + user = frappe.db.get_value(doctype, doc.name, 'user') + + if not user: continue + + _doc.append('applicable_for_users', { + 'user': user + }) + _doc.pos_profile_name = user + ' - ' + _doc.company + _doc.save() diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index 1b67ff2b72..a8093fd4f1 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -261,20 +261,57 @@ erpnext.pos.PointOfSale = class PointOfSale { } setup_pos_profile() { - return frappe.call({ - method: 'erpnext.stock.get_item_details.get_pos_profile', - args: { - company: frappe.sys_defaults.company - } - }).then(r => { - this.pos_profile = r.message; + return new Promise((resolve) => { + const on_submit = ({ pos_profile }) => { + this.get_pos_profile_doc(pos_profile) + .then(doc => { + this.pos_profile = doc; - if (!this.pos_profile) { - this.pos_profile = { - currency: frappe.defaults.get_default('currency'), - selling_price_list: frappe.defaults.get_default('selling_price_list') - }; + if (!this.pos_profile) { + this.pos_profile = { + currency: frappe.defaults.get_default('currency'), + selling_price_list: frappe.defaults.get_default('selling_price_list') + }; + } + + resolve(); + }); } + + frappe.call({ + method: 'erpnext.accounts.doctype.pos_profile.pos_profile.get_pos_profiles_for_user' + }) + .then((r) => { + if (r && r.message) { + const pos_profiles = r.message; + + if(pos_profiles.length === 1) { + // load profile directly + on_submit({pos_profile: pos_profiles[0]}); + } else { + // ask prompt + frappe.prompt( + [{ fieldtype: 'Select', label: 'POS Profile', options: pos_profiles }], + on_submit, + __('Select POS Profile') + ) + } + } + }); + }); + } + + get_pos_profile_doc(pos_profile_name) { + return new Promise(resolve => { + frappe.call({ + method: 'erpnext.accounts.doctype.pos_profile.pos_profile.get_pos_profile', + args: { + pos_profile_name + }, + callback: (r) => { + resolve(r.message); + } + }); }); } From 8c1099d2362bbf25a093d34666b2e7e4391729af Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 27 Oct 2017 16:48:07 +0530 Subject: [PATCH 2/6] Add POS Profile User DocType --- .../doctype/pos_profile_user/__init__.py | 0 .../pos_profile_user/pos_profile_user.js | 8 ++ .../pos_profile_user/pos_profile_user.json | 93 +++++++++++++++++++ .../pos_profile_user/pos_profile_user.py | 10 ++ 4 files changed, 111 insertions(+) create mode 100644 erpnext/accounts/doctype/pos_profile_user/__init__.py create mode 100644 erpnext/accounts/doctype/pos_profile_user/pos_profile_user.js create mode 100644 erpnext/accounts/doctype/pos_profile_user/pos_profile_user.json create mode 100644 erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py diff --git a/erpnext/accounts/doctype/pos_profile_user/__init__.py b/erpnext/accounts/doctype/pos_profile_user/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.js b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.js new file mode 100644 index 0000000000..2f482d6952 --- /dev/null +++ b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.js @@ -0,0 +1,8 @@ +// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('POS Profile User', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.json b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.json new file mode 100644 index 0000000000..22c7f722e2 --- /dev/null +++ b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.json @@ -0,0 +1,93 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2017-10-27 16:46:06.060930", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "user", + "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": "User", + "length": 0, + "no_copy": 0, + "options": "User", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2017-10-27 16:46:12.784244", + "modified_by": "Administrator", + "module": "Accounts", + "name": "POS Profile User", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py new file mode 100644 index 0000000000..755b1e99ff --- /dev/null +++ b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class POSProfileUser(Document): + pass From 79be8f969fe9501bc7155226f96d7fed954e5ebf Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 30 Oct 2017 14:46:09 +0530 Subject: [PATCH 3/6] Add to patches.txt --- erpnext/patches.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index e75c490a36..1e9d529b30 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -448,3 +448,4 @@ erpnext.patches.v8_9.remove_employee_from_salary_structure_parent erpnext.patches.v8_9.delete_gst_doctypes_for_outside_india_accounts erpnext.patches.v8_9.set_default_fields_in_variant_settings erpnext.patches.v8_9.update_billing_gstin_for_indian_account +erpnext.patches.v9_0.add_user_to_child_table_in_pos_profile From 895aa7b7ac8aeccccb59f9ebd0e81d5bab617d6c Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 30 Oct 2017 17:12:50 +0530 Subject: [PATCH 4/6] fix codacy --- .../doctype/pos_profile_user/pos_profile_user.js | 2 -- .../doctype/pos_profile_user/pos_profile_user.py | 1 - .../selling/page/point_of_sale/point_of_sale.js | 16 +++++++--------- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.js b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.js index 2f482d6952..f0884ebef5 100644 --- a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.js +++ b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.js @@ -2,7 +2,5 @@ // For license information, please see license.txt frappe.ui.form.on('POS Profile User', { - refresh: function(frm) { - } }); diff --git a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py index 755b1e99ff..d77cddea61 100644 --- a/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py +++ b/erpnext/accounts/doctype/pos_profile_user/pos_profile_user.py @@ -3,7 +3,6 @@ # For license information, please see license.txt from __future__ import unicode_literals -import frappe from frappe.model.document import Document class POSProfileUser(Document): diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index 6f1cd9ff5e..ee6a633fac 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -290,21 +290,19 @@ erpnext.pos.PointOfSale = class PointOfSale { this.pos_profile = doc; if (!this.pos_profile) { - this.pos_profile = { - company: this.company, - currency: frappe.defaults.get_default('currency'), - selling_price_list: frappe.defaults.get_default('selling_price_list') - }; - } - + this.pos_profile = { + company: this.company, + currency: frappe.defaults.get_default('currency'), + selling_price_list: frappe.defaults.get_default('selling_price_list') + }; + } resolve(); }); } frappe.call({ method: 'erpnext.accounts.doctype.pos_profile.pos_profile.get_pos_profiles_for_user' - }) - .then((r) => { + }).then((r) => { if (r && r.message) { const pos_profiles = r.message; From 3d591792052910c6d97c77f7f056ee788aa10316 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Tue, 31 Oct 2017 21:56:16 +0530 Subject: [PATCH 5/6] Load default pos profile if not found --- .../doctype/pos_profile/pos_profile.py | 3 ++- .../page/point_of_sale/point_of_sale.js | 23 ++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.py b/erpnext/accounts/doctype/pos_profile/pos_profile.py index 3e3728592c..6b7d99f7f1 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.py +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.py @@ -132,6 +132,7 @@ def get_pos_profiles_for_user(user=None): return out @frappe.whitelist() -def get_pos_profile(pos_profile_name): +def get_pos_profile(pos_profile_name=None): + if not pos_profile_name: return name = frappe.db.get_value('POS Profile', { 'pos_profile_name': pos_profile_name }) return frappe.get_doc('POS Profile', name) diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index ee6a633fac..c9893f1ce8 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -284,17 +284,22 @@ erpnext.pos.PointOfSale = class PointOfSale { setup_pos_profile() { return new Promise((resolve) => { + + const load_default = () => { + this.pos_profile = { + company: this.company, + currency: frappe.defaults.get_default('currency'), + selling_price_list: frappe.defaults.get_default('selling_price_list') + }; + resolve(); + } + const on_submit = ({ pos_profile }) => { this.get_pos_profile_doc(pos_profile) .then(doc => { this.pos_profile = doc; - if (!this.pos_profile) { - this.pos_profile = { - company: this.company, - currency: frappe.defaults.get_default('currency'), - selling_price_list: frappe.defaults.get_default('selling_price_list') - }; + load_default(); } resolve(); }); @@ -304,9 +309,11 @@ erpnext.pos.PointOfSale = class PointOfSale { method: 'erpnext.accounts.doctype.pos_profile.pos_profile.get_pos_profiles_for_user' }).then((r) => { if (r && r.message) { - const pos_profiles = r.message; + const pos_profiles = r.message.filter(a => a); - if(pos_profiles.length === 1) { + if (pos_profiles.length === 0) { + load_default(); + } else if(pos_profiles.length === 1) { // load profile directly on_submit({pos_profile: pos_profiles[0]}); } else { From cbaa0e629cc47e665993438f23c97bb03dfd40ab Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 3 Nov 2017 11:35:49 +0530 Subject: [PATCH 6/6] fix codacy --- erpnext/selling/page/point_of_sale/point_of_sale.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index c9893f1ce8..2f6ccdb7b7 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -322,7 +322,7 @@ erpnext.pos.PointOfSale = class PointOfSale { [{ fieldtype: 'Select', label: 'POS Profile', options: pos_profiles }], on_submit, __('Select POS Profile') - ) + ); } } }); @@ -341,7 +341,7 @@ erpnext.pos.PointOfSale = class PointOfSale { } }); }); - } + } setup_company() { this.company = frappe.sys_defaults.company;