From 9a605f5069bdb4108b7d4f2e76094aad39240129 Mon Sep 17 00:00:00 2001 From: Ajay Javiya Date: Mon, 13 Apr 2020 10:33:00 +0530 Subject: [PATCH 01/10] [MIG] Migration to 12.0: pos_automatic_cashdrawer --- pos_automatic_cashdrawer/README.rst | 37 ++ pos_automatic_cashdrawer/__init__.py | 1 + pos_automatic_cashdrawer/__manifest__.py | 22 + pos_automatic_cashdrawer/demo/demo.xml | 10 + pos_automatic_cashdrawer/i18n/fr.po | 574 ++++++++++++++++++ .../i18n/pos_automatic_cashdrawer.pot | 96 +++ pos_automatic_cashdrawer/models/__init__.py | 3 + .../models/account_journal.py | 14 + pos_automatic_cashdrawer/models/pos_config.py | 46 ++ .../models/pos_session.py | 140 +++++ .../security/res_groups.xml | 9 + .../src/css/pos_automatic_cashdrawer.css | 81 +++ .../static/src/js/chrome.js | 129 ++++ .../static/src/js/devices.js | 299 +++++++++ .../static/src/js/models.js | 141 +++++ .../static/src/js/screens.js | 85 +++ .../static/src/js/widgets.js | 532 ++++++++++++++++ .../src/xml/pos_automatic_cashdrawer.xml | 234 +++++++ .../views/account_journal.xml | 14 + pos_automatic_cashdrawer/views/assets.xml | 13 + pos_automatic_cashdrawer/views/pos_config.xml | 26 + 21 files changed, 2506 insertions(+) create mode 100644 pos_automatic_cashdrawer/README.rst create mode 100644 pos_automatic_cashdrawer/__init__.py create mode 100644 pos_automatic_cashdrawer/__manifest__.py create mode 100644 pos_automatic_cashdrawer/demo/demo.xml create mode 100644 pos_automatic_cashdrawer/i18n/fr.po create mode 100644 pos_automatic_cashdrawer/i18n/pos_automatic_cashdrawer.pot create mode 100644 pos_automatic_cashdrawer/models/__init__.py create mode 100644 pos_automatic_cashdrawer/models/account_journal.py create mode 100644 pos_automatic_cashdrawer/models/pos_config.py create mode 100644 pos_automatic_cashdrawer/models/pos_session.py create mode 100644 pos_automatic_cashdrawer/security/res_groups.xml create mode 100644 pos_automatic_cashdrawer/static/src/css/pos_automatic_cashdrawer.css create mode 100755 pos_automatic_cashdrawer/static/src/js/chrome.js create mode 100755 pos_automatic_cashdrawer/static/src/js/devices.js create mode 100755 pos_automatic_cashdrawer/static/src/js/models.js create mode 100755 pos_automatic_cashdrawer/static/src/js/screens.js create mode 100755 pos_automatic_cashdrawer/static/src/js/widgets.js create mode 100644 pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml create mode 100644 pos_automatic_cashdrawer/views/account_journal.xml create mode 100644 pos_automatic_cashdrawer/views/assets.xml create mode 100644 pos_automatic_cashdrawer/views/pos_config.xml diff --git a/pos_automatic_cashdrawer/README.rst b/pos_automatic_cashdrawer/README.rst new file mode 100644 index 0000000000..dda821e86c --- /dev/null +++ b/pos_automatic_cashdrawer/README.rst @@ -0,0 +1,37 @@ +POS Payment Terminal +==================== + +This module adds support for automatic cashdrawers in the Point of Sale. + + +Installation +============ + +This module is designed to be installed on the +*main Odoo server*. On the *POSbox*, you should install the module +*hw_x* depending on the protocol implemented in your device. +`Cashlogy ` are implemented in the +*hw_cashlogy* module and also in pywebdriver . + +Configuration +============= + +The cashlogyConnector adddress and port should be configured on the main Odoo server, +in the menu *Pointof Sale > Configuration > Payment Methods*,under the *Point of Sale* tab. + +Usage +===== + +In the frontend of the POS, when you select a payment method CASH you will have a *Start Transaction* button : +if you click on that button, the amount will be sent to the POSbox. + +Credits +======= + +Contributors +------------ + +* Aurelien Dumaine +* Mathieu Vatel +* Druidoo + diff --git a/pos_automatic_cashdrawer/__init__.py b/pos_automatic_cashdrawer/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/pos_automatic_cashdrawer/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/pos_automatic_cashdrawer/__manifest__.py b/pos_automatic_cashdrawer/__manifest__.py new file mode 100644 index 0000000000..0454dc083e --- /dev/null +++ b/pos_automatic_cashdrawer/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright (C) 2014 Aurélien DUMAINE +# Copyright (C) 2015 Akretion (www.akretion.com) +# Copyright (C) 2019-Today: Druidoo () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "POS Automatic Cashdrawer", + "version": "12.0.1.0.0", + "category": "Point Of Sale", + "summary": "Manage Automatic Cashdrawer device from POS front end", + "author": "Aurélien DUMAINE, Druidoo", + "license": "AGPL-3", + "depends": ["point_of_sale"], + "data": [ + "security/res_groups.xml", + "views/assets.xml", + "views/account_journal.xml", + "views/pos_config.xml", + ], + "qweb": ["static/src/xml/pos_automatic_cashdrawer.xml"], + "demo": ["demo/demo.xml"], +} diff --git a/pos_automatic_cashdrawer/demo/demo.xml b/pos_automatic_cashdrawer/demo/demo.xml new file mode 100644 index 0000000000..57bef68c3a --- /dev/null +++ b/pos_automatic_cashdrawer/demo/demo.xml @@ -0,0 +1,10 @@ + + + + + + 127.0.0.1 + 8092 + + + diff --git a/pos_automatic_cashdrawer/i18n/fr.po b/pos_automatic_cashdrawer/i18n/fr.po new file mode 100644 index 0000000000..b6d388fa10 --- /dev/null +++ b/pos_automatic_cashdrawer/i18n/fr.po @@ -0,0 +1,574 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_automatic_cashdrawer +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-04-09 09:17+0000\n" +"PO-Revision-Date: 2020-04-09 09:17+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:173 +#, python-format +msgid " but the dispensed amount was: " +msgstr " but the dispensed amount was: " + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:250 +#, python-format +msgid "AccessError" +msgstr "AccessError" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:400 +#, python-format +msgid "Added Cash" +msgstr "Monnaie Cash ajoutée" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:53 +#, python-format +msgid "Added so far" +msgstr "Added so far" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer +msgid "An automatic cashdrawer is available on the Proxy" +msgstr "An automatic cashdrawer is available on the Proxy" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:109 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:184 +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer +#, python-format +msgid "Automatic Cashdrawer" +msgstr "Monnayeur automatique" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:75 +#, python-format +msgid "Automatic Cashdrawer Connecting.." +msgstr "Connexion au Monnayeur automatique..." + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_ip_address +msgid "Automatic Cashdrawer IP address" +msgstr "Monnayeur automatique IP address" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:79 +#, python-format +msgid "Automatic Cashdrawer Offline" +msgstr "Automatic Cashdrawer Offline" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_tcp_port +msgid "Automatic Cashdrawer TCP port" +msgstr "Monnayeur automatique TCP port" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:233 +#, python-format +msgid "Automatic Cashdrawer: Close Till / ADDED" +msgstr "Monnayeur automatique: Close Till / ADDED" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:247 +#, python-format +msgid "Automatic Cashdrawer: Close Till / DISPENSED" +msgstr "Monnayeur automatique: Close Till / DISPENSED" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:305 +#, python-format +msgid "Automatic Cashdrawer: Complete Emptying" +msgstr "Automatic Cashdrawer: Complete Emptying" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:276 +#, python-format +msgid "Automatic Cashdrawer: Empty Stacker" +msgstr "Monnayeur automatique: Empty Stacker" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_account_journal_iface_automatic_cashdrawer +msgid "Automatic cashdrawer" +msgstr "Monnayeur automatique" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:35 +#, python-format +msgid "Cancel" +msgstr "Cancel" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:142 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:157 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:227 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:270 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:299 +#, python-format +msgid "Cash In/Out not possible" +msgstr "Cash In/Out not possible" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:190 +#, python-format +msgid "Cash Withdrawal" +msgstr "Retrait de cash" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:15 +#, python-format +msgid "Cashdrawer Admin" +msgstr "Cashdrawer Admin" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:62 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:81 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:99 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:117 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:146 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:164 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:192 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:208 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:224 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:255 +#, python-format +msgid "Cashdrawer Error: " +msgstr "Erreur Monnayeur automatique" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:6 +#, python-format +msgid "Cashlogy Backoffice" +msgstr "Cashlogy Backoffice" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_account_journal_iface_automatic_cashdrawer +msgid "Check this if this journal is linked to an automatic cashdrawer" +msgstr "Vérifiez sur ce journal est lié à un monnayeur automatique" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:97 +#, python-format +msgid "Close" +msgstr "Close" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:22 +#, python-format +msgid "Close Till / Cash Float" +msgstr "Close Till / Cash Float" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:251 +#, python-format +msgid "Close Till Result" +msgstr "Close Till Result" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:237 +#, python-format +msgid "Close Till: Put In" +msgstr "Close Till: Put In" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:349 +#, python-format +msgid "Closing Balance Set" +msgstr "Closing Balance Set" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:309 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:24 +#, python-format +msgid "Complete Emptying" +msgstr "Complete Emptying" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:57 +#, python-format +msgid "Confirm" +msgstr "Confirm" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:176 +#, python-format +msgid "Could not dispense the value requested" +msgstr "Ne peu remettre la valeur demandée" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:186 +#, python-format +msgid "Dispensed: " +msgstr "Dispensed: " + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:280 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:23 +#, python-format +msgid "Empty Stacker" +msgstr "Empty Stacker" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:214 +#, python-format +msgid "IMPORTANT: This operations is not registered on the cash statement. You have to manually register it." +msgstr "IMPORTANT: Cette opération n'est pas enregistrées sur le journal d'espèces, vous devez les enregistrer manuellement." + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:110 +#, python-format +msgid "Inventory" +msgstr "Inventory" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:338 +#, python-format +msgid "It looks the session is already opened" +msgstr "Il semble qu'une session soit déjà ouverte." + +#. module: pos_automatic_cashdrawer +#: model:ir.model,name:pos_automatic_cashdrawer.model_account_journal +msgid "Journal" +msgstr "Journal" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:211 +#, python-format +msgid "Manual Cancel" +msgstr "Annulation Manuelle" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:396 +#, python-format +msgid "Manual: put money in" +msgstr "Action Manuelle: placez les espèces." + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:185 +#, python-format +msgid "Manual: take money out" +msgstr "Action Manuelle: retirez les espèces" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:237 +#, python-format +msgid "Method not implemented yet" +msgstr "Methode pas encore implementée" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:213 +#, python-format +msgid "Money in/out: " +msgstr "Ajout / retrait d'espèces. " + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:236 +#, python-format +msgid "Not implemented" +msgstr "Non implementé" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:31 +#, python-format +msgid "Open Backoffice" +msgstr "Open Backoffice" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:330 +#, python-format +msgid "Opening Balance Set" +msgstr "Ouverture du réglage de balance." + +#. module: pos_automatic_cashdrawer +#: code:addons/pos_automatic_cashdrawer/models/pos_session.py:64 +#, python-format +msgid "Please check that the field 'Journal' is set on the Bank Statement" +msgstr "Vérifiez que le champ 'Journal' est configuré sur les données de la Banque" + +#. module: pos_automatic_cashdrawer +#: code:addons/pos_automatic_cashdrawer/models/pos_session.py:68 +#, python-format +msgid "Please check that the field 'Transfer Account' is set on the company." +msgstr "Vérifiez que le champ 'Compte de transfert' est défini pour cette société." + +#. module: pos_automatic_cashdrawer +#: model:res.groups,name:pos_automatic_cashdrawer.group_pos_automatic_cashlogy_config +msgid "PoS - Allow Cashlogy config" +msgstr "Point de vente - Autoriser configuration Cashlogy" + +#. module: pos_automatic_cashdrawer +#: model:res.groups,name:pos_automatic_cashdrawer.group_pos_automatic_cashlogy +msgid "PoS - Allow Cashlogy connection" +msgstr "Point de vente - Autoriser la connexion Cashlogy" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy_config +msgid "Point of Sale - Allow Cashlogy Config" +msgstr "Point de Vente - Autoriser Cashlogy Config" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:98 +#, python-format +msgid "Print" +msgstr "Print" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:21 +#, python-format +msgid "Print Inventory" +msgstr "Print Inventory" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:18 +#, python-format +msgid "Put Money In" +msgstr "Put Money In" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:220 +#, python-format +msgid "REF:" +msgstr "REF:" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:78 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:153 +#, python-format +msgid "Recycler" +msgstr "Recycler" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:32 +#, python-format +msgid "Send Cancel Command" +msgstr "Send Cancel Command" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/models.js:66 +#, python-format +msgid "Set balance error: " +msgstr "Set balance error: " + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:79 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:157 +#, python-format +msgid "Stacker" +msgstr "Stacker" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:46 +#, python-format +msgid "Start adding cash into the machine." +msgstr "Start adding cash into the machine." + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:219 +#, python-format +msgid "Statement:" +msgstr "Statement:" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:331 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:350 +#, python-format +msgid "Success" +msgstr "Success" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:34 +#, python-format +msgid "Sync Opening Balance" +msgstr "Synchronisation de l'ouverture Balance" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:69 +#, python-format +msgid "Synchronizing automatic cashdrawer inventory" +msgstr "Synchronisation de l'inventaire du Monnayeur automatique." + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:165 +#, python-format +msgid "TOTAL" +msgstr "TOTAL" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:133 +#, python-format +msgid "TOTALS" +msgstr "TOTALS" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:19 +#, python-format +msgid "Take Money Out" +msgstr "Take Money Out" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:180 +#, python-format +msgid "The dispensed amount was: " +msgstr "The dispensed amount was: " + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:35 +#, python-format +msgid "The opening balance for this session is missing. Do you wan't to synchronize it with the automatic cashdrawer?" +msgstr "La balance d'ouverture pour cette session est manquante. Voulez vous la synchroniser avec le monnayeur automatique ?" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_tcp_port +msgid "The port to connect to the Cashdrawer.\n" +"WARNING: set a port bigger than 1024 to allow a non-root user to listen on it." +msgstr "Port à connecter au Monnayeur automatique.\n" +"WARNING: configurez un port plus grand que 1024 pour autoriser l'écoute par un utilisateur non root." + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:173 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:178 +#, python-format +msgid "The requested amount to dispense was: " +msgstr "The requested amount to dispense was: " + +#. module: pos_automatic_cashdrawer +#: code:addons/pos_automatic_cashdrawer/models/pos_session.py:61 +#, python-format +msgid "There's no cash register on this session" +msgstr "Il n'y a pas de caisse enregistreuse sur la session" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy_config +msgid "This field is there to pass the id of the \"PoS - Allow Cashlogy config\" group to the POS." +msgstr "This field is there to pass the id of the \"PoS - Allow Cashlogy config\" group to the POS." + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:80 +#, python-format +msgid "Total" +msgstr "Total" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:239 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:402 +#, python-format +msgid "Total added: " +msgstr "Total added: " + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:253 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:282 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:311 +#, python-format +msgid "Total dispensed: " +msgstr "Total dispensed: " + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:337 +#, python-format +msgid "Unable to set balance on opened sessions" +msgstr "Unable to set balance on opened sessions" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:126 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:202 +#, python-format +msgid "User:" +msgstr "User:" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:47 +#, python-format +msgid "When you finish, press confirm." +msgstr "When you finish, press confirm." + +#. module: pos_automatic_cashdrawer +#: code:addons/pos_automatic_cashdrawer/models/pos_session.py:72 +#, python-format +msgid "You cannot put/take money in/out for a bank statement which is closed." +msgstr "Vous ne pouvez pas placer ou retirer des espèces d'un journal de banque fermé." + +#. module: pos_automatic_cashdrawer +#: model:ir.model,name:pos_automatic_cashdrawer.model_pos_config +msgid "pos.config" +msgstr "pos.config" + +#. module: pos_automatic_cashdrawer +#: model:ir.model,name:pos_automatic_cashdrawer.model_pos_session +msgid "pos.session" +msgstr "pos.session" + diff --git a/pos_automatic_cashdrawer/i18n/pos_automatic_cashdrawer.pot b/pos_automatic_cashdrawer/i18n/pos_automatic_cashdrawer.pot new file mode 100644 index 0000000000..c6346251ee --- /dev/null +++ b/pos_automatic_cashdrawer/i18n/pos_automatic_cashdrawer.pot @@ -0,0 +1,96 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_automatic_cashdrawer +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0c\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer +msgid "An automatic cashdrawer is available on the Proxy" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_account_journal_iface_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer +msgid "Automatic cashdrawer" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_ip_address +msgid "Automatic cashdrawer IP address" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_tcp_port +msgid "Automatic cashdrawer TCP port" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_display_accept_button +msgid "Automatic cashdrawer display accept button" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_screen_on_top +msgid "Automatic cashdrawer screen on top" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_account_journal_iface_automatic_cashdrawer +msgid "Check this if this journal is linked to an automatic cashdrawer" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model,name:pos_automatic_cashdrawer.model_account_journal +msgid "Journal" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:res.groups,name:pos_automatic_cashdrawer.group_pos_automatic_cashlogy_config +msgid "PoS - Allow Cashlogy config" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:res.groups,name:pos_automatic_cashdrawer.group_pos_automatic_cashlogy +msgid "PoS - Allow Cashlogy connection" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy_config +msgid "Point of Sale - Allow Cashlogy Config" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy +msgid "Point of Sale - Allow Cashlogy connection" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy_config +msgid "This field is there to pass the id of the 'PoS - Allow Cashlogy config' Group to the Point of Sale Frontend." +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy +msgid "This field is there to pass the id of the 'PoS - Allow Cashlogy connection' Group to the Point of Sale Frontend." +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model,name:pos_automatic_cashdrawer.model_pos_config +msgid "pos.config" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model,name:pos_automatic_cashdrawer.model_pos_session +msgid "pos.session" +msgstr "" + diff --git a/pos_automatic_cashdrawer/models/__init__.py b/pos_automatic_cashdrawer/models/__init__.py new file mode 100644 index 0000000000..a02d41b97d --- /dev/null +++ b/pos_automatic_cashdrawer/models/__init__.py @@ -0,0 +1,3 @@ +from . import account_journal +from . import pos_config +from . import pos_session diff --git a/pos_automatic_cashdrawer/models/account_journal.py b/pos_automatic_cashdrawer/models/account_journal.py new file mode 100644 index 0000000000..0f88a3505d --- /dev/null +++ b/pos_automatic_cashdrawer/models/account_journal.py @@ -0,0 +1,14 @@ +# Copyright (C) 2015 Mathieu VATEL +# Copyright (C) 2016-Today: La Louve +# Copyright (C) 2019 Druidoo + +from odoo import models, fields + + +class AccountJournal(models.Model): + _inherit = "account.journal" + + iface_automatic_cashdrawer = fields.Boolean( + "Automatic cashdrawer", + help="Check this if this journal is linked to an automatic cashdrawer", + ) diff --git a/pos_automatic_cashdrawer/models/pos_config.py b/pos_automatic_cashdrawer/models/pos_config.py new file mode 100644 index 0000000000..35b32852c8 --- /dev/null +++ b/pos_automatic_cashdrawer/models/pos_config.py @@ -0,0 +1,46 @@ +# Copyright (C) 2015 Mathieu VATEL +# Copyright (C) 2016-Today: La Louve () +# Copyright (C) 2019 Druidoo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models, api + + +class PosConfig(models.Model): + _inherit = "pos.config" + + iface_automatic_cashdrawer = fields.Boolean( + "Automatic Cashdrawer", + help="An automatic cashdrawer is available on the Proxy", + ) + + iface_automatic_cashdrawer_ip_address = fields.Char( + "Automatic Cashdrawer IP address", + ) + + iface_automatic_cashdrawer_tcp_port = fields.Char( + "Automatic Cashdrawer TCP port", + help=( + "The port to connect to the Cashdrawer.\n" + "WARNING: set a port bigger than 1024 to allow a non-root user to " + "listen on it." + ), + ) + + group_pos_automatic_cashlogy_config = fields.Many2one( + comodel_name="res.groups", + compute="_compute_group_pos_automatic_cashlogy_config", + string="Point of Sale - Allow Cashlogy Config", + help=( + "This field is there to pass the id of the " + '"PoS - Allow Cashlogy config" group to the POS.' + ), + ) + + @api.multi + def _compute_group_pos_automatic_cashlogy_config(self): + group_id = self.env.ref( + "pos_automatic_cashdrawer.group_pos_automatic_cashlogy_config" + ) + for rec in self: + rec.group_pos_automatic_cashlogy_config = group_id.id diff --git a/pos_automatic_cashdrawer/models/pos_session.py b/pos_automatic_cashdrawer/models/pos_session.py new file mode 100644 index 0000000000..ea2e951cc5 --- /dev/null +++ b/pos_automatic_cashdrawer/models/pos_session.py @@ -0,0 +1,140 @@ +# Copyright (C) 2019 Druidoo + +import logging + +from odoo import api, models, _ +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class PosSession(models.Model): + _inherit = "pos.session" + + @api.multi + def check_opening_balance_missing(self): + """ + Checks if the opening balance is missing + If it is, returns the theoretical starting balance + """ + self.ensure_one() + self.check_cash_in_out_possible() + missing = True + if self.cash_register_id.cashbox_start_id: + # Cashbox already started + missing = False + if self.cash_register_id.line_ids: + _logger.warning("Cashbox is missing but there are already lines") + missing = False + return { + "missing": missing, + "balance_start": self.cash_register_balance_start, + } + + @api.multi + def action_set_balance(self, inventory, balance="start"): + """ + Sets the opening balance. + Inventory is a dict with: + { denomination: quantity } + """ + self.ensure_one() + self.check_cash_in_out_possible() + # Try to fetch current cashbox + if balance == "start": + cashbox = self.cash_register_id.cashbox_start_id + else: + cashbox = self.cash_register_id.cashbox_end_id + # Or create a new one.. + if not cashbox: + cashbox = self.env["account.bank.statement.cashbox"].create({}) + # Add context values + cashbox = cashbox.with_context( + bank_statement_id=self.cash_register_id.id, balance=balance + ) + # Replace lines with inventory + cashbox.cashbox_lines_ids = [(5, 0, 0)] + cashbox.cashbox_lines_ids = [ + (0, 0, {"coin_value": value, "number": number}) + for value, number in inventory.items() + ] + # Validate + cashbox.validate() + return True + + @api.multi + def check_cash_in_out_possible(self): + self.ensure_one() + if not self.cash_register_id: + raise UserError(_("There's no cash register on this session")) + if not self.cash_register_id.journal_id: + raise UserError( + _( + "Please check that the field 'Journal' is set " + "on the Bank Statement" + ) + ) + if not self.cash_register_id.journal_id.company_id.transfer_account_id: + raise UserError( + _( + "Please check that the field 'Transfer Account' is set " + "on the company." + ) + ) + if self.cash_register_id.state == "confirm": + raise UserError( + _( + "You cannot put/take money in/out for a bank statement " + "which is closed." + ) + ) + return True + + @api.model + def _get_cash_in_out_fields(self): + return [ + "id", + "display_name", + "ref", + "create_date", + "date", + "statement_id", + ] + + @api.multi + def action_put_money_in(self, amount, reason): + self.ensure_one() + wizard = self.env["cash.box.in"].create( + {"amount": amount, "name": reason} + ) + wizard.with_context(active_model=self._name, active_ids=self.ids).run() + # Return the last added line + return ( + self.env["account.bank.statement.line"] + .sudo() + .search( + [("statement_id", "=", self.cash_register_id.id)], + limit=1, + order="id desc", + ) + .read(self._get_cash_in_out_fields())[0] + ) + + @api.multi + def action_take_money_out(self, amount, reason): + self.ensure_one() + wizard = self.env["cash.box.out"].create( + {"amount": amount, "name": reason} + ) + wizard.with_context(active_model=self._name, active_ids=self.ids).run() + # Return the last added line + return ( + self.env["account.bank.statement.line"] + .sudo() + .search( + [("statement_id", "=", self.cash_register_id.id)], + limit=1, + order="id desc", + ) + .read(self._get_cash_in_out_fields())[0] + ) diff --git a/pos_automatic_cashdrawer/security/res_groups.xml b/pos_automatic_cashdrawer/security/res_groups.xml new file mode 100644 index 0000000000..76ec169c17 --- /dev/null +++ b/pos_automatic_cashdrawer/security/res_groups.xml @@ -0,0 +1,9 @@ + + + + + PoS - Allow Cashlogy config + + + + diff --git a/pos_automatic_cashdrawer/static/src/css/pos_automatic_cashdrawer.css b/pos_automatic_cashdrawer/static/src/css/pos_automatic_cashdrawer.css new file mode 100644 index 0000000000..ac0591be04 --- /dev/null +++ b/pos_automatic_cashdrawer/static/src/css/pos_automatic_cashdrawer.css @@ -0,0 +1,81 @@ +.automatic-cashdrawer-transaction-start button { + width: 150px; + height: 60px; + font-size: 18px; + cursor: pointer; + text-align:center; + box-sizing: border-box; + -moz-box-sizing: border-box; + left: 105%; + bottom: 10px; + position: absolute; +} + +.pos .modal-dialog .popup.popup-cashdrawer-admin { + height: 650px; +} + +.pos .popup-cashdrawer-admin .actions .button { + float: none; + width: auto; + margin: 15px; + height: 40px; + line-height: 40px; + font-size: 16px; + font-weight: normal; + position: relative; +} + +.pos .popup-cashdrawer-admin hr { + border-color: rgba(60,60,60,0.1); + margin: 10px 15px; +} + +.pos .popup-cashdrawer-admin .actions .button .fa { + position: absolute; + left: 15px; + top: 8px; + margin-right: 8px; + font-size: 25px; + width: 35px; +} + +.pos .popup-cashdrawer .total .value { + text-align: center; + padding: 24px 0px 18px; + font-size: 64px; + color: #43996E; + text-shadow: 0px 2px white, 0px 2px 2px rgba(0, 0, 0, 0.27); +} + + +.pos .modal-dialog .popup-cashdrawer-inventory { + height: 700px; +} + +.pos .popup-cashdrawer-inventory .inventory-table { + padding: 20px; +} + +.pos .popup-cashdrawer-inventory .inventory-table table { + width: 100%; + font-weight: normal; + font-size: 15px; + text-align: right; +} + +.pos .popup-cashdrawer-inventory .inventory-table table td { + line-height: 25px; + padding: 0 10px; +} + +.pos .popup-cashdrawer-inventory .inventory-table table th { + line-height: 30px; + padding: 0 10px; + width: 25%; +} + +.pos .popup-cashdrawer-inventory .inventory-table thead > tr, +.pos .popup-cashdrawer-inventory .inventory-table tr:nth-child(even) { + background: rgb(247,247,247); +} diff --git a/pos_automatic_cashdrawer/static/src/js/chrome.js b/pos_automatic_cashdrawer/static/src/js/chrome.js new file mode 100755 index 0000000000..807bd8dc22 --- /dev/null +++ b/pos_automatic_cashdrawer/static/src/js/chrome.js @@ -0,0 +1,129 @@ +/* + POS Automatic Cashdrawer module for Odoo + Copyright (C) 2019-Today: Druidoo () + The licence is in the file __manifest__.py +*/ + +odoo.define('pos_automatic_cashdrawer.chrome', function (require) { + "use strict"; + + var chrome = require('point_of_sale.chrome'); + var gui = require('point_of_sale.gui'); + var core = require('web.core'); + var framework = require('web.framework'); + + var _t = core._t; + + chrome.Chrome.include({ + + /* + Extend init to display an open session balance message + It will check if the session has an opening balance cashbox and + if it doesn't, it will syncrhonize it as long as it's the same amount. + If it's different, it will ask for a manager and offer to overwrite it + */ + init: function () { + var self = this; + this._super.apply(this, arguments); + this.ready.done(function () { + if (self.pos.config.iface_automatic_cashdrawer && self.pos.config.cash_control) { + self.pos.check_opening_balance_missing().then(function (res) { + var missing = res['missing']; + var balance_start = res['balance_start']; + // It's not missing, do nothing + if (!missing) return; + // Get the inventory from cashdrawer + framework.blockUI(); + $.when( + self.pos.proxy.automatic_cashdrawer_get_total_amount(), + self.pos.proxy.automatic_cashdrawer_get_inventory() + ).then(function (totals, inventory) { + // Check if the amount is different + if (totals.total != balance_start) { + // Check access rights + var user = self.pos.get_cashier(); + if (user.groups_id.indexOf(self.pos.config.group_pos_automatic_cashlogy_config[0]) != -1) { + self.gui.show_popup('confirm', { + title: _t('The opening balance does not match'), + body: + _t('The opening balance for this session does not match with the Cashdrawer Inventory.') + '\n' + + _t('Do you want to overwrite it with the real amount?') + '\n\n' + + _t('Cashdrawer Inventory: ') + self.format_currency(totals.total) + '\n' + + _t('Session Starting Balance: ') + self.format_currency(balance_start), + confirm: function () { + framework.blockUI(); + self.pos.action_set_balance(inventory.total, 'start') + .always(function () { + framework.unblockUI(); + }); + } + }); + // If user does not have enough access rights, we block the POS + } else { + self.gui.show_popup('error', { + title: _t('The opening balance does not match'), + body: + _t('The opening balance for this session does not match with the Cashdrawer Inventory.') + '\n' + + _t('Please ask your manager to fix it.') + }); + } + // If inventory matchs, we still need to syncronize it + // But we do it without asking + } else { + framework.blockUI(); + self.pos.action_set_balance(inventory.total, 'start') + .always(function () { framework.unblockUI(); }); + } + }).fail(function (error) { + self.gui.show_popup('error', { + title: _t('Unable to syncronize inventory'), + body: _t('Check that the Cashdrawer is online before starting the session, and refresh the browser.\n\n') + error.data.message, + }); + }).always(function () { + framework.unblockUI(); + }); + }); + } + }); + }, + + }); + + + gui.Gui.include({ + + /* + Overload close so that we can synchronize the closing balance + */ + close: function () { + var self = this; + var args = arguments; + var _super = this._super; + + if (!this.pos.config.iface_automatic_cashdrawer) { + return this._super.apply(this, arguments); + } + + self.chrome.loading_show(); + self.chrome.loading_message(_t('Synchronizing automatic cashdrawer inventory')); + self.pos.proxy.automatic_cashdrawer_get_inventory() + .then(function (inventory) { + self.pos.action_set_balance(inventory.total, 'end').then(function () { + _super.apply(self, args); + }); + }) + .fail(function () { + _super.apply(self, args); + }) + .always(function () { + self.chrome.loading_hide(); + }); + }, + + }); + + return { + chrome: chrome.Chrome, + gui: gui.Gui, + }; +}); diff --git a/pos_automatic_cashdrawer/static/src/js/devices.js b/pos_automatic_cashdrawer/static/src/js/devices.js new file mode 100755 index 0000000000..767f5d0eb3 --- /dev/null +++ b/pos_automatic_cashdrawer/static/src/js/devices.js @@ -0,0 +1,299 @@ +/* + POS Automatic Cashdrawer module for Odoo + Copyright (C) 2016 Aurélien DUMAINE + Copyright (C) 2019-Today: Druidoo () + @author: Aurélien DUMAINE + The licence is in the file __manifest__.py +*/ + +odoo.define('pos_automatic_cashdrawer.devices', function (require) { + "use strict"; + + var devices = require('point_of_sale.devices'); + var core = require('web.core'); + var framework = require('web.framework'); + + var _t = core._t; + + devices.ProxyDevice.include({ + + /* + Overload keepalive. + This function is called right after the PosBox is connected and the handshake is made. + Normally, it starts a keepalive timer that request /hw_proxy/status_json + But we're also sending the Cashdrawer connection config here. + */ + keepalive: function () { + this._super.apply(this, arguments); + if (this.pos.config.iface_automatic_cashdrawer) { + this.message('cashlogy/connect', { + 'config': { + 'host': this.pos.config.iface_automatic_cashdrawer_ip_address, + 'port': this.pos.config.iface_automatic_cashdrawer_tcp_port + } + }); + } + }, + + /* + Starts a sale transaction using the backoffice. + It will display the backoffice window so that the cashier can + confirm the amount. + It will return the collected amount. + + options.operation_number default to 00000 + + Possible exceptions: + CancelledOperation + Busy + + @returns {amount: 0.00, amount_in: 0.00, amount_out: 0.00} + */ + automatic_cashdrawer_display_transaction_start: function (amount, options) { + options = options || {}; + var self = this; + var done = this.message('cashlogy/display_transaction_start', { + 'amount': amount, + 'options': options, + }); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + framework.blockUI(); + done.always(function () { + framework.unblockUI(); + }); + return done; + }, + + /* + Display Close Till + + @returns {total_before: 0.00, added: 0.00, dispensed: 0.00, total: 0.00} + */ + automatic_cashdrawer_display_close_till: function () { + var self = this; + var done = this.message('cashlogy/display_close_till'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + framework.blockUI(); + done.always(function () { + framework.unblockUI(); + }); + return done; + }, + + /* + Displays the backoffice complete emptying wizard. + @returns 0.00 - the dispensed amount + */ + automatic_cashdrawer_display_complete_emptying: function () { + var self = this; + var done = this.message('cashlogy/display_complete_emptying'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + framework.blockUI(); + done.always(function () { + framework.unblockUI(); + }); + return done; + }, + + /* + Displays the backoffice empty stacker wizard. + @returns 0.00 - the amount removed from stacker + */ + automatic_cashdrawer_display_empty_stacker: function () { + var self = this; + var done = this.message('cashlogy/display_empty_stacker'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + framework.blockUI(); + done.always(function () { + framework.unblockUI(); + }); + return done; + }, + + /* + Dispenses money + amount float + options.only_coins default False + + @returns 0.00 + */ + automatic_cashdrawer_dispense: function (amount, options) { + options = options || {}; + var self = this; + var done = this.message('cashlogy/dispense', { + 'amount': amount, + 'options': options, + }); + done.done(function (res) { + if (res !== amount) { + console.error('Cashlogy', 'The dispensed amount was different than the requested', amount, res); + } + }).fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + return done; + }, + + /* + Start add change + Used to load money into the cashdrawer + It has to be stopped using stop_acceptance + The amount loaded so far can be queried with get_amount_accepted + */ + automatic_cashdrawer_start_add_change: function () { + var self = this; + var done = this.message('cashlogy/start_add_change'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + return done; + }, + + /* + Returns the money accepted so far + @returns 0.00 + */ + automatic_cashdrawer_get_amount_accepted: function () { + var done = this.message('cashlogy/get_amount_accepted'); + // Silently fail + done.fail(function (error) { + console.error(error); + }); + return done; + }, + + /* + Stops acceptance of money + @returns 0.00 + */ + automatic_cashdrawer_stop_acceptance: function () { + var self = this; + var done = this.message('cashlogy/stop_acceptance'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + return done; + }, + + /* + Gets the inventory of the machine + Returns {total: {}, recycler: {}, stacker: {}} + */ + automatic_cashdrawer_get_inventory: function () { + var self = this; + var done = this.message('cashlogy/get_inventory'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + return done; + }, + + /* + Gets the total amount on the machine + Returns {total: 0.00, recycler: 0.00, stacker: 0.00} + */ + automatic_cashdrawer_get_total_amount: function () { + var self = this; + var done = this.message('cashlogy/get_total_amount'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + return done; + }, + + /* + Prints the current inventory of the machine + */ + automatic_cashdrawer_print_inventory: function () { + this.pos.gui.show_popup('error', { + title: _t('Not implemented'), + body: _t('Method not implemented yet') + }); + return $.Deferred().reject('Not implemented yet. TODO'); + }, + + /* + Displays the backoffice panel. + TODO: Move this to pos_automatic_cashdrawer_cashlogy, or somehow toggle this feature + depending on a supported feature list. + */ + automatic_cashdrawer_display_backoffice: function () { + // TODO : only managers should be able to see/clic this button + // Check for security group of current user + // if (!true) { + // return $.Deferred().reject(_t('AccessError')); + // } + var self = this; + var done = this.message('cashlogy/display_backoffice'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + framework.blockUI(); + done.always(function () { + framework.unblockUI(); + }); + return done; + }, + + }); + + return devices; +}); diff --git a/pos_automatic_cashdrawer/static/src/js/models.js b/pos_automatic_cashdrawer/static/src/js/models.js new file mode 100755 index 0000000000..f2f78d5941 --- /dev/null +++ b/pos_automatic_cashdrawer/static/src/js/models.js @@ -0,0 +1,141 @@ +/* + POS Automatic Cashdrawer module for Odoo + Copyright (C) 2016 Aurélien DUMAINE + Copyright (C) 2019-Today: Druidoo () + @author: Aurélien DUMAINE + The licence is in the file __manifest__.py +*/ + +odoo.define('pos_automatic_cashdrawer.models', function (require) { + "use strict"; + + var models = require('point_of_sale.models'); + var rpc = require('web.rpc'); + var core = require('web.core'); + var _t = core._t; + + models.load_fields("account.journal", [ + 'payment_mode', + 'iface_automatic_cashdrawer', + ]); + + models.load_fields("pos.config", [ + 'iface_automatic_cashdrawer', + 'iface_automatic_cashdrawer_ip_address', + 'iface_automatic_cashdrawer_tcp_port', + 'group_pos_automatic_cashlogy_config', + ]); + + // var Session = new Model('pos.session'); + + /* + PosModel + */ + var _superPosModel = models.PosModel.prototype; + models.PosModel = models.PosModel.extend({ + // Overload 'set_cashier' function to display correctly + // unauthorized function after cashier changed + set_cashier: function (user) { + this.gui.display_access_right_cashlogy(user); + return _superPosModel.set_cashier.apply(this, arguments); + }, + + // If the user is just checking automatic cashdrawer, then the system will try to connect proxy. + after_load_server_data: function (session, attributes) { + if (this.config.iface_automatic_cashdrawer) { + this.config.use_proxy = true; + } + return _superPosModel.after_load_server_data.apply(this, arguments); + }, + + // Checks if the opening balance is missing, fails silently + check_opening_balance_missing: function () { + var done = new $.Deferred(); + var self = this; + rpc.query({ + model: 'pos.session', + method: 'check_opening_balance_missing', + args: [[this.pos_session.id]] + }) + .then(function (res) { + done.resolve(res); + }) + .fail(function (error) { + self.gui.show_popup('error-traceback', { + 'title': _t('Set balance error: ') + error.data.message, + 'body': error.data.debug, + }); + }); + return done; + }, + + // Sets the balance + action_set_balance: function (inventory, balance) { + var self = this; + var done = rpc.query({ + model: 'pos.session', + method: 'action_set_balance', + args: [[this.pos_session.id], { + inventory: inventory, + balance: balance + }] + }); + done.fail(function (error) { + self.gui.show_popup('error-traceback', { + 'title': _t('Set balance error: ') + error.data.message, + 'body': error.data.debug + }); + }); + return done; + }, + + // Checks if the session is able to do cash operations + check_cash_in_out_possible: function () { + return rpc.query({ + model: 'pos.session', + method: 'check_cash_in_out_possible', + args: [[this.pos_session.id]] + }); + }, + + // Saves cash in + action_put_money_in: function (amount, reason) { + if (!amount) { + return $.Deferred().resolve(); + } + return rpc.query({ + model: 'pos.session', + method: 'action_put_money_in', + args: [[this.pos_session.id], { + 'amount': amount, + 'reason': reason, + }] + }); + }, + + action_take_money_out: function (amount, reason) { + if (!amount) { + return $.Deferred().resolve(); + } + return rpc.query({ + model: 'pos.session', + method: 'action_take_money_out', + args: [[this.pos_session.id], { + 'amount': amount, + 'reason': reason, + }] + }); + }, + }); + + /* + Paymentline + */ + models.Paymentline = models.Paymentline.extend({ + get_automatic_cashdrawer: function () { + return this.cashregister.journal.iface_automatic_cashdrawer; + }, + }); + + return models; +}); diff --git a/pos_automatic_cashdrawer/static/src/js/screens.js b/pos_automatic_cashdrawer/static/src/js/screens.js new file mode 100755 index 0000000000..1210ac1c14 --- /dev/null +++ b/pos_automatic_cashdrawer/static/src/js/screens.js @@ -0,0 +1,85 @@ +/* + POS Automatic Cashdrawer module for Odoo + Copyright (C) 2016 Aurélien DUMAINE + Copyright (C) 2019-Today: Druidoo () + @author: Aurélien DUMAINE + The licence is in the file __manifest__.py +*/ + +odoo.define('pos_automatic_cashdrawer.screens', function (require) { + "use strict"; + + var screens = require('point_of_sale.screens'); + var gui = require('point_of_sale.gui'); + var models = require('point_of_sale.models'); + + var core = require('web.core'); + + var _t = core._t; + + + models.load_fields("res.users", [ + 'groups_id', + ]); + /* + Show or hide the cashdrawer backend feature + TODO: Move this to pos_automatic_cashdrawer_cashlogy + */ + gui.Gui.include({ + display_access_right_cashlogy: function (user) { + if (user.groups_id.indexOf(this.pos.config.group_pos_automatic_cashlogy_config[0]) !== -1) { + $('.js_auto_cashdrawer_config').removeClass('oe_hidden'); + } else { + $('.js_auto_cashdrawer_config').addClass('oe_hidden'); + } + } + }); + /* + Overload 'start' function to display correctly unauthorized function + at the beginning of the session, based on current user + + TODO: Analyze why we need this here, on the numpad.. + Isn't it already handled by the set_cashier function? + */ + screens.NumpadWidget.include({ + start: function () { + this._super(); + this.gui.display_access_right_cashlogy(this.pos.get_cashier()); + }, + }); + + + screens.PaymentScreenWidget.include({ + // When the payment journal is clicked, we start the automatic_cashdrawer_transaction + click_paymentmethods: function (id) { + this._super.apply(this, arguments); + var self = this; + var order = this.pos.get_order(); + var line = order.selected_paymentline; + if (line && line.get_automatic_cashdrawer()) { + var amount = order.get_due(line); + // TODO Block input + this.gui.show_popup('cashdrawer_cash_in', { + title: _t('Customer Transaction'), + to_collect: amount, + auto_accept: true, + allow_cancel: true, + confirm: function (amount, amountIn, amountOut) { + var amountFormatted = self.format_currency_no_symbol(amountIn); + line.set_amount(amountIn); + self.order_changes(); + self.render_paymentlines(); + self.$('.paymentline.selected .edit').text(amountFormatted); + self.$('.delete-button').css('display', 'none'); + }, + cancel: function () { + // Remove payment line + self.click_delete_paymentline(line.cid); + } + }); + } + }, + }); + + return screens; +}); diff --git a/pos_automatic_cashdrawer/static/src/js/widgets.js b/pos_automatic_cashdrawer/static/src/js/widgets.js new file mode 100755 index 0000000000..f262949864 --- /dev/null +++ b/pos_automatic_cashdrawer/static/src/js/widgets.js @@ -0,0 +1,532 @@ +/* + POS Automatic Cashdrawer module for Odoo + Copyright (C) 2016 Aurélien DUMAINE + Copyright (C) 2019-Today: Druidoo () + @author: Aurélien DUMAINE + The licence is in the file __manifest__.py +*/ + +odoo.define('pos_automatic_cashdrawer.widgets', function (require) { + "use strict"; + + var PopupWidget = require('point_of_sale.popups'); + var chrome = require('point_of_sale.chrome'); + var gui = require('point_of_sale.gui'); + var core = require('web.core'); + var framework = require('web.framework'); + var field_utils = require('web.field_utils'); + var utils = require('web.utils'); + + var _t = core._t; + var QWeb = core.qweb; + + /* + Attach status widgets + */ + chrome.Chrome.include({ + init: function () { + this._super.apply(this, arguments); + this.automatic_cashdrawer_add_widgets(); + }, + automatic_cashdrawer_add_widgets: function () { + var native_widgets = this.widgets; + var autocashdrawerconfigwidget = { + 'name': 'auto_cashdrawer_config', + 'widget': AutomaticCashdrawerConfigWidget, + 'append': '.pos-rightheader', + 'condition': function () { + return this.pos.config.iface_automatic_cashdrawer; + }, + }; + var sorted_widgets = []; + for (var i = 0, len = native_widgets.length; i < len; i++) { + sorted_widgets.push(native_widgets[i]); + if (native_widgets[i].name === 'order_selector') { + sorted_widgets.push(autocashdrawerconfigwidget); + } + } + this.widgets = sorted_widgets; + } + }); + + + /* + Add Cashdrawer connection to the ProxyStatus widget + It'll also monitor cashdrawer cashbox initial balance status + */ + chrome.ProxyStatusWidget.include({ + set_smart_status: function (status) { + this._super.apply(this, arguments); + if (status.status === 'connected') { + // Get the current status based on the css classes of the widget + // Sadly, there's not a property to check this. + var current_status; + for (var i=0; i < this.status.length; i++) { + var _el = this.$('.js_' + this.status[i]); + if (_el.length && !_el.hasClass('oe_hidden')) { + current_status = this.status[i]; + } + } + var warning = (current_status === 'warning'); + var msg = this.$('.js_msg').html(); + if (this.pos.config.iface_automatic_cashdrawer) { + var automatic_cashdrawer = status.drivers.automatic_cashdrawer ? status.drivers.automatic_cashdrawer.status : false; + if (automatic_cashdrawer == 'connecting') { + warning = true; + msg = msg ? msg + ' & ' : msg; + msg += _t('Automatic Cashdrawer Connecting..'); + } else if (automatic_cashdrawer != 'connected') { + warning = true; + msg = msg ? msg + ' & ' : msg; + msg += _t('Automatic Cashdrawer Offline'); + } + } + this.set_status(warning ? 'warning' : current_status, msg); + } + }, + }); + + /* + Cashdrawer configuration widget + */ + var AutomaticCashdrawerConfigWidget = chrome.StatusWidget.extend({ + template: 'AutomaticCashdrawerConfigWidget', + start: function () { + var self = this; + this.$el.click(function () { + //self.pos.proxy.automatic_cashdrawer_connection_display_backoffice(); + self.gui.show_popup('cashdrawer_admin'); + }); + }, + }); + + var AutomaticCashdrawerAdminDialog = PopupWidget.extend({ + template: 'AutomaticCashdrawerAdminDialog', + + show: function (options) { + var self = this; + this._super.apply(this, arguments); + this.$('.actions .button').on('click', function (el) { + self.gui.close_popup(); + var action = this.dataset['action']; + if (action) { + self.action_handler(action); + } + }); + }, + + action_handler: function (action) { + if (this['action_' + action]) { + this['action_' + action].apply(this); + } else { + console.error('Unrecognized action', action); + } + }, + + action_print_inventory: function () { + this.gui.show_popup('cashdrawer_inventory'); + }, + + action_display_backoffice: function () { + this.pos.proxy.automatic_cashdrawer_display_backoffice(); + }, + + action_put_money_in: function () { + var self = this; + this.pos.check_cash_in_out_possible() + .fail(function (error) { + console.error(error); + self.gui.close_popup(); + self.gui.show_popup('error', { + title: _t('Cash In/Out not possible'), + body: error.data.message, + }); + }).then(function () { + self.gui.show_popup('cashdrawer_cash_in', { + allow_cancel: true, + title: _t('Add cash'), + confirm: function (value) { + self.pos.action_put_money_in(value, _t('Manual: put money in')).then(function (st_line) { + self.pos.proxy.print_receipt(QWeb.render('AutomaticCashdrawerActionXmlReport', { + pos: self.pos, + report: { + name: _t('Added Cash'), + lines: [ + _t('Total added: ') + self.format_currency(value), + ], + st_line: st_line, + } + })); + }); + } + }); + }); + }, + + action_take_money_out: function () { + var self = this; + this.pos.check_cash_in_out_possible() + .fail(function (error) { + console.error(error); + self.gui.close_popup(); + self.gui.show_popup('error', { + title: _t('Cash In/Out not possible'), + body: error.data.message, + }); + }).then(function () { + self.gui.show_popup('number', { + title: 'Cash Withdrawal', + body: 'How much do you want to withdraw?', + confirm: function (value) { + value = field_utils.parse['float'](value); + if (value == 0) { return; } + framework.blockUI(); + self.pos.proxy.automatic_cashdrawer_dispense(value) + .then(function (res) { + var print_lines = []; + // handling + if (res != value) { + // Print it on the ticket aswell + print_lines.push(_t('The requested amount to dispense was: ') + value + _t(' but the dispensed amount was: ') + res); + // Show error popup + self.gui.show_popup('error', { + title: _t('Could not dispense the value requested'), + body: ( + _t('The requested amount to dispense was: ') + value + + '
' + + _t('The dispensed amount was: ') + res + ) + }); + } + // register accounting + self.pos.action_take_money_out(res, _t('Manual: take money out')).then(function (st_line) { + print_lines.push(_t('Dispensed: ') + self.format_currency(res)); + self.pos.proxy.print_receipt(QWeb.render('AutomaticCashdrawerActionXmlReport', { + pos: self.pos, + report: { + name: _t('Cash Withdrawal'), + lines: print_lines, + st_line: st_line, + } + })); + }); + }).always(function () { + framework.unblockUI(); + }); + }, + }); + }); + }, + + action_cancel: function () { + var self = this; + this.pos.proxy.automatic_cashdrawer_stop_acceptance() + .then(function (res) { + self.pos.proxy.print_receipt(QWeb.render('AutomaticCashdrawerActionXmlReport', { + pos: self.pos, + report: { + name: _t('Manual Cancel'), + lines: [ + _t('Money in/out: ') + self.format_currency(res), + _t('IMPORTANT: This operations is not registered on the cash statement. You have to manually register it.') + ], + } + })); + }); + }, + + action_close_till: function () { + var self = this; + this.pos.check_cash_in_out_possible().fail(function (error) { + console.error(error); + self.gui.close_popup(); + self.gui.show_popup('error', { + title: _t('Cash In/Out not possible'), + body: error.data.message, + }); + }).then(function () { + self.pos.proxy.automatic_cashdrawer_display_close_till().then(function (res) { + if (res['added']) { + self.pos.action_put_money_in(res['added'], _t('Automatic Cashdrawer: Close Till / ADDED')).then(function (st_line) { + self.pos.proxy.print_receipt(QWeb.render('AutomaticCashdrawerActionXmlReport', { + pos: self.pos, + report: { + name: _t('Close Till: Put In'), + lines: [ + _t('Total added: ') + self.format_currency(res['added']), + ], + st_line: st_line, + } + })); + }); + } + if (res['dispensed']) { + self.pos.action_take_money_out(res['dispensed'], _t('Automatic Cashdrawer: Close Till / DISPENSED')).then(function (st_line) { + self.pos.proxy.print_receipt(QWeb.render('AutomaticCashdrawerActionXmlReport', { + pos: self.pos, + report: { + name: _t('Close Till Result'), + lines: [ + _t('Total dispensed: ') + self.format_currency(res['dispensed']), + ], + st_line: st_line, + } + })); + }); + } + }); + }); + }, + + action_empty_stacker: function () { + var self = this; + this.pos.check_cash_in_out_possible().fail(function (error) { + console.error(error); + self.gui.close_popup(); + self.gui.show_popup('error', { + title: _t('Cash In/Out not possible'), + body: error.data.message, + }); + }).then(function () { + self.pos.proxy.automatic_cashdrawer_display_empty_stacker().then(function (res) { + if (res) { + self.pos.action_take_money_out(res, _t('Automatic Cashdrawer: Empty Stacker')).then(function (st_line) { + self.pos.proxy.print_receipt(QWeb.render('AutomaticCashdrawerActionXmlReport', { + pos: self.pos, + report: { + name: _t('Empty Stacker'), + lines: [ + _t('Total dispensed: ') + self.format_currency(res), + ], + st_line: st_line, + } + })); + }); + } + }); + }); + }, + + action_complete_emptying: function () { + var self = this; + this.pos.check_cash_in_out_possible().fail(function (error) { + console.error(error); + self.gui.close_popup(); + self.gui.show_popup('error', { + title: _t('Cash In/Out not possible'), + body: error.data.message, + }); + }).then(function () { + self.pos.proxy.automatic_cashdrawer_display_complete_emptying().then(function (res) { + if (res) { + self.pos.action_take_money_out(res, _t('Automatic Cashdrawer: Complete Emptying')).then(function (st_line) { + self.pos.proxy.print_receipt(QWeb.render('AutomaticCashdrawerActionXmlReport', { + pos: self.pos, + report: { + name: _t('Complete Emptying'), + lines: [ + _t('Total dispensed: ') + self.format_currency(res), + ], + st_line: st_line, + } + })); + }); + } + }); + }); + }, + + action_sync_opening_balance: function () { + var self = this; + this.pos.check_opening_balance_missing().then(function (res) { + if (res === true) { + self.pos.proxy.automatic_cashdrawer_get_inventory().then(function (res) { + self.pos.action_set_balance(res.total, 'start') + .then(function (res) { + self.gui.show_popup('alert', { + title: _t('Opening Balance Set'), + body: _t('Success'), + }); + }); + }); + } else { + self.gui.show_popup('error', { + title: _t('Unable to set balance on opened sessions'), + body: _t('It looks the session is already opened'), + }); + } + }); + }, + + action_sync_closing_balance: function () { + var self = this; + this.pos.proxy.automatic_cashdrawer_get_inventory().then(function (res) { + self.pos.action_set_balance(res.total, 'end').then(function (res) { + self.gui.show_popup('alert', { + title: _t('Closing Balance Set'), + body: _t('Success'), + }); + }); + }); + }, + + }); + + + var AutomaticCashDrawerCashInDialog = PopupWidget.extend({ + template: 'AutomaticCashdrawerCashInDialog', + + show: function (options) { + var self = this; + this._super.apply(this, arguments); + this.closed = false; + this.inputbuffer = 0.00; + framework.blockUI(); + this.pos.proxy.automatic_cashdrawer_start_add_change().then(function (res) { + self.update_counter(); + }).fail(function (err) { + self.close(); + }).always(function () { + framework.unblockUI(); + }); + }, + + close: function (options) { + if (this.timer) { clearTimeout(this.timer); } + this.closed = true; + this._super.apply(this, arguments); + }, + + update_counter: function () { + var self = this; + this.pos.proxy.automatic_cashdrawer_get_amount_accepted().then(function (res) { + // Because we might get here after the popup was closed + if (self.closed) { return false; } + self.inputbuffer = res; + self.$('.value').text(self.format_currency(self.inputbuffer)); + // Auto accept dialog if amount is enough + if (self.options.to_collect && self.options.auto_accept && self.inputbuffer >= self.options.to_collect) { + return self.click_confirm(); + } + self.timer = setTimeout(function () { self.update_counter(); }, 100); + }); + }, + + click_confirm: function () { + var self = this; + this.pos.proxy.automatic_cashdrawer_stop_acceptance().then(function (value) { + if (self.options.to_collect && value > self.options.to_collect) { + var change = utils.round_precision(value - self.options.to_collect, self.pos.currency.rounding); + self.pos.proxy.automatic_cashdrawer_dispense(change).then(function (res) { + if (self.options.confirm) { + self.options.confirm.call(self, value - change, value, change); + } + }); + } else { + if (self.options.confirm) { + self.options.confirm.call(self, value); + } + } + self.gui.close_popup(); + }); + }, + + /* + TODO: shuold return the money inserted (maybe) + So, basically, we confirm the operation to the machine, and then we dispense + the inserted amount. + */ + click_cancel: function () { + var self = this; + if (this.options.allow_cancel) { + self.pos.proxy.automatic_cashdrawer_stop_acceptance().then(function (value) { + self.pos.proxy.automatic_cashdrawer_dispense(value).then(function () { + if (self.options.cancel) { + self.options.cancel.call(self); + } + self.gui.close_popup(); + }); + }); + } else { + this.gui.show_popup('error', { + message: _t('Cancel not enabled') + }); + this.gui.close_popup(); + } + }, + }); + + + gui.define_popup({name: 'cashdrawer_admin', widget: AutomaticCashdrawerAdminDialog}); + gui.define_popup({name: 'cashdrawer_cash_in', widget: AutomaticCashDrawerCashInDialog}); + + + var AutomaticCashdrawerInventoryDialog = PopupWidget.extend({ + template: 'AutomaticCashdrawerInventoryDialog', + + init: function (options) { + this._super.apply(this, arguments); + this.inventory_total = 0.00; + this.inventory = { + total: {}, + stacker: {}, + recycler: {} + }; + this.sorted_values = []; + }, + + show: function (options) { + this._super.apply(this, arguments); + var self = this; + // Get information from driver and delays showing + framework.blockUI(); + $.when(this.pos.proxy.automatic_cashdrawer_get_total_amount(), + this.pos.proxy.automatic_cashdrawer_get_inventory() + ).then(function (totals, inventory) { + self.inventory_total = totals.total; + self.totals = totals; + self.inventory = inventory; + self.sorted_values = Object.keys(self.inventory.total).sort(function (a, b) { + return Number(b) - Number(a); + }); + self.renderElement(); + }).fail(function () { + self.close(); + }).always(function () { + framework.unblockUI(); + }); + }, + + to_num: function (v) { + return Number(v); + }, + + click_confirm: function () { + this.pos.proxy.print_receipt(QWeb.render('AutomaticCashdrawerInventoryXmlReport', { + widget: this, + pos: this.pos, + report: { + totals: this.totals, + inventory: this.inventory, + sorted_values: this.sorted_values, + date: false, // todo + } + })); + return this._super.apply(this, arguments); + }, + + click_cancel: function () { + return this._super.apply(this, arguments); + }, + }); + + gui.define_popup({name: 'cashdrawer_inventory', widget: AutomaticCashdrawerInventoryDialog}); + + return { + AutomaticCashdrawerConfigWidget: AutomaticCashdrawerConfigWidget, + AutomaticCashdrawerAdminDialog: AutomaticCashdrawerAdminDialog, + AutomaticCashDrawerCashInDialog: AutomaticCashDrawerCashInDialog, + AutomaticCashdrawerInventoryDialog: AutomaticCashdrawerInventoryDialog, + }; + +}); diff --git a/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml b/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml new file mode 100644 index 0000000000..efd5d7294c --- /dev/null +++ b/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml @@ -0,0 +1,234 @@ + + + + +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + +

