From a774f3d7a073b418d46fe8e2e425f229757b2196 Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Wed, 6 Jun 2018 06:52:13 +0200 Subject: [PATCH] POS closing voucher (#14270) * POS closing voucher * Codacy corrections + improvements * Codacy corrections * POS Closing Voucher improvements --- .../sales_payment_summary.py | 2 + erpnext/accounts/utils.py | 1 + .../img/accounts/pos-closing-voucher.png | Bin 0 -> 41622 bytes .../user/manual/en/accounts/point-of-sales.md | 24 +- .../doctype/pos_closing_voucher/__init__.py | 0 .../closing_voucher_details.html | 84 ++ .../pos_closing_voucher.js | 72 ++ .../pos_closing_voucher.json | 823 ++++++++++++++++++ .../pos_closing_voucher.py | 175 ++++ .../test_pos_closing_voucher.js | 23 + .../test_pos_closing_voucher.py | 9 + .../pos_closing_voucher_details/__init__.py | 0 .../pos_closing_voucher_details.json | 172 ++++ .../pos_closing_voucher_details.py | 9 + .../pos_closing_voucher_invoices/__init__.py | 0 .../pos_closing_voucher_invoices.json | 138 +++ .../pos_closing_voucher_invoices.py | 9 + .../pos_closing_voucher_taxes/__init__.py | 0 .../pos_closing_voucher_taxes.json | 106 +++ .../pos_closing_voucher_taxes.py | 9 + .../page/point_of_sale/point_of_sale.js | 14 +- 21 files changed, 1663 insertions(+), 7 deletions(-) create mode 100644 erpnext/docs/assets/img/accounts/pos-closing-voucher.png create mode 100644 erpnext/selling/doctype/pos_closing_voucher/__init__.py create mode 100644 erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html create mode 100644 erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js create mode 100644 erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json create mode 100644 erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.py create mode 100644 erpnext/selling/doctype/pos_closing_voucher/test_pos_closing_voucher.js create mode 100644 erpnext/selling/doctype/pos_closing_voucher/test_pos_closing_voucher.py create mode 100644 erpnext/selling/doctype/pos_closing_voucher_details/__init__.py create mode 100644 erpnext/selling/doctype/pos_closing_voucher_details/pos_closing_voucher_details.json create mode 100644 erpnext/selling/doctype/pos_closing_voucher_details/pos_closing_voucher_details.py create mode 100644 erpnext/selling/doctype/pos_closing_voucher_invoices/__init__.py create mode 100644 erpnext/selling/doctype/pos_closing_voucher_invoices/pos_closing_voucher_invoices.json create mode 100644 erpnext/selling/doctype/pos_closing_voucher_invoices/pos_closing_voucher_invoices.py create mode 100644 erpnext/selling/doctype/pos_closing_voucher_taxes/__init__.py create mode 100644 erpnext/selling/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.json create mode 100644 erpnext/selling/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.py diff --git a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py index 0c11d52b6b..2ad41d6f30 100644 --- a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py +++ b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py @@ -157,6 +157,7 @@ def get_sales_invoice_data(filters): def get_mode_of_payments(filters): + frappe.log_error(filters, 'filters') mode_of_payments = {} invoice_list = get_invoices(filters) invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list]) @@ -196,6 +197,7 @@ def get_invoices(filters): def get_mode_of_payment_details(filters): mode_of_payment_details = {} invoice_list = get_invoices(filters) + frappe.log_error(invoice_list, 'invoice_list') 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, diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index adb8dca074..8e23975058 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # License: GNU General Public License v3. See license.txt diff --git a/erpnext/docs/assets/img/accounts/pos-closing-voucher.png b/erpnext/docs/assets/img/accounts/pos-closing-voucher.png new file mode 100644 index 0000000000000000000000000000000000000000..7c5fa9e641dfed73322c617ede0eb939f248be4e GIT binary patch literal 41622 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 literal 0 HcmV?d00001 diff --git a/erpnext/docs/user/manual/en/accounts/point-of-sales.md b/erpnext/docs/user/manual/en/accounts/point-of-sales.md index fe7484f3d4..d9f66b28ce 100644 --- a/erpnext/docs/user/manual/en/accounts/point-of-sales.md +++ b/erpnext/docs/user/manual/en/accounts/point-of-sales.md @@ -49,7 +49,7 @@ in Search box. ### Removing an Item from the Cart 1. Select row in the cart and clik on delete button in the numeric keypad - + POS Item @@ -67,7 +67,7 @@ ready to make the Payment. Payment process is divided into 3 steps - 1. Click on “Make Payment” to get the Payment window. 2. Select your “Mode of Payment”. 3. Click on “Pay” button to Save the document. - + POS Payment Submit the document to finalise the record. After the document is submitted, @@ -96,12 +96,12 @@ All the records from the POS stores into the browser's local storegae and sync s Debits: - * Customer (grand total) + * Customer (grand total) * Bank / Cash (payment) Credits: - * Income (net total, minus taxes for each Item) + * Income (net total, minus taxes for each Item) * Taxes (liabilities to be paid to the government) * Customer (payment) * Write Off (optional) @@ -114,4 +114,18 @@ User can send email from the POS, after submission of an order, user has to clic POS Payment After sync of an order, email sent to the customer with the print of the bill in the attachment -{next} \ No newline at end of file + +### POS Closing Voucher + +At the end of its shift, the cashier can close his/her PoS by creating a POS Closing Voucher. + +Click on the menu and select "Close the POS" + +Select the period, your POS Profile and your user to retrieve all sales registered. + +POS Payment + +Enter the collected amount for each mode of payment. +If you notice any difference between the theoretical amount and the collected amount, create a difference posting. + +{next} diff --git a/erpnext/selling/doctype/pos_closing_voucher/__init__.py b/erpnext/selling/doctype/pos_closing_voucher/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html b/erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html new file mode 100644 index 0000000000..2412b071b9 --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html @@ -0,0 +1,84 @@ +
+
+
+
+ + +
+
{{ _("Sales Summary") }}
+
+ + + + + + + + + + + + + + + + + + +
{{ _('Grand Total') }}{{ data.grand_total or '' }} {{ currency.symbol }}
{{ _('Net Total') }}{{ data.net_total or '' }} {{ currency.symbol }}
{{ _('Total Quantity') }}{{ data.total_quantity or '' }}
+
+
+ + + +
+
{{ _("Mode of Payments") }}
+
+ + + + + + + + + {% for d in data.payment_reconciliation %} + + + + + {% endfor %} + +
{{ _("Mode of Payment") }}{{ _("Amount") }}
{{ d.mode_of_payment }}{{ d.expected_amount }} {{ currency.symbol }}
+
+
+ + + +
+
{{ _("Taxes") }}
+
+ + + + + + + + + {% for d in data.taxes %} + + + + + {% endfor %} + +
{{ _("Rate") }}{{ _("Amount") }}
{{ d.rate }} %{{ d.amount }} {{ currency.symbol }}
+
+
+ + +
+
+
+ diff --git a/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js new file mode 100644 index 0000000000..67ff8cb649 --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.js @@ -0,0 +1,72 @@ +// 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 + } + }; + }); + }, + 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_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"); + + 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 new file mode 100644 index 0000000000..077178fa02 --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.json @@ -0,0 +1,823 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "PCV-.#####", + "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": 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": "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": 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_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": "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": "2018-05-31 14:51:19.010430", + "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 +} \ 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 new file mode 100644 index 0000000000..2b66419c89 --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher/pos_closing_voucher.py @@ -0,0 +1,175 @@ +# -*- 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.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 + } + frappe.log_error(filters) + + 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) + + 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 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.db.get_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.js b/erpnext/selling/doctype/pos_closing_voucher/test_pos_closing_voucher.js new file mode 100644 index 0000000000..76338151ec --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher/test_pos_closing_voucher.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: POS Closing Voucher", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new POS Closing Voucher + () => frappe.tests.make('POS Closing Voucher', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); 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 new file mode 100644 index 0000000000..12ddbc2e58 --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher/test_pos_closing_voucher.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import unittest + +class TestPOSClosingVoucher(unittest.TestCase): + pass diff --git a/erpnext/selling/doctype/pos_closing_voucher_details/__init__.py b/erpnext/selling/doctype/pos_closing_voucher_details/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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 new file mode 100644 index 0000000000..a52688462a --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher_details/pos_closing_voucher_details.json @@ -0,0 +1,172 @@ +{ + "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_details/pos_closing_voucher_details.py b/erpnext/selling/doctype/pos_closing_voucher_details/pos_closing_voucher_details.py new file mode 100644 index 0000000000..6bc323f7ad --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher_details/pos_closing_voucher_details.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe.model.document import Document + +class POSClosingVoucherDetails(Document): + pass diff --git a/erpnext/selling/doctype/pos_closing_voucher_invoices/__init__.py b/erpnext/selling/doctype/pos_closing_voucher_invoices/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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 new file mode 100644 index 0000000000..7304550784 --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher_invoices/pos_closing_voucher_invoices.json @@ -0,0 +1,138 @@ +{ + "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_invoices/pos_closing_voucher_invoices.py b/erpnext/selling/doctype/pos_closing_voucher_invoices/pos_closing_voucher_invoices.py new file mode 100644 index 0000000000..a2d488b2f8 --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher_invoices/pos_closing_voucher_invoices.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe.model.document import Document + +class POSClosingVoucherInvoices(Document): + pass diff --git a/erpnext/selling/doctype/pos_closing_voucher_taxes/__init__.py b/erpnext/selling/doctype/pos_closing_voucher_taxes/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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 new file mode 100644 index 0000000000..3089e0621f --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.json @@ -0,0 +1,106 @@ +{ + "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/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.py b/erpnext/selling/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.py new file mode 100644 index 0000000000..87ce842991 --- /dev/null +++ b/erpnext/selling/doctype/pos_closing_voucher_taxes/pos_closing_voucher_taxes.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe.model.document import Document + +class POSClosingVoucherTaxes(Document): + pass diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index fcd221286e..1e0b0f5925 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -512,6 +512,16 @@ erpnext.pos.PointOfSale = class PointOfSale { this.page.add_menu_item(__('Change POS Profile'), function() { me.change_pos_profile(); }); + this.page.add_menu_item(__('Close the POS'), function() { + var voucher = frappe.model.get_new_doc('POS Closing Voucher'); + voucher.pos_profile = me.frm.doc.pos_profile; + voucher.user = frappe.session.user; + voucher.company = me.frm.doc.company; + voucher.period_start_date = me.frm.doc.posting_date; + voucher.period_end_date = me.frm.doc.posting_date; + voucher.posting_date = me.frm.doc.posting_date; + frappe.set_route('Form', 'POS Closing Voucher', voucher.name); + }); } set_form_action() { @@ -727,7 +737,7 @@ class POSCart { ); } - update_qty_total() { + update_qty_total() { var total_item_qty = 0; $.each(this.frm.doc["items"] || [], function (i, d) { if (d.qty > 0) { @@ -1648,4 +1658,4 @@ class Payment { this.dialog.set_value("paid_amount", this.frm.doc.paid_amount); this.dialog.set_value("outstanding_amount", this.frm.doc.outstanding_amount); } -} \ No newline at end of file +}