From 574cd46e410b7c8398fd57f6cc9ee6f9a0ceb9fa Mon Sep 17 00:00:00 2001 From: Bassam Ramadan Date: Thu, 6 Sep 2018 15:32:25 +0200 Subject: [PATCH] Adding cashier closing feature (#15273) * adding cashier closing feature cashier closing feature has been added as now the cashier can make a closure to record every thing from his pos as the expenses which has been paid and the custody which he had at the starting and the amount which is in his save and the system will record the date and time and the user and the total net amount automatically which supposed be equal to all of his sales invoices totals * add cashier closing link at pos menu * add cashier closing link to accounts config file adding cashier closing link at accounts config file to show it at the accounts module page * adding more features to cashier closing adding from time to the cashier closing in case the cashier working more than one shift also giving him the ability to add the type of payments to his cashier closure , also adding validation to be sure the from time is less than to time. * Update cashier_closing.py --- .../doctype/cashier_closing/__init__.py | 0 .../cashier_closing/cashier_closing.js | 11 + .../cashier_closing/cashier_closing.json | 403 ++++++++++++++++++ .../cashier_closing/cashier_closing.py | 36 ++ .../cashier_closing/test_cashier_closing.js | 23 + .../cashier_closing/test_cashier_closing.py | 10 + .../cashier_closing_payments/__init__.py | 0 .../cashier_closing_payments.json | 103 +++++ .../cashier_closing_payments.py | 10 + erpnext/accounts/page/pos/pos.js | 4 + erpnext/config/accounts.py | 5 + 11 files changed, 605 insertions(+) create mode 100644 erpnext/accounts/doctype/cashier_closing/__init__.py create mode 100644 erpnext/accounts/doctype/cashier_closing/cashier_closing.js create mode 100644 erpnext/accounts/doctype/cashier_closing/cashier_closing.json create mode 100644 erpnext/accounts/doctype/cashier_closing/cashier_closing.py create mode 100644 erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js create mode 100644 erpnext/accounts/doctype/cashier_closing/test_cashier_closing.py create mode 100644 erpnext/accounts/doctype/cashier_closing_payments/__init__.py create mode 100644 erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json create mode 100644 erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py diff --git a/erpnext/accounts/doctype/cashier_closing/__init__.py b/erpnext/accounts/doctype/cashier_closing/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/cashier_closing/cashier_closing.js b/erpnext/accounts/doctype/cashier_closing/cashier_closing.js new file mode 100644 index 00000000000..ce791e43acd --- /dev/null +++ b/erpnext/accounts/doctype/cashier_closing/cashier_closing.js @@ -0,0 +1,11 @@ +// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +frappe.ui.form.on('Cashier Closing', { + + setup: function(frm){ + if (frm.doc.user == "" || frm.doc.user == null) { + frm.doc.user = frappe.session.user; + } + } +}); diff --git a/erpnext/accounts/doctype/cashier_closing/cashier_closing.json b/erpnext/accounts/doctype/cashier_closing/cashier_closing.json new file mode 100644 index 00000000000..57a9c7aaddf --- /dev/null +++ b/erpnext/accounts/doctype/cashier_closing/cashier_closing.json @@ -0,0 +1,403 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "naming_series:", + "beta": 0, + "creation": "2018-06-18 16:51:49.994750", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Cashier-closing-", + "fieldname": "naming_series", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 1, + "in_list_view": 0, + "in_standard_filter": 1, + "label": "Series", + "length": 0, + "no_copy": 0, + "options": "Cashier-closing-\n", + "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, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "user", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "User", + "length": 0, + "no_copy": 0, + "options": "User", + "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, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Today", + "fieldname": "date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 1, + "label": "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": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "from_time", + "fieldtype": "Time", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 1, + "label": "From Time", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "", + "fieldname": "time", + "fieldtype": "Time", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 1, + "label": "To Time", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0.00", + "fieldname": "expense", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Expense", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "2", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0.00", + "fieldname": "custody", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Custody", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "2", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0.00", + "fieldname": "outstanding_amount", + "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": "Outstanding Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "2", + "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, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0.0", + "fieldname": "payments", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Payments", + "length": 0, + "no_copy": 0, + "options": "Cashier Closing Payments", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "net_amount", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Net 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, + "unique": 0 + }, + { + "allow_bulk_edit": 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": "Cashier Closing", + "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, + "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-09-03 10:59:54.500567", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Cashier Closing", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "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/accounts/doctype/cashier_closing/cashier_closing.py b/erpnext/accounts/doctype/cashier_closing/cashier_closing.py new file mode 100644 index 00000000000..906bc7f18a5 --- /dev/null +++ b/erpnext/accounts/doctype/cashier_closing/cashier_closing.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document +from frappe.utils import cint, flt, cstr +from frappe import _, msgprint, throw + +class CashierClosing(Document): + def validate(self): + self.validate_time() + + def before_save(self): + self.get_outstanding() + self.make_calculations() + + def get_outstanding(self): + values = frappe.db.sql(""" + select sum(outstanding_amount) + from `tabSales Invoice` + where posting_date=%s and posting_time>=%s and posting_time<=%s and owner=%s + """, (self.date, self.from_time, self.time, self.user)) + self.outstanding_amount = flt(values[0][0] if values else 0) + + def make_calculations(self): + total = 0.00 + for i in self.payments: + total += flt(i.amount) + + self.net_amount = total + self.outstanding_amount + self.expense - self.custody + + def validate_time(self): + if self.from_time >= self.time: + frappe.throw(_("From Time Should Be Less Than To Time")) diff --git a/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js new file mode 100644 index 00000000000..a7fcc8d8421 --- /dev/null +++ b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.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: Cashier Closing", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Cashier Closing + () => frappe.tests.make('Cashier Closing', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.py b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.py new file mode 100644 index 00000000000..3c489a78727 --- /dev/null +++ b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestCashierClosing(unittest.TestCase): + pass diff --git a/erpnext/accounts/doctype/cashier_closing_payments/__init__.py b/erpnext/accounts/doctype/cashier_closing_payments/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json new file mode 100644 index 00000000000..bdfc70f8b18 --- /dev/null +++ b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json @@ -0,0 +1,103 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-09-02 14:45:36.303520", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "mode_of_payment", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "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, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0.00", + "fieldname": "amount", + "fieldtype": "Float", + "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": "2", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2018-09-02 14:45:36.303520", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Cashier Closing Payments", + "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/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py new file mode 100644 index 00000000000..f73703158d8 --- /dev/null +++ b/erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class CashierClosingPayments(Document): + pass diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index ce1f34bb27a..528e3d3f9cd 100755 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -123,6 +123,10 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ me.sync_sales_invoice() }); + this.page.add_menu_item(__("Cashier Closing"), function () { + frappe.set_route('List', 'Cashier Closing'); + }); + this.page.add_menu_item(__("POS Profile"), function () { frappe.set_route('List', 'POS Profile'); }); diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py index 5526ac86999..660f78cc911 100644 --- a/erpnext/config/accounts.py +++ b/erpnext/config/accounts.py @@ -32,6 +32,11 @@ def get_data(): "label": _("POS"), "description": _("Point of Sale") }, + { + "type": "doctype", + "name": "Cashier Closing", + "description": _("Cashier Closing") + }, { "type": "doctype", "name": "Auto Repeat",