Automatic Cashdrawer

+

Inventory

+ + + + +
+
+ +

+
+
+
+ +
+
+
--------------------------------
+
User:
+
+
+

+ + + + TOTALS + -------------------------------- +
+ + + + + x ( + + + + ) = + + + +
+ + + + -------- + + Recycler + + + + Stacker + + + + + + -------- + +
        TOTAL
+ +
+

+ +
+
+
+
+
+ +
+ +
+ + + + + +

Automatic Cashdrawer

+

+ + + + + +
+
+ +

+
+
+
+ +
+
+
--------------------------------
+
User:
+
+
+
+

+ + + + + +

+
+ + +
+
+
--------------------------------
+
Statement:
+
REF: ()
+
+ +
+ +
+ +
diff --git a/pos_automatic_cashdrawer/views/account_journal.xml b/pos_automatic_cashdrawer/views/account_journal.xml new file mode 100644 index 0000000000..41447df2f9 --- /dev/null +++ b/pos_automatic_cashdrawer/views/account_journal.xml @@ -0,0 +1,14 @@ + + + + account.journal.automatic.cashdrawer.form + account.journal + + 20 + + + + + + + diff --git a/pos_automatic_cashdrawer/views/assets.xml b/pos_automatic_cashdrawer/views/assets.xml new file mode 100644 index 0000000000..f5e6fdf3e5 --- /dev/null +++ b/pos_automatic_cashdrawer/views/assets.xml @@ -0,0 +1,13 @@ + + + + diff --git a/pos_automatic_cashdrawer/views/pos_config.xml b/pos_automatic_cashdrawer/views/pos_config.xml new file mode 100644 index 0000000000..58f5dba61a --- /dev/null +++ b/pos_automatic_cashdrawer/views/pos_config.xml @@ -0,0 +1,26 @@ + + + + pos.automatic.cashdrawer.config.form + pos.config + + + +
+
+ +
+
+
+
+
+
+
+
From befe39a4fb057495acfbbbf8e15a2e2d8be6dc4f Mon Sep 17 00:00:00 2001 From: druidoo-transbot Date: Wed, 15 Apr 2020 10:25:49 +0000 Subject: [PATCH 02/10] [UPD] Update pos_automatic_cashdrawer.pot --- .../i18n/pos_automatic_cashdrawer.pot | 621 +++++++++++++++++- 1 file changed, 594 insertions(+), 27 deletions(-) diff --git a/pos_automatic_cashdrawer/i18n/pos_automatic_cashdrawer.pot b/pos_automatic_cashdrawer/i18n/pos_automatic_cashdrawer.pot index c6346251ee..52606f531b 100644 --- a/pos_automatic_cashdrawer/i18n/pos_automatic_cashdrawer.pot +++ b/pos_automatic_cashdrawer/i18n/pos_automatic_cashdrawer.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0c\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: <>\n" "Language-Team: \n" @@ -14,83 +14,650 @@ msgstr "" "Plural-Forms: \n" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:190 +#, python-format +msgid " but the dispensed amount was: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:147 +#, python-format +msgid "Add cash" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:153 +#, python-format +msgid "Added Cash" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config__iface_automatic_cashdrawer msgid "An automatic cashdrawer is available on the Proxy" msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_account_journal_iface_automatic_cashdrawer -#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:116 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:191 +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config__iface_automatic_cashdrawer +#: model_terms:ir.ui.view,arch_db:pos_automatic_cashdrawer.pos_res_config_settings_view_form +#, python-format +msgid "Automatic Cashdrawer" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:77 +#, python-format +msgid "Automatic Cashdrawer Connecting.." +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config__iface_automatic_cashdrawer_ip_address +#: model_terms:ir.ui.view,arch_db:pos_automatic_cashdrawer.pos_res_config_settings_view_form +msgid "Automatic Cashdrawer IP address" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:81 +#, python-format +msgid "Automatic Cashdrawer Offline" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config__iface_automatic_cashdrawer_tcp_port +#: model_terms:ir.ui.view,arch_db:pos_automatic_cashdrawer.pos_res_config_settings_view_form +msgid "Automatic Cashdrawer TCP port" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:250 +#, python-format +msgid "Automatic Cashdrawer: Close Till / ADDED" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:264 +#, python-format +msgid "Automatic Cashdrawer: Close Till / DISPENSED" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:322 +#, python-format +msgid "Automatic Cashdrawer: Complete Emptying" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:293 +#, python-format +msgid "Automatic Cashdrawer: Empty Stacker" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_account_journal__iface_automatic_cashdrawer msgid "Automatic cashdrawer" msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_ip_address -msgid "Automatic cashdrawer IP address" +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:35 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:64 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:452 +#, python-format +msgid "Cancel not enabled" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:141 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:173 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:244 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:287 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:316 +#, python-format +msgid "Cash In/Out not possible" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:207 +#, python-format +msgid "Cash Withdrawal" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:15 +#, python-format +msgid "Cashdrawer Admin" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:63 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:86 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:108 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:130 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:163 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:183 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:214 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:232 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:250 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:285 +#, python-format +msgid "Cashdrawer Error: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:51 +#, python-format +msgid "Cashdrawer Inventory: " msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_tcp_port -msgid "Automatic cashdrawer TCP port" +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:60 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:83 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:105 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:127 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:160 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:180 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:211 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:229 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:247 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:282 +#, python-format +msgid "Cashdrawer not connected" msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_display_accept_button -msgid "Automatic cashdrawer display accept button" +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:6 +#, python-format +msgid "Cashlogy Backoffice" msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_iface_automatic_cashdrawer_screen_on_top -msgid "Automatic cashdrawer screen on top" +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:80 +#, python-format +msgid "Check that the Cashdrawer is online before starting the session, and refresh the browser.\n" +"\n" +"" msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_account_journal_iface_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_account_journal__iface_automatic_cashdrawer msgid "Check this if this journal is linked to an automatic cashdrawer" msgstr "" +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:104 +#, python-format +msgid "Close" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:22 +#, python-format +msgid "Close Till / Cash Float" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:268 +#, python-format +msgid "Close Till Result" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:254 +#, python-format +msgid "Close Till: Put In" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:366 +#, python-format +msgid "Closing Balance Set" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:326 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:24 +#, python-format +msgid "Complete Emptying" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:63 +#, python-format +msgid "Confirm" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:193 +#, python-format +msgid "Could not dispense the value requested" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/screens.js:63 +#, python-format +msgid "Customer Transaction" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:203 +#, python-format +msgid "Dispensed: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:50 +#, python-format +msgid "Do you want to overwrite it with the real amount?" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:297 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:23 +#, python-format +msgid "Empty Stacker" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:231 +#, python-format +msgid "IMPORTANT: This operations is not registered on the cash statement. You have to manually register it." +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:117 +#, python-format +msgid "Inventory" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:355 +#, python-format +msgid "It looks the session is already opened" +msgstr "" + #. module: pos_automatic_cashdrawer #: model:ir.model,name:pos_automatic_cashdrawer.model_account_journal msgid "Journal" msgstr "" #. module: pos_automatic_cashdrawer -#: model:res.groups,name:pos_automatic_cashdrawer.group_pos_automatic_cashlogy_config -msgid "PoS - Allow Cashlogy config" +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:61 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:84 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:106 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:128 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:161 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:181 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:212 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:230 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:248 +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:283 +#, python-format +msgid "Make sure Cashdrawer connected with IOT Box" msgstr "" #. module: pos_automatic_cashdrawer -#: model:res.groups,name:pos_automatic_cashdrawer.group_pos_automatic_cashlogy -msgid "PoS - Allow Cashlogy connection" +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:228 +#, python-format +msgid "Manual Cancel" msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy_config -msgid "Point of Sale - Allow Cashlogy Config" +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:149 +#, python-format +msgid "Manual: put money in" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:202 +#, python-format +msgid "Manual: take money out" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:263 +#, python-format +msgid "Method not implemented yet" msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy -msgid "Point of Sale - Allow Cashlogy connection" +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:230 +#, python-format +msgid "Money in/out: " msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy_config -msgid "This field is there to pass the id of the 'PoS - Allow Cashlogy config' Group to the Point of Sale Frontend." +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/devices.js:262 +#, python-format +msgid "Not implemented" msgstr "" #. module: pos_automatic_cashdrawer -#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config_group_pos_automatic_cashlogy -msgid "This field is there to pass the id of the 'PoS - Allow Cashlogy connection' Group to the Point of Sale Frontend." +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:31 +#, python-format +msgid "Open Backoffice" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:347 +#, python-format +msgid "Opening Balance Set" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:67 +#, python-format +msgid "Please ask your manager to fix it." +msgstr "" + +#. module: pos_automatic_cashdrawer +#: code:addons/pos_automatic_cashdrawer/models/pos_session.py:72 +#, python-format +msgid "Please check that the field 'Journal' is set on the Bank Statement" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: code:addons/pos_automatic_cashdrawer/models/pos_session.py:79 +#, python-format +msgid "Please check that the field 'Transfer Account' is set on the company." +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:res.groups,name:pos_automatic_cashdrawer.group_pos_automatic_cashlogy_config +msgid "PoS - Allow Cashlogy config" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,field_description:pos_automatic_cashdrawer.field_pos_config__group_pos_automatic_cashlogy_config +msgid "Point of Sale - Allow Cashlogy Config" msgstr "" #. module: pos_automatic_cashdrawer #: model:ir.model,name:pos_automatic_cashdrawer.model_pos_config -msgid "pos.config" +msgid "Point of Sale Configuration" msgstr "" #. module: pos_automatic_cashdrawer #: model:ir.model,name:pos_automatic_cashdrawer.model_pos_session -msgid "pos.session" +msgid "Point of Sale Session" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:105 +#, python-format +msgid "Print" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:21 +#, python-format +msgid "Print Inventory" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:18 +#, python-format +msgid "Put Money In" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:227 +#, python-format +msgid "REF:" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:85 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:160 +#, python-format +msgid "Recycler" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:32 +#, python-format +msgid "Send Cancel Command" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:52 +#, python-format +msgid "Session Starting Balance: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/models.js:65 +#: code:addons/pos_automatic_cashdrawer/static/src/js/models.js:85 +#, python-format +msgid "Set balance error: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:86 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:164 +#, python-format +msgid "Stacker" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:53 +#, python-format +msgid "Start adding cash into the machine." +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:226 +#, python-format +msgid "Statement:" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:348 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:367 +#, python-format +msgid "Success" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:108 +#, python-format +msgid "Synchronizing automatic cashdrawer inventory" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:172 +#, python-format +msgid "TOTAL" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:140 +#, python-format +msgid "TOTALS" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:19 +#, python-format +msgid "Take Money Out" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:197 +#, python-format +msgid "The dispensed amount was: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:47 +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:64 +#, python-format +msgid "The opening balance does not match" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:49 +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:66 +#, python-format +msgid "The opening balance for this session does not match with the Cashdrawer Inventory." +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config__iface_automatic_cashdrawer_tcp_port +msgid "The port to connect to the Cashdrawer.\n" +"WARNING: set a port bigger than 1024 to allow a non-root user to listen on it." +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:190 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:195 +#, python-format +msgid "The requested amount to dispense was: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#: code:addons/pos_automatic_cashdrawer/models/pos_session.py:69 +#, python-format +msgid "There's no cash register on this session" +msgstr "" + +#. module: pos_automatic_cashdrawer +#: model:ir.model.fields,help:pos_automatic_cashdrawer.field_pos_config__group_pos_automatic_cashlogy_config +msgid "This field is there to pass the id of the \"PoS - Allow Cashlogy config\" group to the POS." +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:48 +#, python-format +msgid "To collect:" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:87 +#, python-format +msgid "Total" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:155 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:256 +#, python-format +msgid "Total added: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:270 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:299 +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:328 +#, python-format +msgid "Total dispensed: " +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/widgets.js:354 +#, python-format +msgid "Unable to set balance on opened sessions" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/js/chrome.js:79 +#, python-format +msgid "Unable to syncronize inventory" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:133 +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:209 +#, python-format +msgid "User:" +msgstr "" + +#. module: pos_automatic_cashdrawer +#. openerp-web +#: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:54 +#, python-format +msgid "When you finish, press confirm." +msgstr "" + +#. module: pos_automatic_cashdrawer +#: code:addons/pos_automatic_cashdrawer/models/pos_session.py:86 +#, python-format +msgid "You cannot put/take money in/out for a bank statement which is closed." msgstr "" From fab5a4f402e0a8f3dfa447cc0f9774cdd203666f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A0n=20Todorovich?= Date: Tue, 23 Jun 2020 13:49:49 +0200 Subject: [PATCH 03/10] [IMP] New readme format --- pos_automatic_cashdrawer/README.rst | 37 ------------------- pos_automatic_cashdrawer/readme/CONFIGURE.rst | 2 + .../readme/CONTRIBUTORS.rst | 4 ++ .../readme/DESCRIPTION.rst | 1 + pos_automatic_cashdrawer/readme/INSTALL.rst | 5 +++ pos_automatic_cashdrawer/readme/USAGE.rst | 2 + 6 files changed, 14 insertions(+), 37 deletions(-) delete mode 100644 pos_automatic_cashdrawer/README.rst create mode 100644 pos_automatic_cashdrawer/readme/CONFIGURE.rst create mode 100644 pos_automatic_cashdrawer/readme/CONTRIBUTORS.rst create mode 100644 pos_automatic_cashdrawer/readme/DESCRIPTION.rst create mode 100644 pos_automatic_cashdrawer/readme/INSTALL.rst create mode 100644 pos_automatic_cashdrawer/readme/USAGE.rst diff --git a/pos_automatic_cashdrawer/README.rst b/pos_automatic_cashdrawer/README.rst deleted file mode 100644 index dda821e86c..0000000000 --- a/pos_automatic_cashdrawer/README.rst +++ /dev/null @@ -1,37 +0,0 @@ -POS Payment Terminal -==================== - -This module adds support for automatic cashdrawers in the Point of Sale. - - -Installation -============ - -This module is designed to be installed on the -*main Odoo server*. On the *POSbox*, you should install the module -*hw_x* depending on the protocol implemented in your device. -`Cashlogy ` are implemented in the -*hw_cashlogy* module and also in pywebdriver . - -Configuration -============= - -The cashlogyConnector adddress and port should be configured on the main Odoo server, -in the menu *Pointof Sale > Configuration > Payment Methods*,under the *Point of Sale* tab. - -Usage -===== - -In the frontend of the POS, when you select a payment method CASH you will have a *Start Transaction* button : -if you click on that button, the amount will be sent to the POSbox. - -Credits -======= - -Contributors ------------- - -* Aurelien Dumaine -* Mathieu Vatel -* Druidoo - diff --git a/pos_automatic_cashdrawer/readme/CONFIGURE.rst b/pos_automatic_cashdrawer/readme/CONFIGURE.rst new file mode 100644 index 0000000000..de83d6aa88 --- /dev/null +++ b/pos_automatic_cashdrawer/readme/CONFIGURE.rst @@ -0,0 +1,2 @@ +The cashlogyConnector adddress and port should be configured on the main Odoo server, +in the menu *Pointof Sale > Configuration > Payment Methods*,under the *Point of Sale* tab. \ No newline at end of file diff --git a/pos_automatic_cashdrawer/readme/CONTRIBUTORS.rst b/pos_automatic_cashdrawer/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..c4ab824565 --- /dev/null +++ b/pos_automatic_cashdrawer/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* Aurelien Dumaine +* Mathieu Vatel +* Iván Todorovich +* Druidoo diff --git a/pos_automatic_cashdrawer/readme/DESCRIPTION.rst b/pos_automatic_cashdrawer/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..6588de21e0 --- /dev/null +++ b/pos_automatic_cashdrawer/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module adds support for automatic cashdrawers in the Point of Sale. diff --git a/pos_automatic_cashdrawer/readme/INSTALL.rst b/pos_automatic_cashdrawer/readme/INSTALL.rst new file mode 100644 index 0000000000..5bf2266dad --- /dev/null +++ b/pos_automatic_cashdrawer/readme/INSTALL.rst @@ -0,0 +1,5 @@ +This module is designed to be installed on the +*main Odoo server*. On the *POSbox*, you should install the module +*hw_x* depending on the protocol implemented in your device. +`Cashlogy ` are implemented in the +*hw_cashlogy* module and also in pywebdriver . diff --git a/pos_automatic_cashdrawer/readme/USAGE.rst b/pos_automatic_cashdrawer/readme/USAGE.rst new file mode 100644 index 0000000000..7dd6e30296 --- /dev/null +++ b/pos_automatic_cashdrawer/readme/USAGE.rst @@ -0,0 +1,2 @@ +In the frontend of the POS, when you select a payment method CASH you will have a *Start Transaction* button : +if you click on that button, the amount will be sent to the POSbox. From 4c590b56cc841341dee77aa9829e878810996c0a Mon Sep 17 00:00:00 2001 From: druidoo-transbot Date: Tue, 23 Jun 2020 11:52:40 +0000 Subject: [PATCH 04/10] [ADD] icon.png --- .../static/description/icon.png | Bin 0 -> 9673 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pos_automatic_cashdrawer/static/description/icon.png diff --git a/pos_automatic_cashdrawer/static/description/icon.png b/pos_automatic_cashdrawer/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fd60220fbe2d7465dd81af8ca6d5af032879c144 GIT binary patch literal 9673 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 Date: Tue, 23 Jun 2020 12:56:29 +0000 Subject: [PATCH 05/10] [UPD] README.rst --- pos_automatic_cashdrawer/README.rst | 82 ++++ .../static/description/index.html | 439 ++++++++++++++++++ 2 files changed, 521 insertions(+) create mode 100644 pos_automatic_cashdrawer/README.rst create mode 100644 pos_automatic_cashdrawer/static/description/index.html diff --git a/pos_automatic_cashdrawer/README.rst b/pos_automatic_cashdrawer/README.rst new file mode 100644 index 0000000000..c8cc64146b --- /dev/null +++ b/pos_automatic_cashdrawer/README.rst @@ -0,0 +1,82 @@ +======================== +POS Automatic Cashdrawer +======================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-druidoo%2FFoodCoops-lightgray.png?logo=github + :target: https://github.com/druidoo/FoodCoops/tree/12.0/pos_automatic_cashdrawer + :alt: druidoo/FoodCoops + +|badge1| |badge2| |badge3| + +This module adds support for automatic cashdrawers in the Point of Sale. + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +This module is designed to be installed on the +*main Odoo server*. On the *POSbox*, you should install the module +*hw_x* depending on the protocol implemented in your device. +`Cashlogy ` are implemented in the +*hw_cashlogy* module and also in pywebdriver . + +Configuration +============= + +The cashlogyConnector adddress and port should be configured on the main Odoo server, +in the menu *Pointof Sale > Configuration > Payment Methods*,under the *Point of Sale* tab. + +Usage +===== + +In the frontend of the POS, when you select a payment method CASH you will have a *Start Transaction* button : +if you click on that button, the amount will be sent to the POSbox. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Aurélien DUMAINE +* Druidoo + +Contributors +~~~~~~~~~~~~ + +* Aurelien Dumaine +* Mathieu Vatel +* Iván Todorovich +* Druidoo + +Maintainers +~~~~~~~~~~~ + +This module is part of the `druidoo/FoodCoops `_ project on GitHub. + +You are welcome to contribute. diff --git a/pos_automatic_cashdrawer/static/description/index.html b/pos_automatic_cashdrawer/static/description/index.html new file mode 100644 index 0000000000..c3350e8670 --- /dev/null +++ b/pos_automatic_cashdrawer/static/description/index.html @@ -0,0 +1,439 @@ + + + + + + +POS Automatic Cashdrawer + + + +
+

