diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json index 31315e4c710f..a2497838eed1 100644 --- a/erpnext/accounts/desk_page/accounting/accounting.json +++ b/erpnext/accounts/desk_page/accounting/accounting.json @@ -147,10 +147,15 @@ "link_to": "Trial Balance", "type": "Report" }, + { + "label": "Point of Sale", + "link_to": "point-of-sale", + "type": "Page" + }, { "label": "Dashboard", "link_to": "Accounts", "type": "Dashboard" } ] -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.json b/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.json index 597519858ae5..4c1be6517cf2 100644 --- a/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.json +++ b/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.json @@ -1,426 +1,123 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "", - "beta": 0, - "creation": "2018-01-23 05:40:18.117583", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "creation": "2018-01-23 05:40:18.117583", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "loyalty_program", + "loyalty_program_tier", + "customer", + "invoice_type", + "invoice", + "redeem_against", + "loyalty_points", + "purchase_amount", + "expiry_date", + "posting_date", + "company" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "loyalty_program", - "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": "Loyalty Program", - "length": 0, - "no_copy": 0, - "options": "Loyalty Program", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "loyalty_program", + "fieldtype": "Link", + "label": "Loyalty Program", + "options": "Loyalty Program" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "loyalty_program_tier", - "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": "Loyalty Program Tier", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "loyalty_program_tier", + "fieldtype": "Data", + "label": "Loyalty Program Tier" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "customer", - "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": "Customer", - "length": 0, - "no_copy": 0, - "options": "Customer", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "customer", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Customer", + "options": "Customer" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sales_invoice", - "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": "Sales Invoice", - "length": 0, - "no_copy": 0, - "options": "Sales Invoice", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "redeem_against", + "fieldtype": "Link", + "label": "Redeem Against", + "options": "Loyalty Point Entry" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "redeem_against", - "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": "Redeem Against", - "length": 0, - "no_copy": 0, - "options": "Loyalty Point Entry", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "loyalty_points", + "fieldtype": "Int", + "in_list_view": 1, + "label": "Loyalty Points" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "loyalty_points", - "fieldtype": "Int", - "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": "Loyalty Points", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "purchase_amount", + "fieldtype": "Currency", + "label": "Purchase Amount" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "purchase_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": "Purchase Amount", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "expiry_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Expiry Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "expiry_date", - "fieldtype": "Date", - "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": "Expiry Date", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "posting_date", + "fieldtype": "Date", + "label": "Posting Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "posting_date", - "fieldtype": "Date", - "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": "Posting Date", - "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, - "translatable": 0, - "unique": 0 - }, + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "company", - "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": "Company", - "length": 0, - "no_copy": 0, - "options": "Company", - "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, - "translatable": 0, - "unique": 0 + "fieldname": "invoice_type", + "fieldtype": "Link", + "label": "Invoice Type", + "options": "DocType" + }, + { + "fieldname": "invoice", + "fieldtype": "Dynamic Link", + "in_list_view": 1, + "label": "Invoice", + "options": "invoice_type" } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 1, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-29 16:05:22.810347", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Loyalty Point Entry", - "name_case": "", - "owner": "Administrator", + ], + "in_create": 1, + "modified": "2020-01-30 17:27:55.964242", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Loyalty Point Entry", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Auditor", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Auditor" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User" } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "customer", - "track_changes": 1, - "track_seen": 0 + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "customer", + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py b/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py index d65a7d88e639..3579a1a96047 100644 --- a/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py +++ b/erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py @@ -18,7 +18,7 @@ def get_loyalty_point_entries(customer, loyalty_program, company, expiry_date=No date = today() return frappe.db.sql(''' - select name, loyalty_points, expiry_date, loyalty_program_tier, sales_invoice + select name, loyalty_points, expiry_date, loyalty_program_tier, invoice_type, invoice from `tabLoyalty Point Entry` where customer=%s and loyalty_program=%s and expiry_date>=%s and loyalty_points>0 and company=%s diff --git a/erpnext/accounts/doctype/loyalty_program/loyalty_program.py b/erpnext/accounts/doctype/loyalty_program/loyalty_program.py index 563165b2cc8d..cb753a3723df 100644 --- a/erpnext/accounts/doctype/loyalty_program/loyalty_program.py +++ b/erpnext/accounts/doctype/loyalty_program/loyalty_program.py @@ -36,7 +36,8 @@ def get_loyalty_details(customer, loyalty_program, expiry_date=None, company=Non return {"loyalty_points": 0, "total_spent": 0} @frappe.whitelist() -def get_loyalty_program_details_with_points(customer, loyalty_program=None, expiry_date=None, company=None, silent=False, include_expired_entry=False, current_transaction_amount=0): +def get_loyalty_program_details_with_points(customer, loyalty_program=None, expiry_date=None, company=None, \ + silent=False, include_expired_entry=False, current_transaction_amount=0): lp_details = get_loyalty_program_details(customer, loyalty_program, company=company, silent=silent) loyalty_program = frappe.get_doc("Loyalty Program", loyalty_program) lp_details.update(get_loyalty_details(customer, loyalty_program.name, expiry_date, company, include_expired_entry)) @@ -59,10 +60,10 @@ def get_loyalty_program_details(customer, loyalty_program=None, expiry_date=None if not loyalty_program: loyalty_program = frappe.db.get_value("Customer", customer, "loyalty_program") - if not (loyalty_program or silent): + if not loyalty_program and not silent: frappe.throw(_("Customer isn't enrolled in any Loyalty Program")) elif silent and not loyalty_program: - return frappe._dict({"loyalty_program": None}) + return frappe._dict({"loyalty_programs": None}) if not company: company = frappe.db.get_default("company") or frappe.get_all("Company")[0].name diff --git a/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py b/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py index 341884c19013..ee73ccaa611e 100644 --- a/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py +++ b/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py @@ -27,7 +27,7 @@ def test_loyalty_points_earned_single_tier(self): customer = frappe.get_doc('Customer', {"customer_name": "Test Loyalty Customer"}) earned_points = get_points_earned(si_original) - lpe = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer}) + lpe = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si_original.name, 'customer': si_original.customer}) self.assertEqual(si_original.get('loyalty_program'), customer.loyalty_program) self.assertEqual(lpe.get('loyalty_program_tier'), customer.loyalty_program_tier) @@ -42,8 +42,8 @@ def test_loyalty_points_earned_single_tier(self): earned_after_redemption = get_points_earned(si_redeem) - lpe_redeem = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_redeem.name, 'redeem_against': lpe.name}) - lpe_earn = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_redeem.name, 'name': ['!=', lpe_redeem.name]}) + lpe_redeem = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si_redeem.name, 'redeem_against': lpe.name}) + lpe_earn = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si_redeem.name, 'name': ['!=', lpe_redeem.name]}) self.assertEqual(lpe_earn.loyalty_points, earned_after_redemption) self.assertEqual(lpe_redeem.loyalty_points, (-1*earned_points)) @@ -66,7 +66,7 @@ def test_loyalty_points_earned_multiple_tier(self): earned_points = get_points_earned(si_original) - lpe = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer}) + lpe = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si_original.name, 'customer': si_original.customer}) self.assertEqual(si_original.get('loyalty_program'), customer.loyalty_program) self.assertEqual(lpe.get('loyalty_program_tier'), customer.loyalty_program_tier) @@ -82,8 +82,8 @@ def test_loyalty_points_earned_multiple_tier(self): customer = frappe.get_doc('Customer', {"customer_name": "Test Loyalty Customer"}) earned_after_redemption = get_points_earned(si_redeem) - lpe_redeem = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_redeem.name, 'redeem_against': lpe.name}) - lpe_earn = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_redeem.name, 'name': ['!=', lpe_redeem.name]}) + lpe_redeem = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si_redeem.name, 'redeem_against': lpe.name}) + lpe_earn = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si_redeem.name, 'name': ['!=', lpe_redeem.name]}) self.assertEqual(lpe_earn.loyalty_points, earned_after_redemption) self.assertEqual(lpe_redeem.loyalty_points, (-1*earned_points)) @@ -101,7 +101,7 @@ def test_cancel_sales_invoice(self): si.insert() si.submit() - lpe = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si.name, 'customer': si.customer}) + lpe = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si.name, 'customer': si.customer}) self.assertEqual(True, not (lpe is None)) # cancelling sales invoice @@ -118,7 +118,7 @@ def test_sales_invoice_return(self): si_original.submit() earned_points = get_points_earned(si_original) - lpe_original = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer}) + lpe_original = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si_original.name, 'customer': si_original.customer}) self.assertEqual(lpe_original.loyalty_points, earned_points) # create sales invoice return @@ -130,10 +130,10 @@ def test_sales_invoice_return(self): si_return.submit() # fetch original invoice again as its status would have been updated - si_original = frappe.get_doc('Sales Invoice', lpe_original.sales_invoice) + si_original = frappe.get_doc('Sales Invoice', lpe_original.invoice) earned_points = get_points_earned(si_original) - lpe_after_return = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer}) + lpe_after_return = frappe.get_doc('Loyalty Point Entry', {'invoice_type': 'Sales Invoice', 'invoice': si_original.name, 'customer': si_original.customer}) self.assertEqual(lpe_after_return.loyalty_points, earned_points) self.assertEqual(True, (lpe_original.loyalty_points > lpe_after_return.loyalty_points)) diff --git a/erpnext/accounts/page/pos/__init__.py b/erpnext/accounts/doctype/pos_closing_entry/__init__.py similarity index 100% rename from erpnext/accounts/page/pos/__init__.py rename to erpnext/accounts/doctype/pos_closing_entry/__init__.py diff --git a/erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html b/erpnext/accounts/doctype/pos_closing_entry/closing_voucher_details.html similarity index 71% rename from erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html rename to erpnext/accounts/doctype/pos_closing_entry/closing_voucher_details.html index 2412b071b968..983f49563cd9 100644 --- a/erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html +++ b/erpnext/accounts/doctype/pos_closing_entry/closing_voucher_details.html @@ -12,15 +12,15 @@
{{ _("Account") }} | {{ _("Rate") }} | {{ _("Amount") }} | |
---|---|---|---|
{{ d.account_head }} | {{ d.rate }} % | -{{ d.amount }} {{ currency.symbol }} | +{{ frappe.utils.fmt_money(d.amount, currency=currency) }} |
' + html + '
') - .get(0); - } - }); - - this.prepare_customer_mapper() - this.autocomplete_customers(); - - this.party_field.$input - .on('input', function (e) { - if(me.customers_mapper.length <= 1) { - me.prepare_customer_mapper(e.target.value); - } - me.party_field.awesomeplete.list = me.customers_mapper; - }) - .on('awesomplete-select', function (e) { - var customer = me.party_field.awesomeplete - .get_item(e.originalEvent.text.value); - if (!customer) return; - // create customer link - if (customer.action) { - 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(); - me.list_customers_btn.removeClass("view_customer"); - }) - .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 - .get_item(e.originalEvent.text.value); - // clear text input if item is action - if (item.action) { - $(this).val(""); - } - me.make_item_list(item.customer_name); - }); - }, - - prepare_customer_mapper: function(key) { - var me = this; - var customer_data = ''; - - if (key) { - key = key.toLowerCase().trim(); - var re = new RegExp('%', 'g'); - var reg = new RegExp(key.replace(re, '\\w*\\s*[a-zA-Z0-9]*')); - - customer_data = $.grep(this.customers, function(data) { - contact = me.contacts[data.name]; - if(reg.test(data.name.toLowerCase()) - || reg.test(data.customer_name.toLowerCase()) - || (contact && reg.test(contact["phone"])) - || (contact && reg.test(contact["mobile_no"])) - || (data.customer_group && reg.test(data.customer_group.toLowerCase()))){ - return data; - } - }) - } else { - customer_data = this.customers; - } - - this.customers_mapper = []; - - customer_data.forEach(function (c, index) { - if(index < 30) { - contact = me.contacts[c.name]; - if(contact && !c['phone']) { - c["phone"] = contact["phone"]; - c["email_id"] = contact["email_id"]; - c["mobile_no"] = contact["mobile_no"]; - } - - me.customers_mapper.push({ - label: c.name, - value: c.name, - customer_name: c.customer_name, - customer_group: c.customer_group, - territory: c.territory, - phone: contact ? contact["phone"] : '', - mobile_no: contact ? contact["mobile_no"] : '', - email_id: contact ? contact["email_id"] : '', - searchtext: ['customer_name', 'customer_group', 'name', 'value', - 'label', 'email_id', 'phone', 'mobile_no'] - .map(key => c[key]).join(' ') - .toLowerCase() - }); - } else { - return; - } - }); - - this.customers_mapper.push({ - label: "" - + " " - + __("Create a new Customer") - + "", - value: 'is_action', - action: me.add_customer - }); - }, - - autocomplete_customers: function() { - this.party_field.awesomeplete.list = this.customers_mapper; - }, - - 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(true); - this.numeric_keypad.show(); - }, - - update_customer: function (new_customer) { - var me = this; - - this.customer_doc = new frappe.ui.Dialog({ - 'title': 'Customer', - fields: [ - { - "label": __("Full Name"), - "fieldname": "full_name", - "fieldtype": "Data", - "reqd": 1 - }, - { - "fieldtype": "Section Break" - }, - { - "label": __("Email Id"), - "fieldname": "email_id", - "fieldtype": "Data" - }, - { - "fieldtype": "Column Break" - }, - { - "label": __("Contact Number"), - "fieldname": "phone", - "fieldtype": "Data" - }, - { - "fieldtype": "Section Break" - }, - { - "label": __("Address Name"), - "read_only": 1, - "fieldname": "name", - "fieldtype": "Data" - }, - { - "label": __("Address Line 1"), - "fieldname": "address_line1", - "fieldtype": "Data" - }, - { - "label": __("Address Line 2"), - "fieldname": "address_line2", - "fieldtype": "Data" - }, - { - "fieldtype": "Column Break" - }, - { - "label": __("City"), - "fieldname": "city", - "fieldtype": "Data" - }, - { - "label": __("State"), - "fieldname": "state", - "fieldtype": "Data" - }, - { - "label": __("ZIP Code"), - "fieldname": "pincode", - "fieldtype": "Data" - }, - { - "label": __("Customer POS Id"), - "fieldname": "customer_pos_id", - "fieldtype": "Data", - "hidden": 1 - } - ] - }) - this.customer_doc.show() - this.render_address_data() - - this.customer_doc.set_primary_action(__("Save"), function () { - me.make_offline_customer(new_customer); - me.pos_bill.show(); - me.list_customers.hide(); - }); - }, - - render_address_data: function() { - var me = this; - this.address_data = this.address[this.frm.doc.customer] || {}; - if(!this.address_data.email_id || !this.address_data.phone) { - this.address_data = this.contacts[this.frm.doc.customer]; - } - - 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) - } - - if(!this.customer_doc.fields_dict.customer_pos_id.value) { - this.customer_doc.set_value("customer_pos_id", frappe.datetime.now_datetime()) - } - }, - - get_address_from_localstorage: function() { - this.address_details = this.get_customers_details() - return this.address_details[this.frm.doc.customer] - }, - - make_offline_customer: function(new_customer) { - this.frm.doc.customer = this.frm.doc.customer || this.customer_doc.get_values().full_name; - this.frm.doc.customer_pos_id = this.customer_doc.fields_dict.customer_pos_id.value; - 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.update_address_and_customer_list(new_customer) - this.autocomplete_customers(); - this.update_customer_in_localstorage() - this.update_customer_in_localstorage() - this.customer_doc.hide() - }, - - update_address_and_customer_list: function(new_customer) { - var me = this; - if(new_customer) { - this.customers_mapper.push({ - label: this.frm.doc.customer, - value: this.frm.doc.customer, - customer_group: "", - territory: "" - }); - } - - this.address[this.frm.doc.customer] = JSON.parse(this.get_prompt_details()) - }, - - get_prompt_details: function() { - this.prompt_details = this.customer_doc.get_values(); - this.prompt_details['country'] = this.pos_profile_data.country; - this.prompt_details['territory'] = this.pos_profile_data["territory"]; - this.prompt_details['customer_group'] = this.pos_profile_data["customer_group"]; - this.prompt_details['customer_pos_id'] = this.customer_doc.fields_dict.customer_pos_id.value; - return JSON.stringify(this.prompt_details) - }, - - update_customer_data: function (doc) { - var me = this; - this.frm.doc.customer = doc.label || doc.name; - this.frm.doc.customer_name = doc.customer_name; - this.frm.doc.customer_group = doc.customer_group; - this.frm.doc.territory = doc.territory; - this.pos_bill.show(); - this.numeric_keypad.show(); - }, - - make_item_list: function (customer) { - var me = this; - if (!this.price_list) { - frappe.msgprint(__("Price List not found or disabled")); - return; - } - - me.item_timeout = null; - - var $wrap = me.wrapper.find(".item-list"); - me.wrapper.find(".item-list").empty(); - - if (this.items.length > 0) { - $.each(this.items, function(index, obj) { - let customer_price_list = me.customer_wise_price_list[customer]; - let item_price - if (customer && customer_price_list && customer_price_list[obj.name]) { - item_price = format_currency(customer_price_list[obj.name], me.frm.doc.currency); - } else { - item_price = format_currency(me.price_list_data[obj.name], me.frm.doc.currency); - } - if(index < me.page_len) { - $(frappe.render_template("pos_item", { - item_code: obj.name, - item_price: item_price, - item_name: obj.name === obj.item_name ? "" : obj.item_name, - item_image: obj.image, - item_stock: __('Stock Qty') + ": " + me.get_actual_qty(obj), - item_uom: obj.stock_uom, - color: frappe.get_palette(obj.item_name), - abbr: frappe.get_abbr(obj.item_name) - })).tooltip().appendTo($wrap); - } - }); - - $wrap.append(` -" - +__("Not items found")+"
").appendTo($wrap) - } - - if (this.items.length == 1 - && this.search_item.$input.val()) { - this.search_item.$input.val(""); - this.add_to_cart(); - } - }, - - get_items: function (item_code) { - // To search item as per the key enter - - var me = this; - this.item_serial_no = {}; - this.item_batch_no = {}; - - if (item_code) { - return $.grep(this.item_data, function (item) { - if (item.item_code == item_code) { - return true - } - }) - } - - this.items_list = this.apply_category(); - - key = this.search_item.$input.val().toLowerCase().replace(/[&\/\\#,+()\[\]$~.'":*?<>{}]/g, '\\$&'); - var re = new RegExp('%', 'g'); - var reg = new RegExp(key.replace(re, '[\\w*\\s*[a-zA-Z0-9]*]*')) - search_status = true - - if (key) { - return $.grep(this.items_list, function (item) { - if (search_status) { - if (me.batch_no_data[item.item_code] && - in_list(me.batch_no_data[item.item_code], me.search_item.$input.val())) { - search_status = false; - return me.item_batch_no[item.item_code] = me.search_item.$input.val() - } else if (me.serial_no_data[item.item_code] - && in_list(Object.keys(me.serial_no_data[item.item_code]), me.search_item.$input.val())) { - search_status = false; - me.item_serial_no[item.item_code] = [me.search_item.$input.val(), me.serial_no_data[item.item_code][me.search_item.$input.val()]] - return true - } else if (me.barcode_data[item.item_code] && - in_list(me.barcode_data[item.item_code], me.search_item.$input.val())) { - search_status = false; - return true; - } else if (reg.test(item.item_code.toLowerCase()) || (item.description && reg.test(item.description.toLowerCase())) || - reg.test(item.item_name.toLowerCase()) || reg.test(item.item_group.toLowerCase())) { - return true - } - } - }) - } else { - return this.items_list; - } - }, - - apply_category: function() { - var me = this; - category = this.selected_item_group || "All Item Groups"; - if(category == 'All Item Groups') { - return this.item_data - } else { - return this.item_data.filter(function(element, index, array){ - return element.item_group == category; - }); - } - }, - - 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).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.update_value(); - }) - - $(this.wrapper).on("focusout", ".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, true); - me.update_value(); - }) - - $(this.wrapper).find("[data-action='increase-qty']").on("click", function () { - var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); - var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) + 1; - me.update_qty(item_code, qty); - }) - - $(this.wrapper).find("[data-action='decrease-qty']").on("click", function () { - var item_code = $(this).parents(".pos-bill-item").attr("data-item-code"); - var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) - 1; - me.update_qty(item_code, qty); - }) - - $(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(); - if(discount > 100){ - discount = $(this).val(''); - frappe.show_alert({ - indicator: 'red', - message: __('Discount amount cannot be greater than 100%') - }); - me.update_discount(item_code, discount); - }else{ - me.update_discount(item_code, discount); - me.update_value(); - } - }) - }, - - 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 () { - me.item_code = ''; - me.customer_validate(); - if($(me.pos_bill).is(":hidden")) return; - - if (me.frm.doc.docstatus == 0) { - me.items = me.get_items($(this).attr("data-item-code")) - me.add_to_cart(); - me.clear_selected_row(); - } - }); - - me.bind_delete_event() - }, - - update_qty: function (item_code, qty, remove_zero_qty_items) { - var me = this; - this.items = this.get_items(item_code); - this.validate_serial_no() - this.set_item_details(item_code, "qty", qty, remove_zero_qty_items); - }, - - update_discount: function(item_code, discount) { - var me = this; - this.items = this.get_items(item_code); - this.set_item_details(item_code, "discount_percentage", discount); - }, - - update_rate: function () { - var me = this; - $(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()); - me.update_value() - }) - }, - - update_value: function() { - var me = this; - var fields = {qty: ".pos-item-qty", "discount_percentage": ".pos-item-disc", - "rate": ".pos-item-price", "amount": ".pos-amount"} - this.child_doc = this.get_child_item(this.item_code); - - if(me.child_doc.length) { - $.each(fields, function(key, field) { - $(me.selected_row).find(field).val(me.child_doc[0][key]) - }) - } else { - this.clear_selected_row(); - } - }, - - clear_selected_row: function() { - $(this.wrapper).find('.selected-item').empty(); - }, - - render_selected_item: function() { - this.child_doc = this.get_child_item(this.item_code); - $(this.wrapper).find('.selected-item').empty(); - if(this.child_doc.length) { - this.child_doc[0]["allow_user_to_edit_rate"] = this.pos_profile_data["allow_user_to_edit_rate"] ? true : false, - this.child_doc[0]["allow_user_to_edit_discount"] = this.pos_profile_data["allow_user_to_edit_discount"] ? true : false; - this.selected_row = $(frappe.render_template("pos_selected_item", this.child_doc[0])) - $(this.wrapper).find('.selected-item').html(this.selected_row) - } - - $(this.selected_row).find('.form-control').click(function(){ - $(this).select(); - }) - }, - - 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, remove_zero_qty_items) { - var me = this; - if (value < 0) { - frappe.throw(__("Enter value must be positive")); - } - - this.remove_item = [] - $.each(this.frm.doc["items"] || [], function (i, d) { - if (d.item_code == item_code) { - if (d.serial_no && field == 'qty') { - me.validate_serial_no_qty(d, item_code, field, value) - } - - d[field] = flt(value); - d.amount = flt(d.rate) * flt(d.qty); - if (d.qty == 0 && remove_zero_qty_items) { - me.remove_item.push(d.idx) - } - - if(field=="discount_percentage" && value == 0) { - d.rate = d.price_list_rate; - } - } - }); - - if (field == 'qty') { - this.remove_zero_qty_items_from_cart(); - } - - this.update_paid_amount_status(false) - }, - - remove_zero_qty_items_from_cart: function () { - var me = this; - var idx = 0; - this.items = [] - $.each(this.frm.doc["items"] || [], function (i, d) { - if (!in_list(me.remove_item, d.idx)) { - d.idx = idx; - me.items.push(d); - idx++; - } - }); - - this.frm.doc["items"] = this.items; - }, - - make_discount_field: function () { - var me = this; - - this.wrapper.find('input.discount-percentage').on("change", function () { - me.frm.doc.additional_discount_percentage = flt($(this).val(), precision("additional_discount_percentage")); - - if(me.frm.doc.additional_discount_percentage && me.frm.doc.discount_amount) { - // Reset discount amount - me.frm.doc.discount_amount = 0; - } - - var total = me.frm.doc.grand_total - - if (me.frm.doc.apply_discount_on == 'Net Total') { - total = me.frm.doc.net_total - } - - me.frm.doc.discount_amount = flt(total * flt(me.frm.doc.additional_discount_percentage) / 100, precision("discount_amount")); - me.refresh(); - me.wrapper.find('input.discount-amount').val(me.frm.doc.discount_amount) - }); - - this.wrapper.find('input.discount-amount').on("change", function () { - me.frm.doc.discount_amount = flt($(this).val(), precision("discount_amount")); - me.frm.doc.additional_discount_percentage = 0.0; - me.refresh(); - me.wrapper.find('input.discount-percentage').val(0); - }); - }, - - customer_validate: function () { - var me = this; - if (!this.frm.doc.customer || this.party_field.get_value() == "") { - frappe.throw(__("Please select customer")) - } - }, - - add_to_cart: function () { - var me = this; - var caught = false; - var no_of_items = me.wrapper.find(".pos-bill-item").length; - - this.customer_validate(); - this.mandatory_batch_no(); - this.validate_serial_no(); - this.validate_warehouse(); - - if (no_of_items != 0) { - $.each(this.frm.doc["items"] || [], function (i, d) { - if (d.item_code == me.items[0].item_code) { - caught = true; - d.qty += 1; - d.amount = flt(d.rate) * flt(d.qty); - if (me.item_serial_no[d.item_code]) { - d.serial_no += '\n' + me.item_serial_no[d.item_code][0] - d.warehouse = me.item_serial_no[d.item_code][1] - } - - if (me.item_batch_no.length) { - d.batch_no = me.item_batch_no[d.item_code] - } - } - }); - } - - // if item not found then add new item - if (!caught) - 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 () { - var me = this; - this.child = frappe.model.add_child(this.frm.doc, this.frm.doc.doctype + " Item", "items"); - this.child.item_code = this.items[0].item_code; - this.child.item_name = this.items[0].item_name; - this.child.stock_uom = this.items[0].stock_uom; - this.child.uom = this.items[0].sales_uom || this.items[0].stock_uom; - this.child.conversion_factor = this.items[0].conversion_factor || 1; - this.child.brand = this.items[0].brand; - this.child.description = this.items[0].description || this.items[0].item_name; - 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; - this.child.income_account = this.pos_profile_data['income_account'] || this.items[0].income_account; - this.child.warehouse = (this.item_serial_no[this.child.item_code] - ? this.item_serial_no[this.child.item_code][1] : (this.pos_profile_data['warehouse'] || this.items[0].default_warehouse)); - - customer = this.frm.doc.customer; - let rate; - - customer_price_list = this.customer_wise_price_list[customer] - if (customer_price_list && customer_price_list[this.child.item_code]){ - rate = flt(this.customer_wise_price_list[customer][this.child.item_code] * this.child.conversion_factor, 9) / flt(this.frm.doc.conversion_rate, 9); - } - else{ - rate = flt(this.price_list_data[this.child.item_code] * this.child.conversion_factor, 9) / flt(this.frm.doc.conversion_rate, 9); - } - - this.child.price_list_rate = rate; - this.child.rate = rate; - this.child.actual_qty = me.get_actual_qty(this.items[0]); - this.child.amount = flt(this.child.qty) * flt(this.child.rate); - this.child.batch_no = this.item_batch_no[this.child.item_code]; - this.child.serial_no = (this.item_serial_no[this.child.item_code] - ? this.item_serial_no[this.child.item_code][0] : ''); - this.child.item_tax_rate = JSON.stringify(this.tax_data[this.child.item_code]); - }, - - update_paid_amount_status: function (update_paid_amount) { - if (this.frm.doc.offline_pos_name) { - update_paid_amount = update_paid_amount ? false : true; - } - - this.refresh(update_paid_amount); - }, - - refresh: function (update_paid_amount) { - var me = this; - this.refresh_fields(update_paid_amount); - this.set_primary_action(); - }, - - refresh_fields: function (update_paid_amount) { - this.apply_pricing_rule(); - this.discount_amount_applied = false; - this._calculate_taxes_and_totals(); - this.calculate_discount_amount(); - this.show_items_in_item_cart(); - this.set_taxes(); - this.calculate_outstanding_amount(update_paid_amount); - this.set_totals(); - this.update_total_qty(); - }, - - get_company_currency: function () { - return erpnext.get_currency(this.frm.doc.company); - }, - - 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_new", { - item_code: d.item_code, - item_name: (d.item_name === d.item_code || !d.item_name) ? "" : ("\n\t{{ doc.company }}
\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t{{ _(\"GSTIN\") }}:{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"
GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t
\n\t{% if doc.docstatus == 0 %}\n\t\t{{ doc.status + \" \"+ (doc.select_print_heading or _(\"Invoice\")) }}
\n\t{% else %}\n\t\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n\t{% endif %}\n
\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{{ _(\"Customer\") }}:
\n\t\t{{ doc.customer_name }}
\n\t\t{{ customer_address }}\n\t{% endif %}\n
{{ _(\"Item\") }} | \n\t\t\t{{ _(\"Qty\") }} | \n\t\t\t{{ _(\"Amount\") }} | \n\t\t
---|---|---|
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t {{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t {{ _(\"HSN/SAC\") }}: {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t {{ _(\"Serial No\") }}: {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ item.rate }} | \n\t\t\t{{ item.get_formatted(\"amount\") }} | \n\t\t
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t | \n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t | \n\t\t\t{% endif %}\n\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t | \n\t\t\t||
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t | \n\t\t
{{ doc.terms or \"\" }}
\n{{ _(\"Thank you, please visit again.\") }}
", + "html": "\n\n{% if letter_head %}\n {{ letter_head }}\n{% endif %}\n\n\t{{ doc.company }}
\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t{{ _(\"GSTIN\") }}:{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"
GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t
\n\t{% if doc.docstatus == 0 %}\n\t\t{{ doc.status + \" \"+ (doc.select_print_heading or _(\"Invoice\")) }}
\n\t{% else %}\n\t\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n\t{% endif %}\n
\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{{ _(\"Customer\") }}:
\n\t\t{{ doc.customer_name }}
\n\t\t{{ customer_address }}\n\t{% endif %}\n
{{ _(\"Item\") }} | \n\t\t\t{{ _(\"Qty\") }} | \n\t\t\t{{ _(\"Amount\") }} | \n\t\t
---|---|---|
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t {{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t {{ _(\"HSN/SAC\") }}: {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t {{ _(\"Serial No\") }}: {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ item.rate }} | \n\t\t\t{{ item.get_formatted(\"amount\") }} | \n\t\t
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t | \n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t | \n\t\t\t{% endif %}\n\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t | \n\t\t\t||
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t | \n\t\t
{{ doc.terms or \"\" }}
\n{{ _(\"Thank you, please visit again.\") }}
", "idx": 0, "line_breaks": 0, - "modified": "2019-12-09 17:39:23.356573", + "modified": "2020-04-29 16:39:12.936215", "modified_by": "Administrator", "module": "Accounts", "name": "GST POS Invoice", diff --git a/erpnext/accounts/print_format/pos_invoice/pos_invoice.json b/erpnext/accounts/print_format/pos_invoice/pos_invoice.json index be699228c52f..13a973d2341a 100644 --- a/erpnext/accounts/print_format/pos_invoice/pos_invoice.json +++ b/erpnext/accounts/print_format/pos_invoice/pos_invoice.json @@ -6,10 +6,10 @@ "doc_type": "Sales Invoice", "docstatus": 0, "doctype": "Print Format", - "html": "\n\n{% if letter_head %}\n {{ letter_head }}\n{% endif %}\n\n\n\t{{ doc.company }}
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n
\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{{ _(\"Customer\") }}: {{ doc.customer_name }}\n
{{ _(\"Item\") }} | \n\t\t\t{{ _(\"Qty\") }} | \n\t\t\t{{ _(\"Amount\") }} | \n\t\t
---|---|---|
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t {{ item.item_name }}{%- endif -%}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ item.get_formatted(\"rate\") }} | \n\t\t\t{{ item.get_formatted(\"amount\") }} | \n\t\t
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t | \n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t | \n\t\t\t{% endif %}\n\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t | \n\t\t\t||
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t\t | \n\t\t\t
{{ doc.terms or \"\" }}
\n{{ _(\"Thank you, please visit again.\") }}
", + "html": "\n\n{% if letter_head %}\n {{ letter_head }}\n{% endif %}\n\n\n\t{{ doc.company }}
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n
\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{{ _(\"Customer\") }}: {{ doc.customer_name }}\n
{{ _(\"Item\") }} | \n\t\t\t{{ _(\"Qty\") }} | \n\t\t\t{{ _(\"Amount\") }} | \n\t\t
---|---|---|
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t {{ item.item_name }}{%- endif -%}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ item.get_formatted(\"rate\") }} | \n\t\t\t{{ item.get_formatted(\"amount\") }} | \n\t\t
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t | \n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t | \n\t\t\t{% endif %}\n\t\t
\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t | \n\t\t\t||
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t\t | \n\t\t\t
{{ doc.terms or \"\" }}
\n{{ _(\"Thank you, please visit again.\") }}
", "idx": 1, "line_breaks": 0, - "modified": "2019-12-09 17:40:53.183574", + "modified": "2020-04-29 16:35:07.043058", "modified_by": "Administrator", "module": "Accounts", "name": "POS Invoice", diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 90c67f1e5214..3f127a201efc 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -213,7 +213,7 @@ def set_missing_values(source, target): doc.return_against = source.name doc.ignore_pricing_rule = 1 doc.set_warehouse = "" - if doctype == "Sales Invoice": + if doctype == "Sales Invoice" or doctype == "POS Invoice": doc.is_pos = source.is_pos # look for Print Heading "Credit Note" @@ -229,7 +229,7 @@ def set_missing_values(source, target): tax.tax_amount = -1 * tax.tax_amount if doc.get("is_return"): - if doc.doctype == 'Sales Invoice': + if doc.doctype == 'Sales Invoice' or doc.doctype == 'POS Invoice': doc.set('payments', []) for data in source.payments: paid_amount = 0.00 @@ -241,8 +241,11 @@ def set_missing_values(source, target): 'mode_of_payment': data.mode_of_payment, 'type': data.type, 'amount': -1 * paid_amount, - 'base_amount': -1 * base_paid_amount + 'base_amount': -1 * base_paid_amount, + 'account': data.account }) + if doc.is_pos: + doc.paid_amount = -1 * source.paid_amount elif doc.doctype == 'Purchase Invoice': doc.paid_amount = -1 * source.paid_amount doc.base_paid_amount = -1 * source.base_paid_amount @@ -287,7 +290,7 @@ def update_item(source_doc, target_doc, source_parent): target_doc.dn_detail = source_doc.name if default_warehouse_for_sales_return: target_doc.warehouse = default_warehouse_for_sales_return - elif doctype == "Sales Invoice": + elif doctype == "Sales Invoice" or doctype == "POS Invoice": target_doc.sales_order = source_doc.sales_order target_doc.delivery_note = source_doc.delivery_note target_doc.so_detail = source_doc.so_detail diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index b465a106f0e7..0dc9878afd03 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -85,6 +85,12 @@ def validate_status(status, options): "Bank Transaction": [ ["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"], ["Reconciled", "eval:self.docstatus == 1 and self.unallocated_amount<=0"] + ], + "POS Opening Entry": [ + ["Draft", None], + ["Open", "eval:self.docstatus == 1 and not self.pos_closing_entry"], + ["Closed", "eval:self.docstatus == 1 and self.pos_closing_entry"], + ["Cancelled", "eval:self.docstatus == 2"], ] } diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index 6449c71edded..572e1ca23974 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -370,7 +370,7 @@ def calculate_totals(self): self._set_in_company_currency(self.doc, ["total_taxes_and_charges", "rounding_adjustment"]) - if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]: + if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "POS Invoice"]: self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate, self.doc.precision("base_grand_total")) \ if self.doc.total_taxes_and_charges else self.doc.base_net_total else: @@ -619,17 +619,14 @@ def set_item_wise_tax_breakup(self): self.doc.other_charges_calculation = get_itemised_tax_breakup_html(self.doc) def update_paid_amount_for_return(self, total_amount_to_pay): - default_mode_of_payment = frappe.db.get_value('Sales Invoice Payment', - {'parent': self.doc.pos_profile, 'default': 1}, - ['mode_of_payment', 'type', 'account'], as_dict=1) + default_mode_of_payment = frappe.db.get_value('POS Payment Method', + {'parent': self.doc.pos_profile, 'default': 1}, ['mode_of_payment'], as_dict=1) self.doc.payments = [] if default_mode_of_payment: self.doc.append('payments', { 'mode_of_payment': default_mode_of_payment.mode_of_payment, - 'type': default_mode_of_payment.type, - 'account': default_mode_of_payment.account, 'amount': total_amount_to_pay }) else: diff --git a/erpnext/patches.txt b/erpnext/patches.txt index ea2611f6987e..2fb9d7f87014 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -14,6 +14,7 @@ erpnext.patches.v4_0.apply_user_permissions erpnext.patches.v4_0.move_warehouse_user_to_restrictions erpnext.patches.v4_0.global_defaults_to_system_settings erpnext.patches.v4_0.update_incharge_name_to_sales_person_in_maintenance_schedule +execute:frappe.reload_doc("accounts", "doctype", "POS Payment Method") #2020-05-28 execute:frappe.reload_doc("HR", "doctype", "HR Settings") #2020-01-16 execute:frappe.reload_doc('stock', 'doctype', 'warehouse') # 2017-04-24 execute:frappe.reload_doc('accounts', 'doctype', 'sales_invoice') # 2016-08-31 @@ -437,7 +438,6 @@ erpnext.patches.v8_5.remove_project_type_property_setter erpnext.patches.v8_7.sync_india_custom_fields erpnext.patches.v8_7.fix_purchase_receipt_status erpnext.patches.v8_6.rename_bom_update_tool -erpnext.patches.v8_7.set_offline_in_pos_settings #11-09-17 erpnext.patches.v8_9.add_setup_progress_actions #08-09-2017 #26-09-2017 #22-11-2017 #15-12-2017 erpnext.patches.v8_9.rename_company_sales_target_field erpnext.patches.v8_8.set_bom_rate_as_per_uom @@ -677,6 +677,8 @@ erpnext.patches.v12_0.update_end_date_and_status_in_email_campaign erpnext.patches.v13_0.move_tax_slabs_from_payroll_period_to_income_tax_slab #123 erpnext.patches.v12_0.fix_quotation_expired_status erpnext.patches.v12_0.update_appointment_reminder_scheduler_entry +erpnext.patches.v12_0.rename_pos_closing_doctype +erpnext.patches.v13_0.replace_pos_payment_mode_table erpnext.patches.v12_0.retain_permission_rules_for_video_doctype erpnext.patches.v12_0.remove_duplicate_leave_ledger_entries #2020-05-22 erpnext.patches.v13_0.patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive @@ -695,6 +697,7 @@ erpnext.patches.v12_0.update_bom_in_so_mr execute:frappe.delete_doc("Report", "Department Analytics") execute:frappe.rename_doc("Desk Page", "Loan Management", "Loan", force=True) erpnext.patches.v12_0.update_uom_conversion_factor +execute:frappe.delete_doc_if_exists("Page", "pos") #29-05-2020 erpnext.patches.v13_0.delete_old_purchase_reports erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions erpnext.patches.v13_0.update_subscription @@ -708,6 +711,7 @@ execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation") erpnext.patches.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020 erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020 erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020 +erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020 erpnext.patches.v12_0.add_taxjar_integration_field erpnext.patches.v13_0.delete_report_requested_items_to_order erpnext.patches.v12_0.update_item_tax_template_company diff --git a/erpnext/patches/v11_0/refactor_autoname_naming.py b/erpnext/patches/v11_0/refactor_autoname_naming.py index d67c7235e811..5dc5d3bf0cf3 100644 --- a/erpnext/patches/v11_0/refactor_autoname_naming.py +++ b/erpnext/patches/v11_0/refactor_autoname_naming.py @@ -54,7 +54,7 @@ 'Payroll Entry': 'HR-PRUN-.YYYY.-.#####', 'Period Closing Voucher': 'ACC-PCV-.YYYY.-.#####', 'Plant Analysis': 'AG-PLA-.YYYY.-.#####', - 'POS Closing Voucher': 'POS-CLO-.YYYY.-.#####', + 'POS Closing Entry': 'POS-CLO-.YYYY.-.#####', 'Prepared Report': 'SYS-PREP-.YYYY.-.#####', 'Program Enrollment': 'EDU-ENR-.YYYY.-.#####', 'Quotation Item': '', diff --git a/erpnext/patches/v12_0/rename_pos_closing_doctype.py b/erpnext/patches/v12_0/rename_pos_closing_doctype.py new file mode 100644 index 000000000000..8ca92ef65c65 --- /dev/null +++ b/erpnext/patches/v12_0/rename_pos_closing_doctype.py @@ -0,0 +1,25 @@ +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + if frappe.db.table_exists("POS Closing Voucher"): + if not frappe.db.exists("DocType", "POS Closing Entry"): + frappe.rename_doc('DocType', 'POS Closing Voucher', 'POS Closing Entry', force=True) + + if not frappe.db.exists('DocType', 'POS Closing Entry Taxes'): + frappe.rename_doc('DocType', 'POS Closing Voucher Taxes', 'POS Closing Entry Taxes', force=True) + + if not frappe.db.exists('DocType', 'POS Closing Voucher Details'): + frappe.rename_doc('DocType', 'POS Closing Voucher Details', 'POS Closing Entry Details', force=True) + + frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry') + frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry Taxes') + frappe.reload_doc('Accounts', 'doctype', 'POS Closing Entry Details') + + if frappe.db.exists("DocType", "POS Closing Voucher"): + frappe.delete_doc("DocType", "POS Closing Voucher") + frappe.delete_doc("DocType", "POS Closing Voucher Taxes") + frappe.delete_doc("DocType", "POS Closing Voucher Details") + frappe.delete_doc("DocType", "POS Closing Voucher Invoices") \ No newline at end of file diff --git a/erpnext/patches/v13_0/loyalty_points_entry_for_pos_invoice.py b/erpnext/patches/v13_0/loyalty_points_entry_for_pos_invoice.py new file mode 100644 index 000000000000..ee7734053c1d --- /dev/null +++ b/erpnext/patches/v13_0/loyalty_points_entry_for_pos_invoice.py @@ -0,0 +1,20 @@ +# Copyright (c) 2019, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe + +def execute(): + '''`sales_invoice` field from loyalty point entry is splitted into `invoice_type` & `invoice` fields''' + + frappe.reload_doc("Accounts", "doctype", "loyalty_point_entry") + + if not frappe.db.has_column('Loyalty Point Entry', 'sales_invoice'): + return + + frappe.db.sql( + """UPDATE `tabLoyalty Point Entry` lpe + SET lpe.`invoice_type` = 'Sales Invoice', lpe.`invoice` = lpe.`sales_invoice` + WHERE lpe.`sales_invoice` IS NOT NULL + AND (lpe.`invoice` IS NULL OR lpe.`invoice` = '')""") \ No newline at end of file diff --git a/erpnext/patches/v13_0/replace_pos_payment_mode_table.py b/erpnext/patches/v13_0/replace_pos_payment_mode_table.py new file mode 100644 index 000000000000..4a621b6a5149 --- /dev/null +++ b/erpnext/patches/v13_0/replace_pos_payment_mode_table.py @@ -0,0 +1,29 @@ +# Copyright (c) 2019, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe + +def execute(): + frappe.reload_doc("Selling", "doctype", "POS Payment Method") + pos_profiles = frappe.get_all("POS Profile") + + for pos_profile in pos_profiles: + if not pos_profile.get("payments"): return + + payments = frappe.db.sql(""" + select idx, parentfield, parenttype, parent, mode_of_payment, `default` from `tabSales Invoice Payment` where parent=%s + """, pos_profile.name, as_dict=1) + if payments: + for payment_mode in payments: + pos_payment_method = frappe.new_doc("POS Payment Method") + pos_payment_method.idx = payment_mode.idx + pos_payment_method.default = payment_mode.default + pos_payment_method.mode_of_payment = payment_mode.mode_of_payment + pos_payment_method.parent = payment_mode.parent + pos_payment_method.parentfield = payment_mode.parentfield + pos_payment_method.parenttype = payment_mode.parenttype + pos_payment_method.db_insert() + + frappe.db.sql("""delete from `tabSales Invoice Payment` where parent=%s""", pos_profile.name) diff --git a/erpnext/patches/v8_7/set_offline_in_pos_settings.py b/erpnext/patches/v8_7/set_offline_in_pos_settings.py deleted file mode 100644 index 7d2882e0641c..000000000000 --- a/erpnext/patches/v8_7/set_offline_in_pos_settings.py +++ /dev/null @@ -1,13 +0,0 @@ -# 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_doc('accounts', 'doctype', 'pos_field') - frappe.reload_doc('accounts', 'doctype', 'pos_settings') - - doc = frappe.get_doc('POS Settings') - doc.use_pos_in_offline_mode = 1 - doc.save() \ No newline at end of file diff --git a/erpnext/public/css/pos.css b/erpnext/public/css/pos.css index 613a5ffa6e6c..e80e3ed126d4 100644 --- a/erpnext/public/css/pos.css +++ b/erpnext/public/css/pos.css @@ -1,179 +1,216 @@ -[data-route="point-of-sale"] .layout-main-section-wrapper { - margin-bottom: 0; -} -[data-route="point-of-sale"] .pos-items-wrapper { - max-height: calc(100vh - 210px); -} -.pos { - padding: 15px; -} -.list-item { - min-height: 40px; - height: auto; -} -.cart-container { - padding: 0 15px; - display: inline-block; - width: 39%; - vertical-align: top; -} -.item-container { - padding: 0 15px; - display: inline-block; - width: 60%; - vertical-align: top; -} -.search-field { - width: 60%; -} -.search-field input::placeholder { - font-size: 12px; -} -.item-group-field { - width: 40%; - margin-left: 15px; -} -.cart-wrapper { - margin-bottom: 12px; -} -.cart-wrapper .list-item__content:not(:first-child) { - justify-content: flex-end; -} -.cart-wrapper .list-item--head .list-item__content:nth-child(2) { - flex: 1.5; -} -.cart-items { - height: 150px; - overflow: auto; -} -.cart-items .list-item.current-item { - background-color: #fffce7; -} -.cart-items .list-item.current-item.qty input { - border: 1px solid #5E64FF; - font-weight: bold; -} -.cart-items .list-item.current-item.disc .discount { - font-weight: bold; -} -.cart-items .list-item.current-item.rate .rate { - font-weight: bold; -} -.cart-items .list-item .quantity { - flex: 1.5; -} -.cart-items input { - text-align: right; - height: 22px; - font-size: 12px; -} -.fields { - display: flex; -} -.pos-items-wrapper { - max-height: 480px; - overflow-y: auto; -} -.pos-items { - overflow: hidden; -} -.pos-item-wrapper { - display: flex; - flex-direction: column; - position: relative; - width: 25%; -} -.image-view-container { - display: block; -} -.image-view-container .image-field { - height: auto; -} -.empty-state { - height: 100%; - position: relative; -} -.empty-state span { - position: absolute; - color: #8D99A6; - font-size: 12px; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} -@keyframes yellow-fade { - 0% { - background-color: #fffce7; - } - 100% { - background-color: transparent; - } -} -.highlight { - animation: yellow-fade 1s ease-in 1; -} -input[type=number]::-webkit-inner-spin-button, -input[type=number]::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; -} -.number-pad { - border-collapse: collapse; - cursor: pointer; - display: table; -} -.num-row { - display: table-row; -} -.num-col { - display: table-cell; - border: 1px solid #d1d8dd; -} -.num-col > div { - width: 50px; - height: 50px; - text-align: center; - line-height: 50px; -} -.num-col.active { - background-color: #fffce7; -} -.num-col.brand-primary { - background-color: #5E64FF; - color: #ffffff; -} -.discount-amount .discount-inputs { - display: flex; - flex-direction: column; - padding: 15px 0; -} -.discount-amount input:first-child { - margin-bottom: 10px; -} -.taxes-and-totals { - border-top: 1px solid #d1d8dd; -} -.taxes-and-totals .taxes { - display: flex; - flex-direction: column; - padding: 15px 0; - align-items: flex-end; -} -.taxes-and-totals .taxes > div:first-child { - margin-bottom: 10px; -} -.grand-total { - border-top: 1px solid #d1d8dd; -} -.grand-total .list-item { - height: 60px; -} -.grand-total .grand-total-value { - font-size: 18px; -} -.rounded-total-value { - font-size: 18px; -} -.quantity-total { - font-size: 18px; -} +[data-route="point-of-sale"] .layout-main-section { border: none; font-size: 12px; } +[data-route="point-of-sale"] .layout-main-section-wrapper { margin-bottom: 0; } +[data-route="point-of-sale"] .pos-items-wrapper { max-height: calc(100vh - 210px); } +:root { --border-color: #d1d8dd; --text-color: #8d99a6; --primary: #5e64ff; } +[data-route="point-of-sale"] .flex { display: flex; } +[data-route="point-of-sale"] .grid { display: grid; } +[data-route="point-of-sale"] .absolute { position: absolute; } +[data-route="point-of-sale"] .relative { position: relative; } +[data-route="point-of-sale"] .abs-center { top: 50%; left: 50%; transform: translate(-50%, -50%); } +[data-route="point-of-sale"] .inline { display: inline; } +[data-route="point-of-sale"] .float-right { float: right; } +[data-route="point-of-sale"] .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); } +[data-route="point-of-sale"] .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } +[data-route="point-of-sale"] .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } +[data-route="point-of-sale"] .grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } +[data-route="point-of-sale"] .grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } +[data-route="point-of-sale"] .grid-cols-10 { grid-template-columns: repeat(10, minmax(0, 1fr)); } +[data-route="point-of-sale"] .gap-2 { grid-gap: 0.5rem; gap: 0.5rem; } +[data-route="point-of-sale"] .gap-4 { grid-gap: 1rem; gap: 1rem; } +[data-route="point-of-sale"] .gap-6 { grid-gap: 1.25rem; gap: 1.25rem; } +[data-route="point-of-sale"] .gap-8 { grid-gap: 1.5rem; gap: 1.5rem; } +[data-route="point-of-sale"] .row-gap-2 { grid-row-gap: 0.5rem; row-gap: 0.5rem; } +[data-route="point-of-sale"] .col-gap-4 { grid-column-gap: 1rem; column-gap: 1rem; } +[data-route="point-of-sale"] .col-span-2 { grid-column: span 2 / span 2; } +[data-route="point-of-sale"] .col-span-3 { grid-column: span 3 / span 3; } +[data-route="point-of-sale"] .col-span-4 { grid-column: span 4 / span 4; } +[data-route="point-of-sale"] .col-span-6 { grid-column: span 6 / span 6; } +[data-route="point-of-sale"] .col-span-10 { grid-column: span 10 / span 10; } +[data-route="point-of-sale"] .row-span-2 { grid-row: span 2 / span 2; } +[data-route="point-of-sale"] .grid-auto-row { grid-auto-rows: 5.5rem; } +[data-route="point-of-sale"] .d-none { display: none; } +[data-route="point-of-sale"] .flex-wrap { flex-wrap: wrap; } +[data-route="point-of-sale"] .flex-row { flex-direction: row; } +[data-route="point-of-sale"] .flex-col { flex-direction: column; } +[data-route="point-of-sale"] .flex-row-rev { flex-direction: row-reverse; } +[data-route="point-of-sale"] .flex-col-rev { flex-direction: column-reverse; } +[data-route="point-of-sale"] .flex-1 { flex: 1 1 0%; } +[data-route="point-of-sale"] .items-center { align-items: center; } +[data-route="point-of-sale"] .items-end { align-items: flex-end; } +[data-route="point-of-sale"] .f-grow-1 { flex-grow: 1; } +[data-route="point-of-sale"] .f-grow-2 { flex-grow: 2; } +[data-route="point-of-sale"] .f-grow-3 { flex-grow: 3; } +[data-route="point-of-sale"] .f-grow-4 { flex-grow: 4; } +[data-route="point-of-sale"] .f-shrink-0 { flex-shrink: 0; } +[data-route="point-of-sale"] .f-shrink-1 { flex-shrink: 1; } +[data-route="point-of-sale"] .f-shrink-2 { flex-shrink: 2; } +[data-route="point-of-sale"] .f-shrink-3 { flex-shrink: 3; } +[data-route="point-of-sale"] .shadow { box-shadow: 0 0px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 2px 0 rgba(0, 0, 0, 0.06); } +[data-route="point-of-sale"] .shadow-sm { box-shadow: 0 0.5px 3px 0 rgba(0, 0, 0, 0.125); } +[data-route="point-of-sale"] .shadow-inner { box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.1); } +[data-route="point-of-sale"] .rounded { border-radius: 0.3rem; } +[data-route="point-of-sale"] .rounded-b { border-bottom-left-radius: 0.3rem; border-bottom-right-radius: 0.3rem; } +[data-route="point-of-sale"] .p-8 { padding: 2rem; } +[data-route="point-of-sale"] .p-16 { padding: 4rem; } +[data-route="point-of-sale"] .p-32 { padding: 8rem; } +[data-route="point-of-sale"] .p-6 { padding: 1.5rem; } +[data-route="point-of-sale"] .p-4 { padding: 1rem; } +[data-route="point-of-sale"] .p-3 { padding: 0.75rem; } +[data-route="point-of-sale"] .p-2 { padding: 0.5rem; } +[data-route="point-of-sale"] .m-8 { margin: 2rem; } +[data-route="point-of-sale"] .p-1 { padding: 0.25rem; } +[data-route="point-of-sale"] .pr-0 { padding-right: 0rem; } +[data-route="point-of-sale"] .pl-0 { padding-left: 0rem; } +[data-route="point-of-sale"] .pt-0 { padding-top: 0rem; } +[data-route="point-of-sale"] .pb-0 { padding-bottom: 0rem; } +[data-route="point-of-sale"] .mr-0 { margin-right: 0rem; } +[data-route="point-of-sale"] .ml-0 { margin-left: 0rem; } +[data-route="point-of-sale"] .mt-0 { margin-top: 0rem; } +[data-route="point-of-sale"] .mb-0 { margin-bottom: 0rem; } +[data-route="point-of-sale"] .pr-2 { padding-right: 0.5rem; } +[data-route="point-of-sale"] .pl-2 { padding-left: 0.5rem; } +[data-route="point-of-sale"] .pt-2 { padding-top: 0.5rem; } +[data-route="point-of-sale"] .pb-2 { padding-bottom: 0.5rem; } +[data-route="point-of-sale"] .pr-3 { padding-right: 0.75rem; } +[data-route="point-of-sale"] .pl-3 { padding-left: 0.75rem; } +[data-route="point-of-sale"] .pt-3 { padding-top: 0.75rem; } +[data-route="point-of-sale"] .pb-3 { padding-bottom: 0.75rem; } +[data-route="point-of-sale"] .pr-4 { padding-right: 1rem; } +[data-route="point-of-sale"] .pl-4 { padding-left: 1rem; } +[data-route="point-of-sale"] .pt-4 { padding-top: 1rem; } +[data-route="point-of-sale"] .pb-4 { padding-bottom: 1rem; } +[data-route="point-of-sale"] .mr-4 { margin-right: 1rem; } +[data-route="point-of-sale"] .ml-4 { margin-left: 1rem; } +[data-route="point-of-sale"] .mt-4 { margin-top: 1rem; } +[data-route="point-of-sale"] .mb-4 { margin-bottom: 1rem; } +[data-route="point-of-sale"] .mr-2 { margin-right: 0.5rem; } +[data-route="point-of-sale"] .ml-2 { margin-left: 0.5rem; } +[data-route="point-of-sale"] .mt-2 { margin-top: 0.5rem; } +[data-route="point-of-sale"] .mb-2 { margin-bottom: 0.5rem; } +[data-route="point-of-sale"] .mr-1 { margin-right: 0.25rem; } +[data-route="point-of-sale"] .ml-1 { margin-left: 0.25rem; } +[data-route="point-of-sale"] .mt-1 { margin-top: 0.25rem; } +[data-route="point-of-sale"] .mb-1 { margin-bottom: 0.25rem; } +[data-route="point-of-sale"] .mr-auto { margin-right: auto; } +[data-route="point-of-sale"] .ml-auto { margin-left: auto; } +[data-route="point-of-sale"] .mt-auto { margin-top: auto; } +[data-route="point-of-sale"] .mb-auto { margin-bottom: auto; } +[data-route="point-of-sale"] .pr-6 { padding-right: 1.5rem; } +[data-route="point-of-sale"] .pl-6 { padding-left: 1.5rem; } +[data-route="point-of-sale"] .pt-6 { padding-top: 1.5rem; } +[data-route="point-of-sale"] .pb-6 { padding-bottom: 1.5rem; } +[data-route="point-of-sale"] .mr-6 { margin-right: 1.5rem; } +[data-route="point-of-sale"] .ml-6 { margin-left: 1.5rem; } +[data-route="point-of-sale"] .mt-6 { margin-top: 1.5rem; } +[data-route="point-of-sale"] .mb-6 { margin-bottom: 1.5rem; } +[data-route="point-of-sale"] .mr-8 { margin-right: 2rem; } +[data-route="point-of-sale"] .ml-8 { margin-left: 2rem; } +[data-route="point-of-sale"] .mt-8 { margin-top: 2rem; } +[data-route="point-of-sale"] .mb-8 { margin-bottom: 2rem; } +[data-route="point-of-sale"] .pr-8 { padding-right: 2rem; } +[data-route="point-of-sale"] .pl-8 { padding-left: 2rem; } +[data-route="point-of-sale"] .pt-8 { padding-top: 2rem; } +[data-route="point-of-sale"] .pb-8 { padding-bottom: 2rem; } +[data-route="point-of-sale"] .pr-16 { padding-right: 4rem; } +[data-route="point-of-sale"] .pl-16 { padding-left: 4rem; } +[data-route="point-of-sale"] .pt-16 { padding-top: 4rem; } +[data-route="point-of-sale"] .pb-16 { padding-bottom: 4rem; } +[data-route="point-of-sale"] .w-full { width: 100%; } +[data-route="point-of-sale"] .h-full { height: 100%; } +[data-route="point-of-sale"] .w-quarter { width: 25%; } +[data-route="point-of-sale"] .w-half { width: 50%; } +[data-route="point-of-sale"] .w-66 { width: 66.66%; } +[data-route="point-of-sale"] .w-33 { width: 33.33%; } +[data-route="point-of-sale"] .w-60 { width: 60%; } +[data-route="point-of-sale"] .w-40 { width: 40%; } +[data-route="point-of-sale"] .w-fit { width: fit-content; } +[data-route="point-of-sale"] .w-6 { width: 2rem; } +[data-route="point-of-sale"] .h-6 { min-height: 2rem; height: 2rem; } +[data-route="point-of-sale"] .w-8 { width: 2.5rem; } +[data-route="point-of-sale"] .h-8 { min-height: 2.5rem; height: 2.5rem; } +[data-route="point-of-sale"] .w-10 { width: 3rem; } +[data-route="point-of-sale"] .h-10 { min-height:3rem; height: 3rem; } +[data-route="point-of-sale"] .h-12 { min-height: 3.3rem; height: 3.3rem; } +[data-route="point-of-sale"] .w-12 { width: 3.3rem; } +[data-route="point-of-sale"] .h-14 { min-height: 4.2rem; height: 4.2rem; } +[data-route="point-of-sale"] .h-16 { min-height: 4.6rem; height: 4.6rem; } +[data-route="point-of-sale"] .h-18 { min-height: 5rem; height: 5rem; } +[data-route="point-of-sale"] .w-18 { width: 5.4rem; } +[data-route="point-of-sale"] .w-24 { width: 7.2rem; } +[data-route="point-of-sale"] .w-26 { width: 8.4rem; } +[data-route="point-of-sale"] .h-24 { min-height: 7.2rem; height: 7.2rem; } +[data-route="point-of-sale"] .h-32 { min-height: 9.6rem; height: 9.6rem; } +[data-route="point-of-sale"] .w-46 { width: 15rem; } +[data-route="point-of-sale"] .h-46 { min-height:15rem; height: 15rem; } +[data-route="point-of-sale"] .h-100 { height: 100vh; } +[data-route="point-of-sale"] .mx-h-70 { max-height: 67rem; } +[data-route="point-of-sale"] .border-grey-300 { border-color: #e2e8f0; } +[data-route="point-of-sale"] .border-grey { border: 1px solid #d1d8dd; } +[data-route="point-of-sale"] .border-white { border: 1px solid #fff; } +[data-route="point-of-sale"] .border-b-grey { border-bottom: 1px solid #d1d8dd; } +[data-route="point-of-sale"] .border-t-grey { border-top: 1px solid #d1d8dd; } +[data-route="point-of-sale"] .border-r-grey { border-right: 1px solid #d1d8dd; } +[data-route="point-of-sale"] .text-dark-grey { color: #5f5f5f; } +[data-route="point-of-sale"] .text-grey { color: #8d99a6; } +[data-route="point-of-sale"] .text-grey-100 { color: #d1d8dd; } +[data-route="point-of-sale"] .text-grey-200 { color: #a0aec0; } +[data-route="point-of-sale"] .bg-green-200 { background-color: #c6f6d5; } +[data-route="point-of-sale"] .text-bold { font-weight: bold; } +[data-route="point-of-sale"] .italic { font-style: italic; } +[data-route="point-of-sale"] .font-weight-450 { font-weight: 450; } +[data-route="point-of-sale"] .justify-around { justify-content: space-around; } +[data-route="point-of-sale"] .justify-between { justify-content: space-between; } +[data-route="point-of-sale"] .justify-center { justify-content: center; } +[data-route="point-of-sale"] .justify-end { justify-content: flex-end; } +[data-route="point-of-sale"] .bg-white { background-color: white; } +[data-route="point-of-sale"] .bg-light-grey { background-color: #f0f4f7; } +[data-route="point-of-sale"] .bg-grey-100 { background-color: #f7fafc; } +[data-route="point-of-sale"] .bg-grey-200 { background-color: #edf2f7; } +[data-route="point-of-sale"] .bg-grey { background-color: #f4f5f6; } +[data-route="point-of-sale"] .text-center { text-align: center; } +[data-route="point-of-sale"] .text-right { text-align: right; } +[data-route="point-of-sale"] .text-sm { font-size: 1rem; } +[data-route="point-of-sale"] .text-md-0 { font-size: 1.25rem; } +[data-route="point-of-sale"] .text-md { font-size: 1.4rem; } +[data-route="point-of-sale"] .text-lg { font-size: 1.6rem; } +[data-route="point-of-sale"] .text-xl { font-size: 2.2rem; } +[data-route="point-of-sale"] .text-2xl { font-size: 2.8rem; } +[data-route="point-of-sale"] .text-2-5xl { font-size: 3rem; } +[data-route="point-of-sale"] .text-3xl { font-size: 3.8rem; } +[data-route="point-of-sale"] .text-6xl { font-size: 4.8rem; } +[data-route="point-of-sale"] .line-through { text-decoration: line-through; } +[data-route="point-of-sale"] .text-primary { color: #5e64ff; } +[data-route="point-of-sale"] .text-white { color: #fff; } +[data-route="point-of-sale"] .text-green-500 { color: #48bb78; } +[data-route="point-of-sale"] .bg-primary { background-color: #5e64ff; } +[data-route="point-of-sale"] .border-primary { border-color: #5e64ff; } +[data-route="point-of-sale"] .text-danger { color: #e53e3e; } +[data-route="point-of-sale"] .scroll-x { overflow-x: scroll;overflow-y: hidden; } +[data-route="point-of-sale"] .scroll-y { overflow-y: scroll;overflow-x: hidden; } +[data-route="point-of-sale"] .overflow-hidden { overflow: hidden; } +[data-route="point-of-sale"] .whitespace-nowrap { white-space: nowrap; } +[data-route="point-of-sale"] .sticky { position: sticky; top: -1px; } +[data-route="point-of-sale"] .bg-white { background-color: #fff; } +[data-route="point-of-sale"] .bg-selected { background-color: #fffdf4; } +[data-route="point-of-sale"] .border-dashed { border-width:1px; border-style: dashed; } +[data-route="point-of-sale"] .z-100 { z-index: 100; } + +[data-route="point-of-sale"] .frappe-control { margin: 0 !important; width: 100%; } +[data-route="point-of-sale"] .form-control { font-size: 12px; } +[data-route="point-of-sale"] .form-group { margin: 0 !important; } +[data-route="point-of-sale"] .pointer { cursor: pointer; } +[data-route="point-of-sale"] .no-select { user-select: none; } +[data-route="point-of-sale"] .item-wrapper:hover { transform: scale(1.02, 1.02); } +[data-route="point-of-sale"] .hover-underline:hover { text-decoration: underline; } +[data-route="point-of-sale"] .item-wrapper { transition: scale 0.2s ease-in-out; } +[data-route="point-of-sale"] .cart-items-section .cart-item-wrapper:not(:first-child) { border-top: none; } +[data-route="point-of-sale"] .customer-transactions .invoice-wrapper:not(:first-child) { border-top: none; } + +[data-route="point-of-sale"] .payment-summary-wrapper:last-child { border-bottom: none; } +[data-route="point-of-sale"] .item-summary-wrapper:last-child { border-bottom: none; } +[data-route="point-of-sale"] .total-summary-wrapper:last-child { border-bottom: none; } +[data-route="point-of-sale"] .invoices-container .invoice-wrapper:last-child { border-bottom: none; } +[data-route="point-of-sale"] .summary-btns:last-child { margin-right: 0px; } +[data-route="point-of-sale"] ::-webkit-scrollbar { width: 1px } + +[data-route="point-of-sale"] .indicator.grey::before { background-color: #8d99a6; } \ 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 b72ceb211393..405a33c72ae2 100644 --- a/erpnext/public/js/controllers/taxes_and_totals.js +++ b/erpnext/public/js/controllers/taxes_and_totals.js @@ -34,12 +34,12 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ this.calculate_discount_amount(); // Advance calculation applicable to Sales /Purchase Invoice - if(in_list(["Sales Invoice", "Purchase Invoice"], this.frm.doc.doctype) + if(in_list(["Sales Invoice", "POS Invoice", "Purchase Invoice"], this.frm.doc.doctype) && this.frm.doc.docstatus < 2 && !this.frm.doc.is_return) { this.calculate_total_advance(update_paid_amount); } - if (this.frm.doc.doctype == "Sales Invoice" && this.frm.doc.is_pos && + if (in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype) && this.frm.doc.is_pos && this.frm.doc.is_return) { this.update_paid_amount_for_return(); } @@ -425,7 +425,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ ? this.frm.doc["taxes"][tax_count - 1].total + flt(this.frm.doc.rounding_adjustment) : this.frm.doc.net_total); - if(in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"], this.frm.doc.doctype)) { + if(in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "POS Invoice"], this.frm.doc.doctype)) { this.frm.doc.base_grand_total = (this.frm.doc.total_taxes_and_charges) ? flt(this.frm.doc.grand_total * this.frm.doc.conversion_rate) : this.frm.doc.base_net_total; } else { @@ -604,7 +604,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ // NOTE: // paid_amount and write_off_amount is only for POS/Loyalty Point Redemption Invoice // total_advance is only for non POS Invoice - if(this.frm.doc.doctype == "Sales Invoice" && this.frm.doc.is_return){ + if(in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype) && this.frm.doc.is_return){ this.calculate_paid_amount(); } @@ -612,7 +612,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ frappe.model.round_floats_in(this.frm.doc, ["grand_total", "total_advance", "write_off_amount"]); - if(in_list(["Sales Invoice", "Purchase Invoice"], this.frm.doc.doctype)) { + if(in_list(["Sales Invoice", "POS Invoice", "Purchase Invoice"], this.frm.doc.doctype)) { var grand_total = this.frm.doc.rounded_total || this.frm.doc.grand_total; if(this.frm.doc.party_account_currency == this.frm.doc.currency) { @@ -634,7 +634,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ this.frm.refresh_field("base_paid_amount"); } - if(this.frm.doc.doctype == "Sales Invoice") { + if(in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype)) { let total_amount_for_payment = (this.frm.doc.redeem_loyalty_points && this.frm.doc.loyalty_amount) ? flt(total_amount_to_pay - this.frm.doc.loyalty_amount, precision("base_grand_total")) : total_amount_to_pay; @@ -691,11 +691,13 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ if(this.frm.doc.is_pos && (update_paid_amount===undefined || update_paid_amount)) { $.each(this.frm.doc['payments'] || [], function(index, data) { 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")); + let base_amount = flt(total_amount_to_pay, precision("base_amount", data)); + frappe.model.set_value(data.doctype, data.name, "base_amount", base_amount); + let amount = flt(total_amount_to_pay / me.frm.doc.conversion_rate, precision("amount", data)); + frappe.model.set_value(data.doctype, data.name, "amount", amount); payment_status = false; } else if(me.frm.doc.paid_amount) { - data.amount = 0.0; + frappe.model.set_value(data.doctype, data.name, "amount", 0.0); } }); } @@ -707,7 +709,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ var base_paid_amount = 0.0; if(this.frm.doc.is_pos) { $.each(this.frm.doc['payments'] || [], function(index, data){ - data.base_amount = flt(data.amount * me.frm.doc.conversion_rate, precision("base_amount")); + data.base_amount = flt(data.amount * me.frm.doc.conversion_rate, precision("base_amount", data)); paid_amount += data.amount; base_paid_amount += data.base_amount; }); @@ -719,14 +721,14 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ paid_amount += flt(this.frm.doc.loyalty_amount / me.frm.doc.conversion_rate, precision("paid_amount")); } - this.frm.doc.paid_amount = flt(paid_amount, precision("paid_amount")); - this.frm.doc.base_paid_amount = flt(base_paid_amount, precision("base_paid_amount")); + this.frm.set_value('paid_amount', flt(paid_amount, precision("paid_amount"))); + this.frm.set_value('base_paid_amount', flt(base_paid_amount, precision("base_paid_amount"))); }, calculate_change_amount: function(){ this.frm.doc.change_amount = 0.0; this.frm.doc.base_change_amount = 0.0; - if(this.frm.doc.doctype == "Sales Invoice" + if(in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype) && this.frm.doc.paid_amount > this.frm.doc.grand_total && !this.frm.doc.is_return) { var payment_types = $.map(this.frm.doc.payments, function(d) { return d.type; }); diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 3c56a636bd15..4e50f3d7f67d 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -651,7 +651,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ let child = frappe.model.add_child(me.frm.doc, "taxes"); child.charge_type = "On Net Total"; child.account_head = tax; - child.rate = 0; + child.rate = rate; } }); } diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index d75633e5a945..42f9cabc27a4 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -43,6 +43,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ label: __(me.warehouse_details.type), default: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '', onchange: function(e) { + me.warehouse_details.name = this.get_value(); if(me.has_batch && !me.has_serial_no) { fields = fields.concat(me.get_batch_fields()); @@ -50,7 +51,6 @@ erpnext.SerialNoBatchSelector = Class.extend({ fields = fields.concat(me.get_serial_no_fields()); } - me.warehouse_details.name = this.get_value(); var batches = this.layout.fields_dict.batches; if(batches) { batches.grid.df.data = []; @@ -98,8 +98,13 @@ erpnext.SerialNoBatchSelector = Class.extend({ numbers.then((data) => { let auto_fetched_serial_numbers = data.message; let records_length = auto_fetched_serial_numbers.length; + if (!records_length) { + const warehouse = me.dialog.fields_dict.warehouse.get_value().bold(); + frappe.msgprint(__(`Serial numbers unavailable for Item ${me.item.item_code.bold()} + under warehouse ${warehouse}. Please try changing warehouse.`)); + } if (records_length < qty) { - frappe.msgprint(`Fetched only ${records_length} serial numbers.`); + frappe.msgprint(__(`Fetched only ${records_length} available serial numbers.`)); } let serial_no_list_field = this.dialog.fields_dict.serial_no; numbers = auto_fetched_serial_numbers.join('\n'); @@ -445,6 +450,28 @@ erpnext.SerialNoBatchSelector = Class.extend({ serial_no_filters['warehouse'] = me.warehouse_details.name; } + if (me.frm.doc.doctype === 'POS Invoice' && !this.showing_reserved_serial_nos_error) { + frappe.call({ + method: "erpnext.stock.doctype.serial_no.serial_no.get_pos_reserved_serial_nos", + args: { + item_code: me.item_code, + warehouse: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '' + } + }).then((data) => { + if (!data.message[1].length) { + this.showing_reserved_serial_nos_error = true; + const warehouse = me.dialog.fields_dict.warehouse.get_value().bold(); + const d = frappe.msgprint(__(`Serial numbers unavailable for Item ${me.item.item_code.bold()} + under warehouse ${warehouse}. Please try changing warehouse.`)); + d.get_close_btn().on('click', () => { + this.showing_reserved_serial_nos_error = false; + d.hide(); + }); + } + serial_no_filters['name'] = ["not in", data.message[0]] + }) + } + return [ {fieldtype: 'Section Break', label: __('Serial Numbers')}, { diff --git a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js deleted file mode 100644 index f24caf767fe1..000000000000 --- a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('POS Closing Voucher', { - onload: function(frm) { - frm.set_query("pos_profile", function(doc) { - return { - filters: { - 'user': doc.user - } - }; - }); - - frm.set_query("user", function(doc) { - return { - query: "erpnext.selling.doctype.pos_closing_voucher.pos_closing_voucher.get_cashiers", - filters: { - 'parent': doc.pos_profile - } - }; - }); - }, - - total_amount: function(frm) { - get_difference_amount(frm); - }, - custody_amount: function(frm){ - get_difference_amount(frm); - }, - expense_amount: function(frm){ - get_difference_amount(frm); - }, - refresh: function(frm) { - get_closing_voucher_details(frm); - }, - period_start_date: function(frm) { - get_closing_voucher_details(frm); - }, - period_end_date: function(frm) { - get_closing_voucher_details(frm); - }, - company: function(frm) { - get_closing_voucher_details(frm); - }, - pos_profile: function(frm) { - get_closing_voucher_details(frm); - }, - user: function(frm) { - get_closing_voucher_details(frm); - }, -}); - -frappe.ui.form.on('POS Closing Voucher Details', { - collected_amount: function(doc, cdt, cdn) { - var row = locals[cdt][cdn]; - frappe.model.set_value(cdt, cdn, "difference", row.collected_amount - row.expected_amount); - } -}); - -var get_difference_amount = function(frm){ - frm.doc.difference = frm.doc.total_amount - frm.doc.custody_amount - frm.doc.expense_amount; - refresh_field("difference"); -}; - -var get_closing_voucher_details = function(frm) { - if (frm.doc.period_end_date && frm.doc.period_start_date && frm.doc.company && frm.doc.pos_profile && frm.doc.user) { - frappe.call({ - method: "get_closing_voucher_details", - doc: frm.doc, - callback: function(r) { - if (r.message) { - refresh_field("payment_reconciliation"); - refresh_field("sales_invoices_summary"); - refresh_field("taxes"); - - refresh_field("grand_total"); - refresh_field("net_total"); - refresh_field("total_quantity"); - refresh_field("total_amount"); - - frm.get_field("payment_reconciliation_details").$wrapper.html(r.message); - } - } - }); - } - -}; diff --git a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json deleted file mode 100644 index 2ac57794b4f2..000000000000 --- a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json +++ /dev/null @@ -1,1016 +0,0 @@ -{ - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "POS-CLO-.YYYY.-.#####", - "beta": 0, - "creation": "2018-05-28 19:06:40.830043", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fieldname": "period_start_date", - "fieldtype": "Date", - "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": "Period Start Date", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fieldname": "period_end_date", - "fieldtype": "Date", - "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": "Period End Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 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, - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fieldname": "posting_date", - "fieldtype": "Date", - "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": "Posting Date", - "length": 0, - "no_copy": 0, - "options": "", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_5", - "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, - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "company", - "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": "Company", - "length": 0, - "no_copy": 0, - "options": "Company", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_7", - "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, - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "pos_profile", - "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": "POS Profile", - "length": 0, - "no_copy": 0, - "options": "POS Profile", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fieldname": "user", - "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": "Cashier", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "expense_details_section", - "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": "Expense Details", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "expense_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": "Expense Amount", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "custody_amount", - "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": "Amount in Custody", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_13", - "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, - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "total_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": "Total Collected Amount", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "difference", - "fieldtype": "Currency", - "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": "Difference", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_9", - "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, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "payment_reconciliation_details", - "fieldtype": "HTML", - "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, - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_11", - "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": "Modes of Payment", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "payment_reconciliation", - "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": "Payment Reconciliation", - "length": 0, - "no_copy": 0, - "options": "POS Closing Voucher Details", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "section_break_13", - "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": "Details", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "grand_total", - "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": "Grand Total", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "net_total", - "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": "Net Total", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "total_quantity", - "fieldtype": "Float", - "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": "Total Quantity", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_16", - "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, - "label": "Taxes", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "taxes", - "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": "Taxes", - "length": 0, - "no_copy": 0, - "options": "POS Closing Voucher Taxes", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "section_break_12", - "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": "Linked Invoices", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sales_invoices_summary", - "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": "Sales Invoices Summary", - "length": 0, - "no_copy": 0, - "options": "POS Closing Voucher Invoices", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_14", - "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, - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "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": "Amended From", - "length": 0, - "no_copy": 1, - "options": "POS Closing Voucher", - "permlevel": 0, - "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, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-01-28 12:33:45.217813", - "modified_by": "Administrator", - "module": "Selling", - "name": "POS Closing Voucher", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "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 - }, - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Sales Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "quick_entry": 0, - "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, - "track_views": 0 -} \ No newline at end of file diff --git a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.py b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.py deleted file mode 100644 index bb5f83ed0540..000000000000 --- a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.py +++ /dev/null @@ -1,188 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -import frappe -from frappe import _ -from frappe.model.document import Document -from collections import defaultdict -from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data -import json - -class POSClosingVoucher(Document): - def get_closing_voucher_details(self): - filters = { - 'doc': self.name, - 'from_date': self.period_start_date, - 'to_date': self.period_end_date, - 'company': self.company, - 'pos_profile': self.pos_profile, - 'user': self.user, - 'is_pos': 1 - } - - invoice_list = get_invoices(filters) - self.set_invoice_list(invoice_list) - - sales_summary = get_sales_summary(invoice_list) - self.set_sales_summary_values(sales_summary) - self.total_amount = sales_summary['grand_total'] - - if not self.get('payment_reconciliation'): - mop = get_mode_of_payment_details(invoice_list) - self.set_mode_of_payments(mop) - - taxes = get_tax_details(invoice_list) - self.set_taxes(taxes) - - return self.get_payment_reconciliation_details() - - def validate(self): - user = frappe.get_all('POS Closing Voucher', - filters = { - 'user': self.user, - 'docstatus': 1 - }, - or_filters = { - 'period_start_date': ('between', [self.period_start_date, self.period_end_date]), - 'period_end_date': ('between', [self.period_start_date, self.period_end_date]) - }) - - if user: - frappe.throw(_("POS Closing Voucher alreday exists for {0} between date {1} and {2}") - .format(self.user, self.period_start_date, self.period_end_date)) - - def set_invoice_list(self, invoice_list): - self.sales_invoices_summary = [] - for invoice in invoice_list: - self.append('sales_invoices_summary', { - 'invoice': invoice['name'], - 'qty_of_items': invoice['pos_total_qty'], - 'grand_total': invoice['grand_total'] - }) - - def set_sales_summary_values(self, sales_summary): - self.grand_total = sales_summary['grand_total'] - self.net_total = sales_summary['net_total'] - self.total_quantity = sales_summary['total_qty'] - - def set_mode_of_payments(self, mop): - self.payment_reconciliation = [] - for m in mop: - self.append('payment_reconciliation', { - 'mode_of_payment': m['name'], - 'expected_amount': m['amount'] - }) - - def set_taxes(self, taxes): - self.taxes = [] - for tax in taxes: - self.append('taxes', { - 'rate': tax['rate'], - 'amount': tax['amount'] - }) - - def get_payment_reconciliation_details(self): - currency = get_company_currency(self) - return frappe.render_template("erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html", - {"data": self, "currency": currency}) - -@frappe.whitelist() -def get_cashiers(doctype, txt, searchfield, start, page_len, filters): - cashiers_list = frappe.get_all("POS Profile User", filters=filters, fields=['user']) - cashiers = [cashier for cashier in set(c['user'] for c in cashiers_list)] - return [[c] for c in cashiers] - -def get_mode_of_payment_details(invoice_list): - mode_of_payment_details = [] - invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list]) - if invoice_list: - inv_mop_detail = frappe.db.sql("""select a.owner, a.posting_date, - ifnull(b.mode_of_payment, '') as mode_of_payment, sum(b.base_amount) as paid_amount - from `tabSales Invoice` a, `tabSales Invoice Payment` b - where a.name = b.parent - and a.name in ({invoice_list_names}) - group by a.owner, a.posting_date, mode_of_payment - union - select a.owner,a.posting_date, - ifnull(b.mode_of_payment, '') as mode_of_payment, sum(b.base_paid_amount) as paid_amount - from `tabSales Invoice` a, `tabPayment Entry` b,`tabPayment Entry Reference` c - where a.name = c.reference_name - and b.name = c.parent - and a.name in ({invoice_list_names}) - group by a.owner, a.posting_date, mode_of_payment - union - select a.owner, a.posting_date, - ifnull(a.voucher_type,'') as mode_of_payment, sum(b.credit) - from `tabJournal Entry` a, `tabJournal Entry Account` b - where a.name = b.parent - and a.docstatus = 1 - and b.reference_type = "Sales Invoice" - and b.reference_name in ({invoice_list_names}) - group by a.owner, a.posting_date, mode_of_payment - """.format(invoice_list_names=invoice_list_names), as_dict=1) - - inv_change_amount = frappe.db.sql("""select a.owner, a.posting_date, - ifnull(b.mode_of_payment, '') as mode_of_payment, sum(a.base_change_amount) as change_amount - from `tabSales Invoice` a, `tabSales Invoice Payment` b - where a.name = b.parent - and a.name in ({invoice_list_names}) - and b.mode_of_payment = 'Cash' - and a.base_change_amount > 0 - group by a.owner, a.posting_date, mode_of_payment""".format(invoice_list_names=invoice_list_names), as_dict=1) - - for d in inv_change_amount: - for det in inv_mop_detail: - if det["owner"] == d["owner"] and det["posting_date"] == d["posting_date"] and det["mode_of_payment"] == d["mode_of_payment"]: - paid_amount = det["paid_amount"] - d["change_amount"] - det["paid_amount"] = paid_amount - - payment_details = defaultdict(int) - for d in inv_mop_detail: - payment_details[d.mode_of_payment] += d.paid_amount - - for m in payment_details: - mode_of_payment_details.append({'name': m, 'amount': payment_details[m]}) - - return mode_of_payment_details - -def get_tax_details(invoice_list): - tax_breakup = [] - tax_details = defaultdict(int) - for invoice in invoice_list: - doc = frappe.get_doc("Sales Invoice", invoice.name) - itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(doc) - - if itemised_tax: - for a in itemised_tax: - for b in itemised_tax[a]: - for c in itemised_tax[a][b]: - if c == 'tax_rate': - tax_details[itemised_tax[a][b][c]] += itemised_tax[a][b]['tax_amount'] - - for t in tax_details: - tax_breakup.append({'rate': t, 'amount': tax_details[t]}) - - return tax_breakup - -def get_sales_summary(invoice_list): - net_total = sum(item['net_total'] for item in invoice_list) - grand_total = sum(item['grand_total'] for item in invoice_list) - total_qty = sum(item['pos_total_qty'] for item in invoice_list) - - return {'net_total': net_total, 'grand_total': grand_total, 'total_qty': total_qty} - -def get_company_currency(doc): - currency = frappe.get_cached_value('Company', doc.company, "default_currency") - return frappe.get_doc('Currency', currency) - -def get_invoices(filters): - return frappe.db.sql("""select a.name, a.base_grand_total as grand_total, - a.base_net_total as net_total, a.pos_total_qty - from `tabSales Invoice` a - where a.docstatus = 1 and a.posting_date >= %(from_date)s - and a.posting_date <= %(to_date)s and a.company=%(company)s - and a.pos_profile = %(pos_profile)s and a.is_pos = %(is_pos)s - and a.owner = %(user)s""", - filters, as_dict=1) diff --git a/erpnext/selling/doctype/pos_closing_voucher/test_pos_closing_voucher.py b/erpnext/selling/doctype/pos_closing_voucher/test_pos_closing_voucher.py deleted file mode 100644 index 8899aaff41c4..000000000000 --- a/erpnext/selling/doctype/pos_closing_voucher/test_pos_closing_voucher.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt -from __future__ import unicode_literals -import frappe -import unittest -from frappe.utils import nowdate -from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice -from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile - -class TestPOSClosingVoucher(unittest.TestCase): - def test_pos_closing_voucher(self): - old_user = frappe.session.user - user = 'test@example.com' - test_user = frappe.get_doc('User', user) - - roles = ("Accounts Manager", "Accounts User", "Sales Manager") - test_user.add_roles(*roles) - frappe.set_user(user) - - pos_profile = make_pos_profile() - pos_profile.append('applicable_for_users', { - 'default': 1, - 'user': user - }) - - pos_profile.save() - - si1 = create_sales_invoice(is_pos=1, rate=3500, do_not_submit=1) - si1.append('payments', { - 'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 3500 - }) - si1.submit() - - si2 = create_sales_invoice(is_pos=1, rate=3200, do_not_submit=1) - si2.append('payments', { - 'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 3200 - }) - si2.submit() - - pcv_doc = create_pos_closing_voucher(user=user, - pos_profile=pos_profile.name, collected_amount=6700) - - pcv_doc.get_closing_voucher_details() - - self.assertEqual(pcv_doc.total_quantity, 2) - self.assertEqual(pcv_doc.net_total, 6700) - - payment = pcv_doc.payment_reconciliation[0] - self.assertEqual(payment.mode_of_payment, 'Cash') - - si1.load_from_db() - si1.cancel() - - si2.load_from_db() - si2.cancel() - - test_user.load_from_db() - test_user.remove_roles(*roles) - - frappe.set_user(old_user) - frappe.db.sql("delete from `tabPOS Profile`") - -def create_pos_closing_voucher(**args): - args = frappe._dict(args) - - doc = frappe.get_doc({ - 'doctype': 'POS Closing Voucher', - 'period_start_date': args.period_start_date or nowdate(), - 'period_end_date': args.period_end_date or nowdate(), - 'posting_date': args.posting_date or nowdate(), - 'company': args.company or "_Test Company", - 'pos_profile': args.pos_profile, - 'user': args.user or "Administrator", - }) - - doc.get_closing_voucher_details() - if doc.get('payment_reconciliation'): - doc.payment_reconciliation[0].collected_amount = (args.collected_amount or - doc.payment_reconciliation[0].expected_amount) - - doc.save() - return doc \ No newline at end of file diff --git a/erpnext/selling/doctype/pos_closing_voucher_details/pos_closing_voucher_details.json b/erpnext/selling/doctype/pos_closing_voucher_details/pos_closing_voucher_details.json deleted file mode 100644 index a52688462af3..000000000000 --- a/erpnext/selling/doctype/pos_closing_voucher_details/pos_closing_voucher_details.json +++ /dev/null @@ -1,172 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-05-28 19:10:47.580174", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 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, - "options": "Mode of Payment", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0.0", - "fieldname": "collected_amount", - "fieldtype": "Currency", - "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": "Collected Amount", - "length": 0, - "no_copy": 0, - "options": "currency", - "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, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "expected_amount", - "fieldtype": "Currency", - "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": "Expected Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "difference", - "fieldtype": "Currency", - "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": "Difference", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 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": 1, - "max_attachments": 0, - "modified": "2018-05-29 17:47:16.311557", - "modified_by": "Administrator", - "module": "Selling", - "name": "POS Closing Voucher Details", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "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/selling/doctype/pos_closing_voucher_invoices/pos_closing_voucher_invoices.json b/erpnext/selling/doctype/pos_closing_voucher_invoices/pos_closing_voucher_invoices.json deleted file mode 100644 index 730455078476..000000000000 --- a/erpnext/selling/doctype/pos_closing_voucher_invoices/pos_closing_voucher_invoices.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-05-29 14:50:08.687453", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "invoice", - "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": "Invoices", - "length": 0, - "no_copy": 0, - "options": "Sales Invoice", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "qty_of_items", - "fieldtype": "Data", - "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": "Quantity of Items", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "grand_total", - "fieldtype": "Currency", - "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": "Grand Total", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 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": 1, - "max_attachments": 0, - "modified": "2018-05-29 17:46:46.539993", - "modified_by": "Administrator", - "module": "Selling", - "name": "POS Closing Voucher Invoices", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "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/selling/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.json b/erpnext/selling/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.json deleted file mode 100644 index 3089e0621f14..000000000000 --- a/erpnext/selling/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2018-05-30 09:11:22.535470", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "rate", - "fieldtype": "Percent", - "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": "Rate", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amount", - "fieldtype": "Currency", - "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": "Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 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": 1, - "max_attachments": 0, - "modified": "2018-05-30 09:11:22.535470", - "modified_by": "Administrator", - "module": "Selling", - "name": "POS Closing Voucher Taxes", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "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/selling/page/point_of_sale/onscan.js b/erpnext/selling/page/point_of_sale/onscan.js new file mode 100644 index 000000000000..428dc75cf82e --- /dev/null +++ b/erpnext/selling/page/point_of_sale/onscan.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t()):e.onScan=t()}(this,function(){var d={attachTo:function(e,t){if(void 0!==e.scannerDetectionData)throw new Error("onScan.js is already initialized for DOM element "+e);var n={onScan:function(e,t){},onScanError:function(e){},onKeyProcess:function(e,t){},onKeyDetect:function(e,t){},onPaste:function(e,t){},keyCodeMapper:function(e){return d.decodeKeyEvent(e)},onScanButtonLongPress:function(){},scanButtonKeyCode:!1,scanButtonLongPressTime:500,timeBeforeScanTest:100,avgTimeByChar:30,minLength:6,suffixKeyCodes:[9,13],prefixKeyCodes:[],ignoreIfFocusOn:!1,stopPropagation:!1,preventDefault:!1,captureEvents:!1,reactToKeydown:!0,reactToPaste:!1,singleScanQty:1};return t=this._mergeOptions(n,t),e.scannerDetectionData={options:t,vars:{firstCharTime:0,lastCharTime:0,accumulatedString:"",testTimer:!1,longPressTimeStart:0,longPressed:!1}},!0===t.reactToPaste&&e.addEventListener("paste",this._handlePaste,t.captureEvents),!1!==t.scanButtonKeyCode&&e.addEventListener("keyup",this._handleKeyUp,t.captureEvents),!0!==t.reactToKeydown&&!1===t.scanButtonKeyCode||e.addEventListener("keydown",this._handleKeyDown,t.captureEvents),this},detachFrom:function(e){e.scannerDetectionData.options.reactToPaste&&e.removeEventListener("paste",this._handlePaste),!1!==e.scannerDetectionData.options.scanButtonKeyCode&&e.removeEventListener("keyup",this._handleKeyUp),e.removeEventListener("keydown",this._handleKeyDown),e.scannerDetectionData=void 0},getOptions:function(e){return e.scannerDetectionData.options},setOptions:function(e,t){switch(e.scannerDetectionData.options.reactToPaste){case!0:!1===t.reactToPaste&&e.removeEventListener("paste",this._handlePaste);break;case!1:!0===t.reactToPaste&&e.addEventListener("paste",this._handlePaste)}switch(e.scannerDetectionData.options.scanButtonKeyCode){case!1:!1!==t.scanButtonKeyCode&&e.addEventListener("keyup",this._handleKeyUp);break;default:!1===t.scanButtonKeyCode&&e.removeEventListener("keyup",this._handleKeyUp)}return e.scannerDetectionData.options=this._mergeOptions(e.scannerDetectionData.options,t),this._reinitialize(e),this},decodeKeyEvent:function(e){var t=this._getNormalizedKeyNum(e);switch(!0){case 48<=t&&t<=90:case 106<=t&&t<=111:if(void 0!==e.key&&""!==e.key)return e.key;var n=String.fromCharCode(t);switch(e.shiftKey){case!1:n=n.toLowerCase();break;case!0:n=n.toUpperCase()}return n;case 96<=t&&t<=105:return t-96}return""},simulate:function(e,t){return this._reinitialize(e),Array.isArray(t)?t.forEach(function(e){var t={};"object"!=typeof e&&"function"!=typeof e||null===e?t.keyCode=parseInt(e):t=e;var n=new KeyboardEvent("keydown",t);document.dispatchEvent(n)}):this._validateScanCode(e,t),this},_reinitialize:function(e){var t=e.scannerDetectionData.vars;t.firstCharTime=0,t.lastCharTime=0,t.accumulatedString=""},_isFocusOnIgnoredElement:function(e){var t=e.scannerDetectionData.options.ignoreIfFocusOn;if(!t)return!1;var n=document.activeElement;if(Array.isArray(t)){for(var a=0;a\n\t{{ doc.company }}
\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t{{ _(\"GSTIN\") }}:{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"
GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t
\n\t{% if doc.docstatus == 0 %}\n\t\t{{ doc.status + \" \"+ (doc.select_print_heading or _(\"Invoice\")) }}
\n\t{% else %}\n\t\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n\t{% endif %}\n
\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"
\", \" \") %}\n\t\t{{ _(\"Customer\") }}:
\n\t\t{{ doc.customer_name }}
\n\t\t{{ customer_address }}\n\t{% endif %}\n
{{ _(\"Item\") }} | \n\t\t\t{{ _(\"Qty\") }} | \n\t\t\t{{ _(\"Amount\") }} | \n\t\t
---|---|---|
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t {{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t {{ _(\"HSN/SAC\") }}: {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t {{ _(\"SR.No\") }}: \n\t\t\t\t\t{{ item.serial_no | replace(\"\\n\", \", \") }}\n\t\t\t\t{%- endif -%}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ item.rate }} | \n\t\t\t{{ item.get_formatted(\"amount\") }} | \n\t\t
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t | \n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t | \n\t\t\t{% endif %}\n\t\t
\n\t\t\t\t\t{% if '%' in row.description %}\n\t\t\t\t\t {{ row.description }}\n\t\t\t\t\t{% else %}\n\t\t\t\t\t {{ row.description }}@{{ row.rate }}%\n\t\t\t\t\t{% endif %}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t | \n\t\t\t||
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t | \n\t\t
{{ doc.terms or \"\" }}
\n{{ _(\"Thank you, please visit again.\") }}
", + "idx": 0, + "line_breaks": 0, + "modified": "2020-04-29 16:47:02.743246", + "modified_by": "Administrator", + "module": "Selling", + "name": "GST POS Invoice", + "owner": "Administrator", + "print_format_builder": 0, + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/erpnext/selling/print_format/pos_invoice/__init__.py b/erpnext/selling/print_format/pos_invoice/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/selling/print_format/pos_invoice/pos_invoice.json b/erpnext/selling/print_format/pos_invoice/pos_invoice.json new file mode 100644 index 000000000000..99094ed9b02d --- /dev/null +++ b/erpnext/selling/print_format/pos_invoice/pos_invoice.json @@ -0,0 +1,22 @@ +{ + "align_labels_right": 0, + "creation": "2011-12-21 11:08:55", + "custom_format": 1, + "disabled": 0, + "doc_type": "POS Invoice", + "docstatus": 0, + "doctype": "Print Format", + "html": "\n\n{% if letter_head %}\n {{ letter_head }}\n{% endif %}\n\n\n\t{{ doc.company }}
\n\t{{ doc.select_print_heading or _(\"Invoice\") }}
\n
\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{{ _(\"Customer\") }}: {{ doc.customer_name }}\n
{{ _(\"Item\") }} | \n\t\t\t{{ _(\"Qty\") }} | \n\t\t\t{{ _(\"Amount\") }} | \n\t\t
---|---|---|
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t {{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t {{ _(\"SR.No\") }}: \n\t\t\t\t\t{{ item.serial_no | replace(\"\\n\", \", \") }}\n\t\t\t\t{%- endif -%}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ item.get_formatted(\"rate\") }} | \n\t\t\t{{ item.get_formatted(\"amount\") }} | \n\t\t
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t | \n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t | \n\t\t\t{% endif %}\n\t\t
\n\t\t\t\t {% if '%' in row.description %}\n\t\t\t\t\t {{ row.description }}\n\t\t\t\t\t{% else %}\n\t\t\t\t\t {{ row.description }}@{{ row.rate }}%\n\t\t\t\t\t{% endif %}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t | \n\t\t\t||
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t\t | \n\t\t\t
{{ doc.terms or \"\" }}
\n{{ _(\"Thank you, please visit again.\") }}
", + "idx": 1, + "line_breaks": 0, + "modified": "2020-04-29 16:45:58.942375", + "modified_by": "Administrator", + "module": "Selling", + "name": "POS Invoice", + "owner": "Administrator", + "print_format_builder": 0, + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/erpnext/selling/print_format/return_pos_invoice/__init__.py b/erpnext/selling/print_format/return_pos_invoice/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/selling/print_format/return_pos_invoice/return_pos_invoice.json b/erpnext/selling/print_format/return_pos_invoice/return_pos_invoice.json new file mode 100644 index 000000000000..d7f335059ca3 --- /dev/null +++ b/erpnext/selling/print_format/return_pos_invoice/return_pos_invoice.json @@ -0,0 +1,24 @@ +{ + "align_labels_right": 0, + "creation": "2020-05-14 17:02:44.207166", + "custom_format": 1, + "default_print_language": "en", + "disabled": 0, + "doc_type": "POS Invoice", + "docstatus": 0, + "doctype": "Print Format", + "font": "Default", + "html": "\n\n{% if letter_head %}\n {{ letter_head }}\n{% endif %}\n\n\n\t{{ doc.company }}
\n\t{{ doc.select_print_heading or _(\"Return Invoice\") }}
\n
\n\t{{ _(\"Receipt No\") }}: {{ doc.name }}
\n\t{{ _(\"Original Invoice\") }}: {{ doc.return_against }}
\n\t{{ _(\"Date\") }}: {{ doc.get_formatted(\"posting_date\") }}
\n\t{{ _(\"Customer\") }}: {{ doc.customer_name }}\n
{{ _(\"Item\") }} | \n\t\t\t{{ _(\"Qty\") }} | \n\t\t\t{{ _(\"Amount\") }} | \n\t\t
---|---|---|
\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t {{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t {{ _(\"SR.No\") }}: \n\t\t\t\t\t{{ item.serial_no | replace(\"\\n\", \", \") }}\n\t\t\t\t{%- endif -%}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ item.get_formatted(\"rate\") }} | \n\t\t\t{{ item.get_formatted(\"amount\") }} | \n\t\t
\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t | \n\t\t\t{% else %}\n\t\t\t\t\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t | \n\t\t\t{% endif %}\n\t\t
\n\t\t\t\t {% if '%' in row.description %}\n\t\t\t\t\t {{ row.description }}\n\t\t\t\t\t{% else %}\n\t\t\t\t\t {{ row.description }}@{{ row.rate }}%\n\t\t\t\t\t{% endif %}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc)}}\n\t\t\t\t | \n\t\t\t||
\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Rounded Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t{{ _(\"Paid Amount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t | \n\t\t||
\n\t\t\t\t\t{{ _(\"Change Amount\") }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ doc.get_formatted(\"change_amount\")}}\n\t\t\t\t | \n\t\t\t
{{ doc.terms or \"\" }}
\n{{ _(\"Thank you, please visit again.\") }}
", + "idx": 0, + "line_breaks": 0, + "modified": "2020-05-14 17:13:29.354015", + "modified_by": "Administrator", + "module": "Selling", + "name": "Return POS Invoice", + "owner": "Administrator", + "print_format_builder": 0, + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 4a7dd5ad9b42..333a563aa5d8 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -142,7 +142,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]); // check if child doctype is Sales Order Item/Qutation Item and calculate the rate - if(in_list(["Quotation Item", "Sales Order Item", "Delivery Note Item", "Sales Invoice Item"]), cdt) + if(in_list(["Quotation Item", "Sales Order Item", "Delivery Note Item", "Sales Invoice Item", "POS Invoice Item"]), cdt) this.apply_pricing_rule_on_item(item); else item.rate = flt(item.price_list_rate * (1 - item.discount_percentage / 100.0), @@ -312,6 +312,11 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ batch_no: function(doc, cdt, cdn) { var me = this; var item = frappe.get_doc(cdt, cdn); + + if (item.serial_no) { + return; + } + item.serial_no = null; var has_serial_no; frappe.db.get_value('Item', {'item_code': item.item_code}, 'has_serial_no', (r) => { diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 153ce2fb6746..f7ff916c5a24 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import frappe +import json from frappe.model.naming import make_autoname from frappe.utils import cint, cstr, flt, add_days, nowdate, getdate @@ -537,15 +538,54 @@ def get_delivery_note_serial_no(item_code, qty, delivery_note): return serial_nos @frappe.whitelist() -def auto_fetch_serial_number(qty, item_code, warehouse, batch_nos=None): - import json +def auto_fetch_serial_number(qty, item_code, warehouse, batch_nos=None, for_doctype=None): filters = { "item_code": item_code, "warehouse": warehouse, "delivery_document_no": "", "sales_invoice": "" } - if batch_nos: filters["batch_no"] = ["in", json.loads(batch_nos)] + + if batch_nos: + try: + filters["batch_no"] = ["in", json.loads(batch_nos)] + except: + filters["batch_no"] = ["in", [batch_nos]] + + if for_doctype == 'POS Invoice': + reserved_serial_nos, unreserved_serial_nos = get_pos_reserved_serial_nos(filters, qty) + return unreserved_serial_nos serial_numbers = frappe.get_list("Serial No", filters=filters, limit=qty, order_by="creation") return [item['name'] for item in serial_numbers] + +@frappe.whitelist() +def get_pos_reserved_serial_nos(filters, qty=None): + batch_no_cond = "" + if filters.get("batch_no"): + batch_no_cond = "and item.batch_no = {}".format(frappe.db.escape(filters.get('batch_no'))) + + reserved_serial_nos_str = [d.serial_no for d in frappe.db.sql("""select item.serial_no as serial_no + from `tabPOS Invoice` p, `tabPOS Invoice Item` item + where p.name = item.parent + and p.consolidated_invoice is NULL + and p.docstatus = 1 + and item.docstatus = 1 + and item.item_code = %s + and item.warehouse = %s + {} + """.format(batch_no_cond), [filters.get('item_code'), filters.get('warehouse')], as_dict=1)] + + reserved_serial_nos = [] + for s in reserved_serial_nos_str: + if not s: continue + + serial_nos = s.split("\n") + serial_nos = ' '.join(serial_nos).split() # remove whitespaces + if len(serial_nos): reserved_serial_nos += serial_nos + + filters["name"] = ["not in", reserved_serial_nos] + serial_numbers = frappe.get_list("Serial No", filters=filters, limit=qty, order_by="creation") + unreserved_serial_nos = [item['name'] for item in serial_numbers] + + return reserved_serial_nos, unreserved_serial_nos \ No newline at end of file diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index b8554c83e249..1a7c15ebca79 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -401,13 +401,30 @@ def get_item_warehouse(item, args, overwrite_warehouse, defaults={}): return warehouse def update_barcode_value(out): - from erpnext.accounts.doctype.sales_invoice.pos import get_barcode_data barcode_data = get_barcode_data([out]) # If item has one barcode then update the value of the barcode field if barcode_data and len(barcode_data.get(out.item_code)) == 1: out['barcode'] = barcode_data.get(out.item_code)[0] +def get_barcode_data(items_list): + # get itemwise batch no data + # exmaple: {'LED-GRE': [Batch001, Batch002]} + # where LED-GRE is item code, SN0001 is serial no and Pune is warehouse + + itemwise_barcode = {} + for item in items_list: + barcodes = frappe.db.sql(""" + select barcode from `tabItem Barcode` where parent = %s + """, item.item_code, as_dict=1) + + for barcode in barcodes: + if item.item_code not in itemwise_barcode: + itemwise_barcode.setdefault(item.item_code, []) + itemwise_barcode[item.item_code].append(barcode.get("barcode")) + + return itemwise_barcode + @frappe.whitelist() def get_item_tax_info(company, tax_category, item_codes): out = {}