POS Automatic Cashdrawer

+ + +

Beta License: AGPL-3 druidoo/FoodCoops

+

This module adds support for automatic cashdrawers in the Point of Sale.

+

Table of contents

+ +
+

Installation

+

This module is designed to be installed on the +main Odoo server. On the POSbox, you should install the module +hw_x depending on the protocol implemented in your device. +Cashlogy <http://www.cashlogy.com> are implemented in the +hw_cashlogy module and also in pywebdriver <https://github.com/akretion/pywebdriver>.

+
+
+

Configuration

+

The cashlogyConnector adddress and port should be configured on the main Odoo server, +in the menu Pointof Sale > Configuration > Payment Methods,under the Point of Sale tab.

+
+
+

Usage

+

In the frontend of the POS, when you select a payment method CASH you will have a Start Transaction button : +if you click on that button, the amount will be sent to the POSbox.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Aurélien DUMAINE
  • +
  • Druidoo
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is part of the druidoo/FoodCoops project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + From 6f6b00946d1b423d6a771513111564606380c389 Mon Sep 17 00:00:00 2001 From: Simon Mas Date: Wed, 1 Jul 2020 08:57:43 +0000 Subject: [PATCH 06/10] Translated using Weblate (French) Currently translated at 100.0% (80 of 80 strings) Translation: foodcoops-12.0/foodcoops-12.0-pos_automatic_cashdrawer Translate-URL: https://translate.druidoo.io/projects/foodcoops-12-0/foodcoops-12-0-pos_automatic_cashdrawer/fr/ --- pos_automatic_cashdrawer/i18n/fr.po | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pos_automatic_cashdrawer/i18n/fr.po b/pos_automatic_cashdrawer/i18n/fr.po index b6d388fa10..72b02d88d0 100644 --- a/pos_automatic_cashdrawer/i18n/fr.po +++ b/pos_automatic_cashdrawer/i18n/fr.po @@ -7,13 +7,16 @@ msgstr "" "Project-Id-Version: Odoo Server 12.0c\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-04-09 09:17+0000\n" -"PO-Revision-Date: 2020-04-09 09:17+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" +"PO-Revision-Date: 2020-07-01 10:27+0000\n" +"Last-Translator: Simon Mas \n" +"Language-Team: French \n" +"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.8\n" #. module: pos_automatic_cashdrawer #. openerp-web @@ -119,7 +122,7 @@ msgstr "Monnayeur automatique" #: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:35 #, python-format msgid "Cancel" -msgstr "Cancel" +msgstr "Annuler" #. module: pos_automatic_cashdrawer #. openerp-web @@ -222,7 +225,7 @@ msgstr "Complete Emptying" #: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:57 #, python-format msgid "Confirm" -msgstr "Confirm" +msgstr "Confirmer" #. module: pos_automatic_cashdrawer #. openerp-web @@ -258,7 +261,7 @@ msgstr "IMPORTANT: Cette opération n'est pas enregistrées sur le journal d'esp #: code:addons/pos_automatic_cashdrawer/static/src/xml/pos_automatic_cashdrawer.xml:110 #, python-format msgid "Inventory" -msgstr "Inventory" +msgstr "Ligne d'inventaire" #. module: pos_automatic_cashdrawer #. openerp-web @@ -571,4 +574,3 @@ msgstr "pos.config" #: model:ir.model,name:pos_automatic_cashdrawer.model_pos_session msgid "pos.session" msgstr "pos.session" - From 4c363f8e4aae20b7ea4131f993ef197f10808199 Mon Sep 17 00:00:00 2001 From: Nguyen Minh Chien Date: Mon, 17 May 2021 04:23:22 +0000 Subject: [PATCH 07/10] [FIX] S#26123: lalouve: cashdrawer issues --- .../static/src/js/devices.js | 20 +++++++++ .../static/src/js/screens.js | 1 + .../static/src/js/widgets.js | 43 +++++++++++++------ 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/pos_automatic_cashdrawer/static/src/js/devices.js b/pos_automatic_cashdrawer/static/src/js/devices.js index 767f5d0eb3..4aae982619 100755 --- a/pos_automatic_cashdrawer/static/src/js/devices.js +++ b/pos_automatic_cashdrawer/static/src/js/devices.js @@ -187,6 +187,26 @@ odoo.define('pos_automatic_cashdrawer.devices', function (require) { return done; }, + /* + Start acceptance + Similar to Start add change, but used for sales + It has to be stopped using stop_acceptance + The amount loaded so far can be queried with get_amount_accepted + */ + automatic_cashdrawer_start_acceptance: function () { + var self = this; + var done = this.message('cashlogy/start_acceptance'); + done.fail(function (error) { + var message = error ? error.data.message : _t('Cashdrawer not connected'); + var body = error ? error.data.debug : _t('Make sure Cashdrawer connected with IOT Box'); + self.pos.gui.show_popup('error-traceback', { + 'title': _t('Cashdrawer Error: ') + message, + 'body': body + }); + }); + return done; + }, + /* Returns the money accepted so far @returns 0.00 diff --git a/pos_automatic_cashdrawer/static/src/js/screens.js b/pos_automatic_cashdrawer/static/src/js/screens.js index 1210ac1c14..248767f100 100755 --- a/pos_automatic_cashdrawer/static/src/js/screens.js +++ b/pos_automatic_cashdrawer/static/src/js/screens.js @@ -64,6 +64,7 @@ odoo.define('pos_automatic_cashdrawer.screens', function (require) { to_collect: amount, auto_accept: true, allow_cancel: true, + payment: true, confirm: function (amount, amountIn, amountOut) { var amountFormatted = self.format_currency_no_symbol(amountIn); line.set_amount(amountIn); diff --git a/pos_automatic_cashdrawer/static/src/js/widgets.js b/pos_automatic_cashdrawer/static/src/js/widgets.js index f262949864..d48b537fce 100755 --- a/pos_automatic_cashdrawer/static/src/js/widgets.js +++ b/pos_automatic_cashdrawer/static/src/js/widgets.js @@ -144,6 +144,7 @@ odoo.define('pos_automatic_cashdrawer.widgets', function (require) { }).then(function () { self.gui.show_popup('cashdrawer_cash_in', { allow_cancel: true, + payment: false, title: _t('Add cash'), confirm: function (value) { self.pos.action_put_money_in(value, _t('Manual: put money in')).then(function (st_line) { @@ -382,13 +383,23 @@ odoo.define('pos_automatic_cashdrawer.widgets', function (require) { this.closed = false; this.inputbuffer = 0.00; framework.blockUI(); - this.pos.proxy.automatic_cashdrawer_start_add_change().then(function (res) { - self.update_counter(); - }).fail(function (err) { - self.close(); - }).always(function () { - framework.unblockUI(); - }); + if (options.payment) { + this.pos.proxy.automatic_cashdrawer_start_acceptance().then(function (res) { + self.update_counter(); + }).fail(function (err) { + self.close(); + }).always(function () { + framework.unblockUI(); + }); + } else { + this.pos.proxy.automatic_cashdrawer_start_add_change().then(function (res) { + self.update_counter(); + }).fail(function (err) { + self.close(); + }).always(function () { + framework.unblockUI(); + }); + } }, close: function (options) { @@ -415,16 +426,22 @@ odoo.define('pos_automatic_cashdrawer.widgets', function (require) { click_confirm: function () { var self = this; this.pos.proxy.automatic_cashdrawer_stop_acceptance().then(function (value) { - if (self.options.to_collect && value > self.options.to_collect) { + if (self.options.to_collect && value >= self.options.to_collect) { var change = utils.round_precision(value - self.options.to_collect, self.pos.currency.rounding); - self.pos.proxy.automatic_cashdrawer_dispense(change).then(function (res) { + if (change > 0) { // more was collected, we dispense + self.pos.proxy.automatic_cashdrawer_dispense(change).then(function (res) { + if (self.options.confirm) { + self.options.confirm.call(self, value - change, value, change); + } + }); + } else { // exact amount was collected if (self.options.confirm) { - self.options.confirm.call(self, value - change, value, change); + self.options.confirm.call(self, value, value, 0); } - }); - } else { + } + } else { // not enough was collected if (self.options.confirm) { - self.options.confirm.call(self, value); + self.options.confirm.call(self, self.options.to_collect, value, 0); } } self.gui.close_popup(); From 70f8c92beab82b5f3e5cdc5cc6cffa02578df2b6 Mon Sep 17 00:00:00 2001 From: Nils Hamerlinck Date: Tue, 18 May 2021 16:51:32 +0700 Subject: [PATCH 08/10] [FIX] pos_automatic_cashdrawer: migration errors --- pos_automatic_cashdrawer/static/src/js/models.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/pos_automatic_cashdrawer/static/src/js/models.js b/pos_automatic_cashdrawer/static/src/js/models.js index f2f78d5941..9511cf2733 100755 --- a/pos_automatic_cashdrawer/static/src/js/models.js +++ b/pos_automatic_cashdrawer/static/src/js/models.js @@ -75,10 +75,7 @@ odoo.define('pos_automatic_cashdrawer.models', function (require) { var done = rpc.query({ model: 'pos.session', method: 'action_set_balance', - args: [[this.pos_session.id], { - inventory: inventory, - balance: balance - }] + args: [[this.pos_session.id], inventory, balance] }); done.fail(function (error) { self.gui.show_popup('error-traceback', { @@ -106,10 +103,7 @@ odoo.define('pos_automatic_cashdrawer.models', function (require) { return rpc.query({ model: 'pos.session', method: 'action_put_money_in', - args: [[this.pos_session.id], { - 'amount': amount, - 'reason': reason, - }] + args: [[this.pos_session.id], amount, reason] }); }, @@ -120,10 +114,7 @@ odoo.define('pos_automatic_cashdrawer.models', function (require) { return rpc.query({ model: 'pos.session', method: 'action_take_money_out', - args: [[this.pos_session.id], { - 'amount': amount, - 'reason': reason, - }] + args: [[this.pos_session.id], amount, reason] }); }, }); From f154b17a9f94664f2686279e3ced945d56a471dc Mon Sep 17 00:00:00 2001 From: phucph Date: Mon, 1 Dec 2025 11:30:47 +0700 Subject: [PATCH 09/10] [IMP] pos_automatic_cashdrawer: pre-commit auto fixes --- pos_automatic_cashdrawer/README.rst | 76 +- pos_automatic_cashdrawer/demo/demo.xml | 8 +- .../models/account_journal.py | 2 +- pos_automatic_cashdrawer/models/pos_config.py | 2 +- .../models/pos_session.py | 10 +- pos_automatic_cashdrawer/pyproject.toml | 3 + pos_automatic_cashdrawer/readme/CONFIGURE.md | 3 + pos_automatic_cashdrawer/readme/CONFIGURE.rst | 2 - .../readme/CONTRIBUTORS.md | 4 + .../readme/CONTRIBUTORS.rst | 4 - .../{DESCRIPTION.rst => DESCRIPTION.md} | 0 pos_automatic_cashdrawer/readme/INSTALL.md | 5 + pos_automatic_cashdrawer/readme/INSTALL.rst | 5 - pos_automatic_cashdrawer/readme/USAGE.md | 3 + pos_automatic_cashdrawer/readme/USAGE.rst | 2 - .../security/res_groups.xml | 4 +- .../static/description/index.html | 88 +- .../src/css/pos_automatic_cashdrawer.css | 13 +- .../static/src/js/chrome.js | 171 ++-- .../static/src/js/devices.js | 251 +++--- .../static/src/js/models.js | 82 +- .../static/src/js/screens.js | 42 +- .../static/src/js/widgets.js | 799 +++++++++++------- .../src/xml/pos_automatic_cashdrawer.xml | 232 +++-- .../views/account_journal.xml | 6 +- pos_automatic_cashdrawer/views/assets.xml | 32 +- pos_automatic_cashdrawer/views/pos_config.xml | 37 +- 27 files changed, 1158 insertions(+), 728 deletions(-) create mode 100644 pos_automatic_cashdrawer/pyproject.toml create mode 100644 pos_automatic_cashdrawer/readme/CONFIGURE.md delete mode 100644 pos_automatic_cashdrawer/readme/CONFIGURE.rst create mode 100644 pos_automatic_cashdrawer/readme/CONTRIBUTORS.md delete mode 100644 pos_automatic_cashdrawer/readme/CONTRIBUTORS.rst rename pos_automatic_cashdrawer/readme/{DESCRIPTION.rst => DESCRIPTION.md} (100%) create mode 100644 pos_automatic_cashdrawer/readme/INSTALL.md delete mode 100644 pos_automatic_cashdrawer/readme/INSTALL.rst create mode 100644 pos_automatic_cashdrawer/readme/USAGE.md delete mode 100644 pos_automatic_cashdrawer/readme/USAGE.rst diff --git a/pos_automatic_cashdrawer/README.rst b/pos_automatic_cashdrawer/README.rst index c8cc64146b..c6d2854440 100644 --- a/pos_automatic_cashdrawer/README.rst +++ b/pos_automatic_cashdrawer/README.rst @@ -2,10 +2,13 @@ POS Automatic Cashdrawer ======================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:e73ed38d380e8af85d3a877abc3182d0fe2bf1ca0972506b861e1255689596da + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -13,11 +16,17 @@ POS Automatic Cashdrawer .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 -.. |badge3| image:: https://img.shields.io/badge/github-druidoo%2FFoodCoops-lightgray.png?logo=github - :target: https://github.com/druidoo/FoodCoops/tree/12.0/pos_automatic_cashdrawer - :alt: druidoo/FoodCoops - -|badge1| |badge2| |badge3| +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github + :target: https://github.com/OCA/pos/tree/18.0/pos_automatic_cashdrawer + :alt: OCA/pos +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/pos-18-0/pos-18-0-pos_automatic_cashdrawer + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/pos&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| This module adds support for automatic cashdrawers in the Point of Sale. @@ -29,31 +38,34 @@ This module adds support for automatic cashdrawers in the Point of Sale. Installation ============ -This module is designed to be installed on the -*main Odoo server*. On the *POSbox*, you should install the module -*hw_x* depending on the protocol implemented in your device. -`Cashlogy ` are implemented in the -*hw_cashlogy* module and also in pywebdriver . +This module is designed to be installed on the *main Odoo server*. On +the *POSbox*, you should install the module *hw_x* depending on the +protocol implemented in your device. Cashlogy +<`http://www.cashlogy.com\\> >`__ are +implemented in the *hw_cashlogy* module and also in pywebdriver +<`https://github.com/akretion/pywebdriver\\> >`__. Configuration ============= -The cashlogyConnector adddress and port should be configured on the main Odoo server, -in the menu *Pointof Sale > Configuration > Payment Methods*,under the *Point of Sale* tab. +The cashlogyConnector adddress and port should be configured on the main +Odoo server, in the menu *Pointof Sale > Configuration > Payment +Methods*,under the *Point of Sale* tab. Usage ===== -In the frontend of the POS, when you select a payment method CASH you will have a *Start Transaction* button : -if you click on that button, the amount will be sent to the POSbox. +In the frontend of the POS, when you select a payment method CASH you +will have a *Start Transaction* button : if you click on that button, +the amount will be sent to the POSbox. Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. +Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -61,22 +73,32 @@ Credits ======= Authors -~~~~~~~ +------- * Aurélien DUMAINE * Druidoo Contributors -~~~~~~~~~~~~ +------------ -* Aurelien Dumaine -* Mathieu Vatel -* Iván Todorovich -* Druidoo +- Aurelien Dumaine +- Mathieu Vatel +- Iván Todorovich +- Druidoo <`https://www.druidoo.io\\> >`__ Maintainers -~~~~~~~~~~~ +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. -This module is part of the `druidoo/FoodCoops `_ project on GitHub. +This module is part of the `OCA/pos `_ project on GitHub. -You are welcome to contribute. +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_automatic_cashdrawer/demo/demo.xml b/pos_automatic_cashdrawer/demo/demo.xml index 57bef68c3a..2271e758b2 100644 --- a/pos_automatic_cashdrawer/demo/demo.xml +++ b/pos_automatic_cashdrawer/demo/demo.xml @@ -1,10 +1,10 @@ - + - - 127.0.0.1 - 8092 + + 127.0.0.1 + 8092 diff --git a/pos_automatic_cashdrawer/models/account_journal.py b/pos_automatic_cashdrawer/models/account_journal.py index 0f88a3505d..b06a574d80 100644 --- a/pos_automatic_cashdrawer/models/account_journal.py +++ b/pos_automatic_cashdrawer/models/account_journal.py @@ -2,7 +2,7 @@ # Copyright (C) 2016-Today: La Louve # Copyright (C) 2019 Druidoo -from odoo import models, fields +from odoo import fields, models class AccountJournal(models.Model): diff --git a/pos_automatic_cashdrawer/models/pos_config.py b/pos_automatic_cashdrawer/models/pos_config.py index 35b32852c8..1959af9f8b 100644 --- a/pos_automatic_cashdrawer/models/pos_config.py +++ b/pos_automatic_cashdrawer/models/pos_config.py @@ -3,7 +3,7 @@ # Copyright (C) 2019 Druidoo # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import fields, models, api +from odoo import api, fields, models class PosConfig(models.Model): diff --git a/pos_automatic_cashdrawer/models/pos_session.py b/pos_automatic_cashdrawer/models/pos_session.py index ea2e951cc5..36ad963c8c 100644 --- a/pos_automatic_cashdrawer/models/pos_session.py +++ b/pos_automatic_cashdrawer/models/pos_session.py @@ -2,7 +2,7 @@ import logging -from odoo import api, models, _ +from odoo import _, api, models from odoo.exceptions import UserError _logger = logging.getLogger(__name__) @@ -104,9 +104,7 @@ def _get_cash_in_out_fields(self): @api.multi def action_put_money_in(self, amount, reason): self.ensure_one() - wizard = self.env["cash.box.in"].create( - {"amount": amount, "name": reason} - ) + wizard = self.env["cash.box.in"].create({"amount": amount, "name": reason}) wizard.with_context(active_model=self._name, active_ids=self.ids).run() # Return the last added line return ( @@ -123,9 +121,7 @@ def action_put_money_in(self, amount, reason): @api.multi def action_take_money_out(self, amount, reason): self.ensure_one() - wizard = self.env["cash.box.out"].create( - {"amount": amount, "name": reason} - ) + wizard = self.env["cash.box.out"].create({"amount": amount, "name": reason}) wizard.with_context(active_model=self._name, active_ids=self.ids).run() # Return the last added line return ( diff --git a/pos_automatic_cashdrawer/pyproject.toml b/pos_automatic_cashdrawer/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/pos_automatic_cashdrawer/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/pos_automatic_cashdrawer/readme/CONFIGURE.md b/pos_automatic_cashdrawer/readme/CONFIGURE.md new file mode 100644 index 0000000000..73ef79dc84 --- /dev/null +++ b/pos_automatic_cashdrawer/readme/CONFIGURE.md @@ -0,0 +1,3 @@ +The cashlogyConnector adddress and port should be configured on the main +Odoo server, in the menu *Pointof Sale \> Configuration \> Payment +Methods*,under the *Point of Sale* tab. diff --git a/pos_automatic_cashdrawer/readme/CONFIGURE.rst b/pos_automatic_cashdrawer/readme/CONFIGURE.rst deleted file mode 100644 index de83d6aa88..0000000000 --- a/pos_automatic_cashdrawer/readme/CONFIGURE.rst +++ /dev/null @@ -1,2 +0,0 @@ -The cashlogyConnector adddress and port should be configured on the main Odoo server, -in the menu *Pointof Sale > Configuration > Payment Methods*,under the *Point of Sale* tab. \ No newline at end of file diff --git a/pos_automatic_cashdrawer/readme/CONTRIBUTORS.md b/pos_automatic_cashdrawer/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..3e6be06de8 --- /dev/null +++ b/pos_automatic_cashdrawer/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- Aurelien Dumaine +- Mathieu Vatel +- Iván Todorovich +- Druidoo \ diff --git a/pos_automatic_cashdrawer/readme/CONTRIBUTORS.rst b/pos_automatic_cashdrawer/readme/CONTRIBUTORS.rst deleted file mode 100644 index c4ab824565..0000000000 --- a/pos_automatic_cashdrawer/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,4 +0,0 @@ -* Aurelien Dumaine -* Mathieu Vatel -* Iván Todorovich -* Druidoo diff --git a/pos_automatic_cashdrawer/readme/DESCRIPTION.rst b/pos_automatic_cashdrawer/readme/DESCRIPTION.md similarity index 100% rename from pos_automatic_cashdrawer/readme/DESCRIPTION.rst rename to pos_automatic_cashdrawer/readme/DESCRIPTION.md diff --git a/pos_automatic_cashdrawer/readme/INSTALL.md b/pos_automatic_cashdrawer/readme/INSTALL.md new file mode 100644 index 0000000000..d9d2d515ab --- /dev/null +++ b/pos_automatic_cashdrawer/readme/INSTALL.md @@ -0,0 +1,5 @@ +This module is designed to be installed on the *main Odoo server*. On +the *POSbox*, you should install the module *hw_x* depending on the +protocol implemented in your device. Cashlogy +\ are implemented in the *hw_cashlogy* module +and also in pywebdriver \. diff --git a/pos_automatic_cashdrawer/readme/INSTALL.rst b/pos_automatic_cashdrawer/readme/INSTALL.rst deleted file mode 100644 index 5bf2266dad..0000000000 --- a/pos_automatic_cashdrawer/readme/INSTALL.rst +++ /dev/null @@ -1,5 +0,0 @@ -This module is designed to be installed on the -*main Odoo server*. On the *POSbox*, you should install the module -*hw_x* depending on the protocol implemented in your device. -`Cashlogy ` are implemented in the -*hw_cashlogy* module and also in pywebdriver . diff --git a/pos_automatic_cashdrawer/readme/USAGE.md b/pos_automatic_cashdrawer/readme/USAGE.md new file mode 100644 index 0000000000..4b4dd1bb9d --- /dev/null +++ b/pos_automatic_cashdrawer/readme/USAGE.md @@ -0,0 +1,3 @@ +In the frontend of the POS, when you select a payment method CASH you +will have a *Start Transaction* button : if you click on that button, +the amount will be sent to the POSbox. diff --git a/pos_automatic_cashdrawer/readme/USAGE.rst b/pos_automatic_cashdrawer/readme/USAGE.rst deleted file mode 100644 index 7dd6e30296..0000000000 --- a/pos_automatic_cashdrawer/readme/USAGE.rst +++ /dev/null @@ -1,2 +0,0 @@ -In the frontend of the POS, when you select a payment method CASH you will have a *Start Transaction* button : -if you click on that button, the amount will be sent to the POSbox. diff --git a/pos_automatic_cashdrawer/security/res_groups.xml b/pos_automatic_cashdrawer/security/res_groups.xml index 76ec169c17..11b27f840e 100644 --- a/pos_automatic_cashdrawer/security/res_groups.xml +++ b/pos_automatic_cashdrawer/security/res_groups.xml @@ -1,9 +1,9 @@ - + PoS - Allow Cashlogy config - + diff --git a/pos_automatic_cashdrawer/static/description/index.html b/pos_automatic_cashdrawer/static/description/index.html index c3350e8670..c29e83fd10 100644 --- a/pos_automatic_cashdrawer/static/description/index.html +++ b/pos_automatic_cashdrawer/static/description/index.html @@ -1,20 +1,20 @@ - - + POS Automatic Cashdrawer -
-

POS Automatic Cashdrawer

+
+

POS Automatic Cashdrawer Cashlogy

-

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

-

This module adds support for automatic cashdrawers in the Point of Sale.

+

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

+
    +
  • This module adds support for automatic cashdrawers in the Point of +Sale with other IP Address different with IoT Box.
  • +
  • In user form, you can add Point of Sale - Allow Cashlogy Config +group to user to display Cashlogy Admin popup in PoS.
  • +

Table of contents

Configuration

-

The cashlogyConnector adddress and port should be configured on the main -Odoo server, in the menu Pointof Sale > Configuration > Payment -Methods,under the Point of Sale tab.

+
    +
  • Go to Point of Sale > Configuration > Settings, in +Connected Devices section, enable Automation Cashdrawer and fill +IP Address, TCP Port.
  • +
+

Config automatic cashdrawer

+
    +
  • Go to Point of Sale > Configuration > Payment Methods, with Cash +type, enable Automation Cashdrawer.
  • +
+

Config pos payment methods

Usage

In the frontend of the POS, when you select a payment method CASH you -will have a Start Transaction button : if you click on that button, -the amount will be sent to the POSbox.

+can see a popup show Customer Transaction to start adding cash into +the machine. When fully paid or have change, the amount of cash will be +updated.

+

Payment

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -431,6 +446,10 @@

Contributors

  • Mathieu Vatel
  • Iván Todorovich
  • Druidoo <https://www.druidoo.io\>
  • +
  • Trobz +
  • @@ -442,7 +461,7 @@

    Maintainers

    OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

    -

    This module is part of the OCA/pos project on GitHub.

    +

    This module is part of the OCA/pos project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    diff --git a/pos_automatic_cashdrawer/static/src/css/pos_automatic_cashdrawer.css b/pos_automatic_cashdrawer_cashlogy/static/src/css/pos_automatic_cashdrawer_cashlogy.css similarity index 54% rename from pos_automatic_cashdrawer/static/src/css/pos_automatic_cashdrawer.css rename to pos_automatic_cashdrawer_cashlogy/static/src/css/pos_automatic_cashdrawer_cashlogy.css index 2cb61b7870..bd5f451f8e 100644 --- a/pos_automatic_cashdrawer/static/src/css/pos_automatic_cashdrawer.css +++ b/pos_automatic_cashdrawer_cashlogy/static/src/css/pos_automatic_cashdrawer_cashlogy.css @@ -11,28 +11,23 @@ position: absolute; } -.pos .modal-dialog .popup.popup-cashdrawer-admin { - height: 650px; -} - -.pos .popup-cashdrawer-admin .actions .button { +.popup-cashdrawer-admin.actions .button { float: none; width: auto; - margin: 15px; + margin: 15px 0px; height: 40px; line-height: 40px; font-size: 16px; font-weight: normal; - position: relative; + display: flex; + align-items: center; } -.pos .popup-cashdrawer-admin hr { - border-color: rgba(60, 60, 60, 0.1); +.popup-cashdrawer-admin hr { margin: 10px 15px; } -.pos .popup-cashdrawer-admin .actions .button .fa { - position: absolute; +.popup-cashdrawer-admin.actions .button .fa { left: 15px; top: 8px; margin-right: 8px; @@ -40,7 +35,7 @@ width: 35px; } -.pos .popup-cashdrawer .total .value { +.popup-cashdrawer .total .value { text-align: center; padding: 24px 0px 18px; font-size: 64px; @@ -50,33 +45,29 @@ 0px 2px 2px rgba(0, 0, 0, 0.27); } -.pos .modal-dialog .popup-cashdrawer-inventory { - height: 700px; -} - -.pos .popup-cashdrawer-inventory .inventory-table { +.popup-cashdrawer-inventory .inventory-table { padding: 20px; } -.pos .popup-cashdrawer-inventory .inventory-table table { +.popup-cashdrawer-inventory .inventory-table table { width: 100%; font-weight: normal; font-size: 15px; text-align: right; } -.pos .popup-cashdrawer-inventory .inventory-table table td { +.popup-cashdrawer-inventory .inventory-table table td { line-height: 25px; padding: 0 10px; } -.pos .popup-cashdrawer-inventory .inventory-table table th { +.popup-cashdrawer-inventory .inventory-table table th { line-height: 30px; padding: 0 10px; width: 25%; } -.pos .popup-cashdrawer-inventory .inventory-table thead > tr, -.pos .popup-cashdrawer-inventory .inventory-table tr:nth-child(even) { +.popup-cashdrawer-inventory .inventory-table thead > tr, +.popup-cashdrawer-inventory .inventory-table tr:nth-child(even) { background: rgb(247, 247, 247); } diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_admin.esm.js b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_admin.esm.js new file mode 100644 index 0000000000..acbadc93c7 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_admin.esm.js @@ -0,0 +1,257 @@ +import {AutomaticCashdrawerInventoryDialog} from "@pos_automatic_cashdrawer_cashlogy/dialogs/cashdrawer_inventory.esm"; +import {Component} from "@odoo/owl"; +import {Dialog} from "@web/core/dialog/dialog"; +import {_t} from "@web/core/l10n/translation"; +import {renderToElement} from "@web/core/utils/render"; +import {usePos} from "@point_of_sale/app/store/pos_hook"; +import {useService} from "@web/core/utils/hooks"; + +export class AutomaticCashdrawerAdmin extends Component { + static template = "AutomaticCashdrawerAdmin"; + static components = {Dialog}; + static props = { + close: Function, + }; + setup() { + super.setup(...arguments); + this.dialog = useService("dialog"); + this.notification = useService("notification"); + this.pos = usePos(); + this.printer = useService("printer"); + this.ui = useService("ui"); + } + + /** + * HELPERS + **/ + + extras(amount, type) { + const formattedAmount = this.pos.formatCurrencyCashlogy(amount); + const translatedType = _t(type); + return { + formattedAmount, + translatedType, + }; + } + + /** + * ACTIONS + **/ + + cancel() { + this.props.close(); + } + + async action_print_inventory() { + this.dialog.closeAll(); + try { + this.ui.block(); + const totals = await this.pos.callAutomaticCashdrawerGetTotalAmount(); + const inventory = await this.pos.callAutomaticCashdrawerGetInventory(); + const sorted_values = Object.keys(inventory.total) + .map((k) => parseFloat(k)) + .sort((a, b) => b - a); + return this.dialog.add(AutomaticCashdrawerInventoryDialog, { + totals: totals, + inventory: inventory, + sorted_values: sorted_values, + }); + } catch (error) { + this.pos.showErrorCashlogy(error); + } finally { + this.ui.unblock(); + } + } + + async action_display_backoffice() { + try { + await this.pos.callAutomaticCashlogyDisplayBackoffice(); + } catch (error) { + this.pos.showErrorCashlogy(error); + } finally { + this.notification.add(_t("Backoffice displayed successfully"), { + type: "success", + }); + } + } + + async action_cancel() { + this.ui.block(); + await this.pos.callAutomaticCashdrawerStopAcceptance().then(async (res) => { + const xmlReportElement = renderToElement( + "AutomaticCashdrawerActionXmlReport", + { + pos: this.pos, + report: { + name: _t("Manual Cancel"), + lines: [ + _t("Money in/out: ") + this.pos.formatCurrencyCashlogy(res), + _t( + "IMPORTANT: This operations is not registered on the cash statement. You have to manually register it." + ), + ], + }, + } + ); + await this.pos.sendCashlogy("print_xml_receipt", { + receipt: xmlReportElement.outerHTML, + }); + this.notification.add(_t("Send Cancel Successfully"), {type: "success"}); + }); + this.ui.unblock(); + this.dialog.closeAll(); + } + + async action_close_till() { + this.ui.block(); + this.pos.checkCashInOutPossible(); + await this.pos.callAutomaticCashdrawerDisplayCloseTill().then(async (res) => { + if (res.added) { + await this.pos + .actionPutMoneyIn( + res.added, + _t("Automatic Cashdrawer: Close Till / ADDED"), + this.extras(res.added, "in") + ) + .then(async (st_line) => { + const xmlReportElement = renderToElement( + "AutomaticCashdrawerActionXmlReport", + { + pos: this.pos, + report: { + name: _t("Close Till Result"), + lines: [ + _t("Total added: ") + + this.pos.formatCurrencyCashlogy(res.added), + ], + st_line: st_line, + }, + } + ); + await this.pos.sendCashlogy("print_xml_receipt", { + receipt: xmlReportElement.outerHTML, + }); + this.notification.add(_t("Close Till / ADDED Successfully"), { + type: "success", + }); + }); + } + if (res.dispensed) { + await this.pos + .actionTakeMoneyOut( + res.dispensed, + _t("Automatic Cashdrawer: Close Till / DISPENSED"), + this.extras(res.dispensed, "out") + ) + .then(async (st_line) => { + const xmlReportElement = renderToElement( + "AutomaticCashdrawerActionXmlReport", + { + pos: this.pos, + report: { + name: _t("Close Till Result"), + lines: [ + _t("Total dispensed: ") + + this.pos.formatCurrencyCashlogy( + res.dispensed + ), + ], + st_line: st_line, + }, + } + ); + await this.pos.sendCashlogy("print_xml_receipt", { + receipt: xmlReportElement.outerHTML, + }); + this.notification.add( + _t("Close Till / DISPENSED Successfully"), + {type: "success"} + ); + }); + } + }); + this.ui.unblock(); + this.dialog.closeAll(); + } + + async action_empty_stacker() { + this.ui.block(); + this.pos.checkCashInOutPossible(); + await this.pos.callAutomaticCashdrawerEmptyStacker().then(async (res) => { + if (res) { + await this.pos + .actionTakeMoneyOut( + res, + _t("Automatic Cashdrawer: Empty Stacker"), + this.extras(res, "out") + ) + .then(async (st_line) => { + const xmlReportElement = renderToElement( + "AutomaticCashdrawerActionXmlReport", + { + pos: this.pos, + report: { + name: _t("Empty Stacker"), + lines: [ + _t("Total dispensed: ") + + this.pos.formatCurrencyCashlogy(res), + ], + st_line: st_line, + }, + } + ); + await this.pos.sendCashlogy("print_xml_receipt", { + receipt: xmlReportElement.outerHTML, + }); + this.notification.add(_t("Empty Stacker Successfully"), { + type: "success", + }); + }); + } + }); + this.ui.unblock(); + this.dialog.closeAll(); + } + + async action_complete_emptying() { + this.ui.block(); + this.pos.checkCashInOutPossible(); + await this.pos + .callAutomaticCashdrawerDisplayCompleteEmptying() + .then(async (res) => { + if (res) { + await this.pos + .actionTakeMoneyOut( + res, + _t("Automatic Cashdrawer: Complete Emptying"), + this.extras(res, "out") + ) + .then(async (st_line) => { + const xmlReportElement = renderToElement( + "AutomaticCashdrawerActionXmlReport", + { + pos: this.pos, + report: { + name: _t("Complete Emptying"), + lines: [ + _t("Total dispensed: ") + + this.pos.formatCurrencyCashlogy(res), + ], + st_line: st_line, + }, + } + ); + await this.pos.sendCashlogy("print_xml_receipt", { + receipt: xmlReportElement.outerHTML, + }); + this.notification.add( + _t("Complete Emptying Successfully"), + {type: "success"} + ); + }); + } + }); + this.ui.unblock(); + this.dialog.closeAll(); + } +} diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_admin.xml b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_admin.xml new file mode 100644 index 0000000000..bee7d56e30 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_admin.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_cash_in.esm.js b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_cash_in.esm.js new file mode 100644 index 0000000000..e2321e89c9 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_cash_in.esm.js @@ -0,0 +1,136 @@ +/* global clearTimeout, setTimeout */ + +import {Component, onMounted, onWillUnmount, useState} from "@odoo/owl"; +import {AlertDialog} from "@web/core/confirmation_dialog/confirmation_dialog"; +import {Dialog} from "@web/core/dialog/dialog"; +import {_t} from "@web/core/l10n/translation"; +import {roundPrecision} from "@web/core/utils/numbers"; +import {usePos} from "@point_of_sale/app/store/pos_hook"; +import {useService} from "@web/core/utils/hooks"; + +export class AutomaticCashdrawerCashInDialog extends Component { + static template = "AutomaticCashdrawerCashInDialog"; + static components = {Dialog}; + static props = { + allow_cancel: Boolean, + auto_accept: Boolean, + to_collect: Number, + payment: Boolean, + confirmCashIn: Function, + cancelCashIn: Function, + close: Function, + body: {type: String, optional: true}, + }; + + setup() { + super.setup(); + this.pos = usePos(); + this.dialog = useService("dialog"); + this.notification = useService("notification"); + this.ui = useService("ui"); + this.inputBuffer = useState({value: 0.0}); + this.loading = useState({value: false}); + this.closed = false; + const {payment} = this.props; + onMounted(() => { + this.loading.value = true; + if (payment) { + this.pos.callAutomaticCashdrawerStartAcceptance().then(() => { + this.updateCounter(); + }); + } else { + this.pos.callAutomaticCashdrawerStartAddChange().then(() => { + this.updateCounter(); + }); + } + }); + onWillUnmount(() => { + if (this.timer) { + clearTimeout(this.timer); + } + this.closed = true; + }); + } + + async updateCounter() { + await this.pos.callAutomaticCashdrawerGetAmountAccepted().then((res) => { + if (this.closed) { + return; + } + this.inputBuffer.value = res; + // Auto accept dialog if amount is enough + const {to_collect, auto_accept} = this.props; + if (to_collect && auto_accept && this.inputBuffer.value >= to_collect) { + return this.onClickConfirm(); + } + this.timer = setTimeout(async () => { + this.updateCounter(); + }, 1000); + }); + } + + async onClickCancel() { + if (this.props.allow_cancel) { + try { + this.ui.block(); + await this.pos.callAutomaticCashdrawerStopAcceptance().then((value) => { + this.pos.callAutomaticCashdrawerDispense(value); + }); + } catch { + this.dialog.add(AlertDialog, { + title: _t("Error"), + body: _t("An error occurred during the cancel."), + }); + } finally { + this.ui.unblock(); + this.props.close(); + this.props.cancelCashIn(); + this.notification.add(_t("Transaction Cancelled"), {type: "success"}); + } + } else { + this.dialog.add(AlertDialog, { + title: _t("Failed"), + body: _t("Cancel not enable"), + }); + } + } + + async onClickConfirm() { + try { + this.loading.value = false; + this.ui.block(); + await this.pos + .callAutomaticCashdrawerStopAcceptance() + .then(async (response) => { + const {to_collect} = this.props; + if (to_collect && response >= to_collect) { + const rounding = this.pos.currency.rounding; + const change = roundPrecision(response - to_collect, rounding); + if (change > 0) { + // More was collected, we dispense + await this.pos + .callAutomaticCashdrawerDispense(change) + .then(() => { + this.props.confirmCashIn(response); + }); + } else { + // Exact amount was collected + this.props.confirmCashIn(response); + } + } else { + // Not enough was collected + this.props.confirmCashIn(response); + } + }); + } catch { + this.dialog.add(AlertDialog, { + title: _t("Error"), + body: _t("An error occurred during the confirm."), + }); + } finally { + this.ui.unblock(); + this.props.close(); + this.notification.add(_t("Transaction Success"), {type: "success"}); + } + } +} diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_cash_in.xml b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_cash_in.xml new file mode 100644 index 0000000000..bd00101dea --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_cash_in.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_inventory.esm.js b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_inventory.esm.js new file mode 100644 index 0000000000..a79c85dc91 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_inventory.esm.js @@ -0,0 +1,54 @@ +import {Component} from "@odoo/owl"; +import {Dialog} from "@web/core/dialog/dialog"; +import {_t} from "@web/core/l10n/translation"; +import {renderToElement} from "@web/core/utils/render"; +import {usePos} from "@point_of_sale/app/store/pos_hook"; +import {useService} from "@web/core/utils/hooks"; + +export class AutomaticCashdrawerInventoryDialog extends Component { + static template = "AutomaticCashdrawerInventoryDialog"; + static components = {Dialog}; + static props = { + close: Function, + totals: Object, + inventory: Object, + sorted_values: Array, + }; + setup() { + super.setup(...arguments); + this.dialog = useService("dialog"); + this.notification = useService("notification"); + this.printer = useService("printer"); + this.ui = useService("ui"); + this.pos = usePos(); + } + + /** + * ACTIONS + **/ + + cancel() { + this.props.close(); + } + async print_inventory() { + this.ui.block(); + const {totals, inventory, sorted_values} = this.props; + const xmlReportElement = renderToElement( + "AutomaticCashdrawerInventoryXmlReport", + { + pos: this.pos, + report: { + totals: totals, + inventory: inventory, + sorted_values: sorted_values, + }, + } + ); + await this.pos.sendCashlogy("print_xml_receipt", { + receipt: xmlReportElement.outerHTML, + }); + this.notification.add(_t("Print Inventory Successfully"), {type: "success"}); + this.ui.unblock(); + this.props.close(); + } +} diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_inventory.xml b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_inventory.xml new file mode 100644 index 0000000000..a955e07769 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/dialogs/cashdrawer_inventory.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/hardware_proxy/hardware_proxy_device.esm.js b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/hardware_proxy/hardware_proxy_device.esm.js new file mode 100644 index 0000000000..9bd09882c0 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/hardware_proxy/hardware_proxy_device.esm.js @@ -0,0 +1,16 @@ +import {HardwareProxy} from "@point_of_sale/app/hardware_proxy/hardware_proxy_service"; +import {patch} from "@web/core/utils/patch"; + +patch(HardwareProxy.prototype, { + async keepalive() { + super.keepalive(); + if (this.pos.config.iface_automatic_cashdrawer) { + await this.pos.sendCashlogy("/cashlogy/connnect", { + config: { + host: this.pos.config.iface_automatic_cashdrawer_ip_address, + port: this.pos.config.iface_automatic_cashdrawer_tcp_port, + }, + }); + } + }, +}); diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/navbar/navbar.esm.js b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/navbar/navbar.esm.js new file mode 100644 index 0000000000..164633b2be --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/navbar/navbar.esm.js @@ -0,0 +1,22 @@ +import {AutomaticCashdrawerAdmin} from "@pos_automatic_cashdrawer_cashlogy/dialogs/cashdrawer_admin.esm"; +import {Navbar} from "@point_of_sale/app/navbar/navbar"; +import {onWillStart} from "@odoo/owl"; +import {patch} from "@web/core/utils/patch"; +import {user} from "@web/core/user"; + +patch(Navbar.prototype, { + setup() { + super.setup(...arguments); + onWillStart(async () => { + this.allowCashlogy = await user.hasGroup( + "pos_automatic_cashdrawer_cashlogy.group_pos_automatic_cashlogy_config" + ); + }); + }, + get showCashlogyAdmin() { + return this.pos.config.iface_automatic_cashdrawer && this.allowCashlogy; + }, + openCashlogyAdmin() { + this.dialog.add(AutomaticCashdrawerAdmin, {}); + }, +}); diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/navbar/navbar.xml b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/navbar/navbar.xml new file mode 100644 index 0000000000..8e1d06abc8 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/navbar/navbar.xml @@ -0,0 +1,19 @@ + + + + + + + Cashlogy Admin + + + + + diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/payment_screen/payment_screen.esm.js b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/payment_screen/payment_screen.esm.js new file mode 100644 index 0000000000..773cf8cc74 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/payment_screen/payment_screen.esm.js @@ -0,0 +1,30 @@ +import {AutomaticCashdrawerCashInDialog} from "@pos_automatic_cashdrawer_cashlogy/dialogs/cashdrawer_cash_in.esm"; +import {PaymentScreen} from "@point_of_sale/app/screens/payment_screen/payment_screen"; +import {patch} from "@web/core/utils/patch"; + +patch(PaymentScreen.prototype, { + async addNewPaymentLine(paymentMethod) { + const result = super.addNewPaymentLine(paymentMethod); + const line = this.selectedPaymentLine; + if (line && line.get_iface_automatic_cashdrawer()) { + this.openCashdrawerCashInDialog(line); + } + return result; + }, + + openCashdrawerCashInDialog(line) { + const amount = line.get_amount(); + this.dialog.add(AutomaticCashdrawerCashInDialog, { + to_collect: amount, + allow_cancel: true, + auto_accept: true, + payment: true, + confirmCashIn: (amountIn) => { + line.set_amount(amountIn); + }, + cancelCashIn: () => { + this.deletePaymentLine(line.uuid); + }, + }); + }, +}); diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/payment_screen/pos_payment.esm.js b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/payment_screen/pos_payment.esm.js new file mode 100644 index 0000000000..06e2800dbb --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/payment_screen/pos_payment.esm.js @@ -0,0 +1,8 @@ +import {PosPayment} from "@point_of_sale/app/models/pos_payment"; +import {patch} from "@web/core/utils/patch"; + +patch(PosPayment.prototype, { + get_iface_automatic_cashdrawer() { + return this.payment_method_id.iface_automatic_cashdrawer || false; + }, +}); diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/store/pos_store.esm.js b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/store/pos_store.esm.js new file mode 100644 index 0000000000..8aaad7e411 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/overrides/components/store/pos_store.esm.js @@ -0,0 +1,290 @@ +/* global console, fetch*/ + +import {AlertDialog} from "@web/core/confirmation_dialog/confirmation_dialog"; +import {PosStore} from "@point_of_sale/app/store/pos_store"; +import {_t} from "@web/core/l10n/translation"; +import {deduceUrl} from "@point_of_sale/utils"; +import {patch} from "@web/core/utils/patch"; + +patch(PosStore.prototype, { + async setup() { + await super.setup(...arguments); + }, + async checkCashInOutPossible() { + const result = await this.data.call( + "pos.session", + "js_check_cash_in_out_possible", + [this.session.id] + ); + if (result.error) { + this.dialog.add(AlertDialog, { + title: _t("Error"), + body: result.message, + }); + } + }, + async actionPutMoneyIn(amount, reason, extras) { + const res = await this.data.call("pos.session", "action_put_money_in", [ + [this.session.id], + amount, + reason, + extras, + ]); + return res; + }, + async actionTakeMoneyOut(amount, reason, extras) { + const res = await this.data.call("pos.session", "action_take_money_out", [ + [this.session.id], + amount, + reason, + extras, + ]); + return res; + }, + + /** + * CALL CASHLOGY METHODS + **/ + + async callAutomaticCashdrawerDisplayTransactionStart(amount, options = {}) { + try { + this.ui.block(); + const res = await this.sendCashlogy("cashlogy/display_transaction_start", { + amount: amount, + options: options, + }); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } finally { + this.ui.unblock(); + } + }, + + async callAutomaticCashlogyDisplayBackoffice() { + try { + this.ui.block(); + const res = await this.sendCashlogy("cashlogy/display_backoffice", {}); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } finally { + this.ui.unblock(); + } + }, + + /* + Dispenses money + amount float + options.only_coins default False + + @returns 0.00 + */ + async callAutomaticCashdrawerDispense(amount, options = {}) { + try { + const res = await this.sendCashlogy("cashlogy/dispense", { + amount: amount, + options: options, + }); + if (res !== amount) { + const message = _t( + "Cashlogy: The dispensed amount was different than the requested" + ); + console.error(message); + this.notification.add(message, {type: "warning"}); + } else { + const res_formatted = this.formatCurrencyCashlogy(res); + this.notification.add( + _t(`Successfully made a dispend amount of ${res_formatted}`), + {type: "success"} + ); + } + } catch (error) { + this.showErrorCashlogy(error); + } + }, + + /* + Start add change + Used to load money into the cashdrawer + It has to be stopped using stop_acceptance + The amount loaded so far can be queried with get_amount_accepted + */ + async callAutomaticCashdrawerStartAddChange() { + try { + const res = await this.sendCashlogy("cashlogy/start_add_change", {}); + const res_formatted = this.formatCurrencyCashlogy(res); + this.notification.add( + _t(`Successfully load money into the cashdrawer of ${res_formatted}`), + {type: "success"} + ); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } + }, + + /* + Start acceptance + Similar to Start add change, but used for sales + It has to be stopped using stop_acceptance + The amount loaded so far can be queried with get_amount_accepted + */ + async callAutomaticCashdrawerStartAcceptance() { + try { + const res = await this.sendCashlogy("cashlogy/start_acceptance", {}); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } + }, + /* + Returns the money accepted so far + @returns 0.00 + */ + async callAutomaticCashdrawerGetAmountAccepted() { + try { + const res = await this.sendCashlogy("cashlogy/get_amount_accepted", {}); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } + }, + + /* + Stops acceptance of money + @returns 0.00 + */ + async callAutomaticCashdrawerStopAcceptance() { + try { + const res = await this.sendCashlogy("cashlogy/stop_acceptance", {}); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } + }, + + /* + Gets the inventory of the machine + Returns {total: {} recycler: {} stacker: {}} + */ + async callAutomaticCashdrawerGetInventory() { + try { + const res = await this.sendCashlogy("cashlogy/get_inventory", {}); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } + }, + + /* + Gets the total amount on the machine + Returns {total: 0.00, recycler: 0.00, stacker: 0.00} + */ + async callAutomaticCashdrawerGetTotalAmount() { + try { + const res = await this.sendCashlogy("cashlogy/get_total_amount", {}); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } + }, + + /* + Display Close Till + @returns {total_before: 0.00, added: 0.00, dispensed: 0.00, total: 0.00} + */ + async callAutomaticCashdrawerDisplayCloseTill() { + try { + this.ui.block(); + const res = await this.sendCashlogy("cashlogy/display_close_till", {}); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } finally { + this.ui.unblock(); + } + }, + + /* + Displays the backoffice empty stacker wizard. + @returns 0.00 - the amount removed from stacker + */ + async callAutomaticCashdrawerEmptyStacker() { + try { + this.ui.block(); + const res = await this.sendCashlogy("cashlogy/display_empty_stacker", {}); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } finally { + this.ui.unblock(); + } + }, + + /* + Displays the backoffice complete emptying wizard. + @returns 0.00 - the dispensed amount + */ + async callAutomaticCashdrawerDisplayCompleteEmptying() { + try { + this.ui.block(); + const res = await this.sendCashlogy( + "cashlogy/display_complete_emptying", + {} + ); + return res; + } catch (error) { + this.showErrorCashlogy(error); + } finally { + this.ui.unblock(); + } + }, + + /** + * HELPERS + **/ + + _getCashlogyIP() { + const IPAdress = this.config.iface_automatic_cashdrawer_ip_address; + const TCPPort = this.config.iface_automatic_cashdrawer_tcp_port; + if (!TCPPort) return IPAdress; + return `${IPAdress}:${TCPPort}`; + }, + + async sendCashlogy(name, params) { + const proxyIP = this._getCashlogyIP(); + if (!proxyIP) { + this.showErrorCashlogy({message: _t("IP address not configured.")}); + return; + } + const response = await fetch(`${deduceUrl(proxyIP)}/hw_proxy/${name}`, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + body: JSON.stringify({ + params, + }), + }); + const data = await response.json(); + return data.result; + }, + + showErrorCashlogy(error) { + this.dialog.closeAll(); + const message = error + ? error?.message + : _t("Make sure Cashdrawer connected with IOT Box"); + this.dialog.add(AlertDialog, { + title: _t("Cashdrawer Error"), + body: message, + }); + }, + + formatCurrencyCashlogy(value) { + const number = Number(value) || 0; + return this.env.utils.formatCurrency(number); + }, +}); diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/report/cashdrawer_action_xml_report.xml b/pos_automatic_cashdrawer_cashlogy/static/src/report/cashdrawer_action_xml_report.xml new file mode 100644 index 0000000000..c15e4dc422 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/report/cashdrawer_action_xml_report.xml @@ -0,0 +1,54 @@ + + + + +

    Automatic Cashdrawer

    +

    + +

    + + + + + +
    +
    + +

    + +

    +
    +
    +
    + +
    +
    +
    --------------------------------
    +
    User:
    +
    +
    + +
    +
    +
    +
    + + + + + +

    + +

    +
    + +
    +
    +
    --------------------------------
    +
    REF: ()
    +
    +
    +
    +
    diff --git a/pos_automatic_cashdrawer_cashlogy/static/src/report/cashdrawer_inventory_report.xml b/pos_automatic_cashdrawer_cashlogy/static/src/report/cashdrawer_inventory_report.xml new file mode 100644 index 0000000000..76fce5b187 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/static/src/report/cashdrawer_inventory_report.xml @@ -0,0 +1,115 @@ + + + + + + +

    Automatic Cashdrawer

    +

    Inventory

    + + + + +
    +
    + +

    + +

    +
    +
    +
    + +
    +
    +
    --------------------------------
    +
    User:
    +
    +
    +
    +
    + + + + + TOTALS + + + -------------------------------- + +
    + + + + + + + + + x ( + + + + + + + + ) = + + + + + +
    + + + + + -------- + + + Recycler + + + + + + + + Stacker + + + + + + + + + + + -------- + + + +
            TOTAL
    +
    + + + + + +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    diff --git a/pos_automatic_cashdrawer_cashlogy/views/pos_payment_method.xml b/pos_automatic_cashdrawer_cashlogy/views/pos_payment_method.xml new file mode 100644 index 0000000000..a352af3bf6 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/views/pos_payment_method.xml @@ -0,0 +1,14 @@ + + + + pos.payment.method.view.form + pos.payment.method + + 20 + + + + + + + diff --git a/pos_automatic_cashdrawer_cashlogy/views/res_config_settings_views.xml b/pos_automatic_cashdrawer_cashlogy/views/res_config_settings_views.xml new file mode 100644 index 0000000000..2b4ffb6b43 --- /dev/null +++ b/pos_automatic_cashdrawer_cashlogy/views/res_config_settings_views.xml @@ -0,0 +1,35 @@ + + + + res.config.settings + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +