OCA-git-bot
5 years ago
31 changed files with 2361 additions and 1 deletions
-
128pos_order_mgmt/README.rst
-
1pos_order_mgmt/__init__.py
-
28pos_order_mgmt/__manifest__.py
-
172pos_order_mgmt/i18n/es.po
-
249pos_order_mgmt/i18n/fr.po
-
244pos_order_mgmt/i18n/pos_order_mgmt.pot
-
2pos_order_mgmt/models/__init__.py
-
38pos_order_mgmt/models/pos_config.py
-
160pos_order_mgmt/models/pos_order.py
-
12pos_order_mgmt/readme/CONFIGURE.rst
-
5pos_order_mgmt/readme/CONTRIBUTORS.rst
-
3pos_order_mgmt/readme/DESCRIPTION.rst
-
5pos_order_mgmt/readme/ROADMAP.rst
-
19pos_order_mgmt/readme/USAGE.rst
-
BINpos_order_mgmt/static/description/icon.png
-
474pos_order_mgmt/static/description/index.html
-
BINpos_order_mgmt/static/description/order-mgmt-icon.png
-
BINpos_order_mgmt/static/description/order-mgmt-list.png
-
35pos_order_mgmt/static/src/css/pos.css
-
30pos_order_mgmt/static/src/js/models.js
-
464pos_order_mgmt/static/src/js/widgets.js
-
104pos_order_mgmt/static/src/xml/pos.xml
-
1pos_order_mgmt/tests/__init__.py
-
80pos_order_mgmt/tests/test_module.py
-
13pos_order_mgmt/views/assets.xml
-
63pos_order_mgmt/views/view_pos_config.xml
-
22pos_order_mgmt/views/view_pos_order.xml
-
2setup/_metapackage/VERSION.txt
-
1setup/_metapackage/setup.py
-
1setup/pos_order_mgmt/odoo/addons/pos_order_mgmt
-
6setup/pos_order_mgmt/setup.py
@ -0,0 +1,128 @@ |
|||||
|
============================== |
||||
|
POS Frontend Orders Management |
||||
|
============================== |
||||
|
|
||||
|
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||||
|
!! 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-OCA%2Fpos-lightgray.png?logo=github |
||||
|
:target: https://github.com/OCA/pos/tree/12.0/pos_order_mgmt |
||||
|
:alt: OCA/pos |
||||
|
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png |
||||
|
:target: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_order_mgmt |
||||
|
:alt: Translate me on Weblate |
||||
|
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png |
||||
|
:target: https://runbot.odoo-community.org/runbot/184/12.0 |
||||
|
:alt: Try me on Runbot |
||||
|
|
||||
|
|badge1| |badge2| |badge3| |badge4| |badge5| |
||||
|
|
||||
|
This module extends the functionality of the PoS frontend allowing to load |
||||
|
already done PoS Orders in order to be able to operate over them, being able to |
||||
|
reprint past tickets or return them. |
||||
|
|
||||
|
**Table of contents** |
||||
|
|
||||
|
.. contents:: |
||||
|
:local: |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
To configure this module, you need to: |
||||
|
|
||||
|
#. Go to *Point of Sale > Configuration > Point of Sale* and select one of |
||||
|
them. |
||||
|
#. Change *Max Done Orders Quantity To Load* to your desired amount (10 by |
||||
|
default). Please note that the more you load, the more it will take to load |
||||
|
them in the session opening. You can also set it to 0 and you'll just be |
||||
|
able to load them from the order list screen. |
||||
|
#. Set *Reprint Done Orders* on if you want to be able to reprint past orders |
||||
|
in that PoS. |
||||
|
#. Set *Return Done Orders* on if you want to be able to return past orders |
||||
|
in that PoS. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
Once the PoS is loaded, you'll find a shopping trolley icon (🛒) in the top |
||||
|
bar that grants access to the order list screen. |
||||
|
|
||||
|
.. image:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-icon.png |
||||
|
|
||||
|
There you can find the number of past orders loaded according to your |
||||
|
configuration (see Configuration) as well as the orders you checked out in |
||||
|
the current session: |
||||
|
|
||||
|
.. image:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-list.png |
||||
|
|
||||
|
#. You can see their totals as well as their custumers if registered. |
||||
|
#. You can reprint their tickets clicking on the printer icon (⎙). |
||||
|
#. You can return them pressing on the arrow icon (↶). |
||||
|
#. You have a search input as well that lets you find past tickets by its |
||||
|
reference number. |
||||
|
|
||||
|
NOTE: You'll need your PoS to be online to be able to search or return a past |
||||
|
ticket. |
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
* It's possible to return the same order over and over. To avoid so, we should |
||||
|
load and control if there's a returned line id associated with the original |
||||
|
order. That would be a great improvement for future revisions. |
||||
|
This feature is implemented in the module ``pos_order_return`` in the back |
||||
|
office part, but not in front office part (implemented in this this module). |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/pos/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 <https://github.com/OCA/pos/issues/new?body=module:%20pos_order_mgmt%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. |
||||
|
|
||||
|
Do not contact contributors directly about support or help with technical issues. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Authors |
||||
|
~~~~~~~ |
||||
|
|
||||
|
* GRAP |
||||
|
* Tecnativa |
||||
|
|
||||
|
Contributors |
||||
|
~~~~~~~~~~~~ |
||||
|
|
||||
|
* David Vidal <david.vidal@tecnativa.com> |
||||
|
* Sylvain LE GAL (https://twitter.com/legalsylvain) |
||||
|
* Carlos Martínez <carlos@domatix.com> |
||||
|
* Pierrick Brun <pierrick.brun@akretion.com> |
||||
|
* Iván Todorovich <ivan.todorovich@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 `OCA/pos <https://github.com/OCA/pos/tree/12.0/pos_order_mgmt>`_ project on GitHub. |
||||
|
|
||||
|
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
@ -0,0 +1 @@ |
|||||
|
from . import models |
@ -0,0 +1,28 @@ |
|||||
|
# Copyright 2018 GRAP - Sylvain LE GAL |
||||
|
# Copyright 2018 Tecnativa S.L. - David Vidal |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
{ |
||||
|
'name': 'POS Frontend Orders Management', |
||||
|
'summary': 'Manage old POS Orders from the frontend', |
||||
|
'version': '12.0.1.0.1', |
||||
|
'category': 'Point of Sale', |
||||
|
'author': 'GRAP, ' |
||||
|
'Tecnativa, ' |
||||
|
'Odoo Community Association (OCA)', |
||||
|
'website': 'https://github.com/OCA/pos', |
||||
|
'license': 'AGPL-3', |
||||
|
'depends': [ |
||||
|
'point_of_sale', |
||||
|
], |
||||
|
'data': [ |
||||
|
'views/assets.xml', |
||||
|
'views/view_pos_config.xml', |
||||
|
'views/view_pos_order.xml', |
||||
|
], |
||||
|
'qweb': [ |
||||
|
'static/src/xml/pos.xml' |
||||
|
], |
||||
|
'application': False, |
||||
|
'installable': True, |
||||
|
} |
@ -0,0 +1,172 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * pos_order_mgmt |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 11.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2018-10-18 11:15+0000\n" |
||||
|
"PO-Revision-Date: 2019-03-01 15:53+0000\n" |
||||
|
"Last-Translator: Marta Vázquez Rodríguez <vazrodmar@gmail.com>\n" |
||||
|
"Language-Team: \n" |
||||
|
"Language: es\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Plural-Forms: nplurals=2; plural=n != 1;\n" |
||||
|
"X-Generator: Weblate 3.4\n" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Allow to load done orders in this POS" |
||||
|
msgstr "Permitir cargar pedidos en este PdV" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config_iface_load_done_order |
||||
|
msgid "" |
||||
|
"Allows to load already done orders in the frontend to operate over them, " |
||||
|
"allowing reprint the tickets, return items, etc." |
||||
|
msgstr "" |
||||
|
"Permite cargar pedidos ya realizados desde el PdV para operar sobre ellos: " |
||||
|
"reimprimir tickes, devoluciónes, etc." |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:36 |
||||
|
#, python-format |
||||
|
msgid "Amount Total" |
||||
|
msgstr "Importe Total" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:17 |
||||
|
#, python-format |
||||
|
msgid "Back" |
||||
|
msgstr "Volver" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:303 |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:331 |
||||
|
#, python-format |
||||
|
msgid "Can not execute this action because the POS is currently offline" |
||||
|
msgstr "" |
||||
|
"No se puede ejecutar esta acción porque el PdV está sin línea en este momento" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:302 |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:330 |
||||
|
#, python-format |
||||
|
msgid "Connection error" |
||||
|
msgstr "Error de conexión" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:34 |
||||
|
#, python-format |
||||
|
msgid "Customer" |
||||
|
msgstr "Cliente" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:35 |
||||
|
#, python-format |
||||
|
msgid "Date" |
||||
|
msgstr "Fecha" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Load Done Order Max Qty." |
||||
|
msgstr "Nº Máximo de Ventas a Cargar." |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config_iface_load_done_order |
||||
|
#: model:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Load Done Orders" |
||||
|
msgstr "Cargar Ventas Realizadas" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config_iface_load_done_order_max_qty |
||||
|
msgid "Max. Done Orders Quantity To Load" |
||||
|
msgstr "Nº Máximo de Ventas Realizadas a Cargar" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config_iface_load_done_order_max_qty |
||||
|
msgid "" |
||||
|
"Maximum number of orders to load on the PoS at its init. Set it to 0 to load " |
||||
|
"none (it's still posible to load them by ticket code)." |
||||
|
msgstr "" |
||||
|
"Número máximo de ventas a cargar en el PdV cuando este se inicia. " |
||||
|
"Establézcalo a 0 para no cargar ninguna (es posible cargarlas por referencia " |
||||
|
"del ticket)." |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Maximum number orders to load" |
||||
|
msgstr "Ventas máximas a cargar" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model,name:pos_order_mgmt.model_pos_order |
||||
|
msgid "Point of Sale Orders" |
||||
|
msgstr "Ventas del Punto de Venta" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:80 |
||||
|
#, python-format |
||||
|
msgid "Rectifies:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:33 |
||||
|
#, python-format |
||||
|
msgid "Ref." |
||||
|
msgstr "'Ref.'" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:71 |
||||
|
#, python-format |
||||
|
msgid "Returned order:" |
||||
|
msgstr "Devolución de venta:" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:21 |
||||
|
#, python-format |
||||
|
msgid "Search Order" |
||||
|
msgstr "Buscar Venta" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:280 |
||||
|
#, python-format |
||||
|
msgid "" |
||||
|
"Unable to load some order lines because the products are not available in " |
||||
|
"the POS cache.\n" |
||||
|
"\n" |
||||
|
"Please check that lines :\n" |
||||
|
"\n" |
||||
|
" * " |
||||
|
msgstr "" |
||||
|
"No fue posible cargar algunas líneas porque los pedidos no están disponibles " |
||||
|
"en la caché del PdV.\n" |
||||
|
"\n" |
||||
|
"Por favor, compruebe estas líneas :\n" |
||||
|
"\n" |
||||
|
" * " |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:279 |
||||
|
#, python-format |
||||
|
msgid "Unknown Products" |
||||
|
msgstr "Productos desconocidos" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model,name:pos_order_mgmt.model_pos_config |
||||
|
msgid "pos.config" |
||||
|
msgstr "'pos.config'" |
@ -0,0 +1,249 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * pos_order_mgmt |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 12.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2019-07-15 20:54+0000\n" |
||||
|
"PO-Revision-Date: 2019-07-15 20:54+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_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Allow to duplicate done orders in this POS" |
||||
|
msgstr "Autoriser à dupliquer des commandes réalisées dans l'interface tactile" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Allow to reprint done orders in this POS" |
||||
|
msgstr "Autoriser à réimprimer des commandes réalisées dans l'interface tactile" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Allow to return done orders in this POS" |
||||
|
msgstr "Autoriser à rembourser des commandes réalisées dans l'interface tactile" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config__iface_copy_done_order |
||||
|
msgid "Allows to duplicate already done orders in the frontend" |
||||
|
msgstr "Autoriser à dupliquer des commandes réalisées dans l'interface tactile" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config__iface_reprint_done_order |
||||
|
msgid "Allows to reprint already done orders in the frontend" |
||||
|
msgstr "Autoriser à réimprimer des commandes réalisées dans l'interface tactile" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config__iface_return_done_order |
||||
|
msgid "Allows to return already done orders in the frontend" |
||||
|
msgstr "Autoriser à rembourser des commandes réalisées dans l'interface tactile" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:36 |
||||
|
#, python-format |
||||
|
msgid "Amount Total" |
||||
|
msgstr "Total" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:17 |
||||
|
#, python-format |
||||
|
msgid "Back" |
||||
|
msgstr "Retour" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:341 |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:396 |
||||
|
#, python-format |
||||
|
msgid "Can not execute this action because the POS is currently offline" |
||||
|
msgstr "Vous ne pouvez pas exécuter cette action, car le Point de Vente est actuellement hors ligne" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:340 |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:395 |
||||
|
#, python-format |
||||
|
msgid "Connection error" |
||||
|
msgstr "Erreur de connexion" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:61 |
||||
|
#, python-format |
||||
|
msgid "Create a new order based on this one" |
||||
|
msgstr "Créer une nouvelle commande basée sur celle-ci" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:64 |
||||
|
#, python-format |
||||
|
msgid "Create a refund order of this order" |
||||
|
msgstr "Rembourser cette commande" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:34 |
||||
|
#, python-format |
||||
|
msgid "Customer" |
||||
|
msgstr "Client" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:89 |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:98 |
||||
|
#, python-format |
||||
|
msgid "DUPLICATE" |
||||
|
msgstr "DUPLICATA" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:35 |
||||
|
#, python-format |
||||
|
msgid "Date" |
||||
|
msgstr "Date" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config__iface_copy_done_order |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Duplicate Done Orders" |
||||
|
msgstr "Copier une commande réalisées" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Load Done Order Max Qty." |
||||
|
msgstr "Quantité maximale de commandes à charger" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config__iface_load_done_order_max_qty |
||||
|
msgid "Max. Done Orders Quantity To Load" |
||||
|
msgstr "Quantité maximale de commandes à charger" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config__iface_load_done_order_max_qty |
||||
|
msgid "Maximum number of orders to load on the PoS at its init. Set it to 0 to load none (it's still possible to load them by ticket code)." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Maximum number orders to load" |
||||
|
msgstr "Nombre maximum de commande à charger" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model,name:pos_order_mgmt.model_pos_config |
||||
|
msgid "Point of Sale Configuration" |
||||
|
msgstr "Paramétrage du point de vente" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model,name:pos_order_mgmt.model_pos_order |
||||
|
msgid "Point of Sale Orders" |
||||
|
msgstr "Commandes du point de vente" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:58 |
||||
|
#, python-format |
||||
|
msgid "Print a duplicate for this order" |
||||
|
msgstr "Imprimer un duplicata de cette commande" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:83 |
||||
|
#, python-format |
||||
|
msgid "Rectifies:" |
||||
|
msgstr "Rectifie : " |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:33 |
||||
|
#, python-format |
||||
|
msgid "Ref." |
||||
|
msgstr "Réf." |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_order__returned_order_reference |
||||
|
msgid "Reference of the returned Order" |
||||
|
msgstr "Réference de la vente retournée" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:242 |
||||
|
#, python-format |
||||
|
msgid "Refund " |
||||
|
msgstr "Rembourse " |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_order__refund_order_ids |
||||
|
msgid "Refund Orders" |
||||
|
msgstr "Commandes remboursées" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_order__refund_order_qty |
||||
|
msgid "Refund Orders Quantity" |
||||
|
msgstr "Nombre de remboursement" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_order_form |
||||
|
msgid "Refunds" |
||||
|
msgstr "Remboursements" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config__iface_reprint_done_order |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Reprint Done Orders" |
||||
|
msgstr "Réimprimer le ticket d'une commande réalisée" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config__iface_return_done_order |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Return Done Orders" |
||||
|
msgstr "Retourner une commande réalisée" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_order__returned_order_id |
||||
|
msgid "Returned Order" |
||||
|
msgstr "Commande retournée" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:74 |
||||
|
#, python-format |
||||
|
msgid "Returned order:" |
||||
|
msgstr "Commande retournée:" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:21 |
||||
|
#, python-format |
||||
|
msgid "Search Order" |
||||
|
msgstr "Recherche une commande" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:358 |
||||
|
#, python-format |
||||
|
msgid "Unable to load some order lines because the products are not available in the POS cache.\n" |
||||
|
"\n" |
||||
|
"Please check that lines :\n" |
||||
|
"\n" |
||||
|
" * " |
||||
|
msgstr "Impossible de charger certaines lignes de ticket car les produits ne sont pas disponible dans le point de vente\n" |
||||
|
"Veuillez vérifier les lignes suivantes : \n" |
||||
|
"\n" |
||||
|
" * " |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:357 |
||||
|
#, python-format |
||||
|
msgid "Unknown Products" |
||||
|
msgstr "Produit inconnu" |
||||
|
|
@ -0,0 +1,244 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * pos_order_mgmt |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 12.0\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_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Allow to duplicate done orders in this POS" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Allow to reprint done orders in this POS" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Allow to return done orders in this POS" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config__iface_copy_done_order |
||||
|
msgid "Allows to duplicate already done orders in the frontend" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config__iface_reprint_done_order |
||||
|
msgid "Allows to reprint already done orders in the frontend" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config__iface_return_done_order |
||||
|
msgid "Allows to return already done orders in the frontend" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:36 |
||||
|
#, python-format |
||||
|
msgid "Amount Total" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:17 |
||||
|
#, python-format |
||||
|
msgid "Back" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:341 |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:396 |
||||
|
#, python-format |
||||
|
msgid "Can not execute this action because the POS is currently offline" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:340 |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:395 |
||||
|
#, python-format |
||||
|
msgid "Connection error" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:61 |
||||
|
#, python-format |
||||
|
msgid "Create a new order based on this one" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:64 |
||||
|
#, python-format |
||||
|
msgid "Create a refund order of this order" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:34 |
||||
|
#, python-format |
||||
|
msgid "Customer" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:89 |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:98 |
||||
|
#, python-format |
||||
|
msgid "DUPLICATE" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:35 |
||||
|
#, python-format |
||||
|
msgid "Date" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config__iface_copy_done_order |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Duplicate Done Orders" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Load Done Order Max Qty." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config__iface_load_done_order_max_qty |
||||
|
msgid "Max. Done Orders Quantity To Load" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,help:pos_order_mgmt.field_pos_config__iface_load_done_order_max_qty |
||||
|
msgid "Maximum number of orders to load on the PoS at its init. Set it to 0 to load none (it's still possible to load them by ticket code)." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Maximum number orders to load" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model,name:pos_order_mgmt.model_pos_config |
||||
|
msgid "Point of Sale Configuration" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model,name:pos_order_mgmt.model_pos_order |
||||
|
msgid "Point of Sale Orders" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:58 |
||||
|
#, python-format |
||||
|
msgid "Print a duplicate for this order" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:83 |
||||
|
#, python-format |
||||
|
msgid "Rectifies:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:33 |
||||
|
#, python-format |
||||
|
msgid "Ref." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_order__returned_order_reference |
||||
|
msgid "Reference of the returned Order" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:242 |
||||
|
#, python-format |
||||
|
msgid "Refund " |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_order__refund_order_ids |
||||
|
msgid "Refund Orders" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_order__refund_order_qty |
||||
|
msgid "Refund Orders Quantity" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_order_form |
||||
|
msgid "Refunds" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config__iface_reprint_done_order |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Reprint Done Orders" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config__iface_return_done_order |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form |
||||
|
msgid "Return Done Orders" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_order__returned_order_id |
||||
|
msgid "Returned Order" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:74 |
||||
|
#, python-format |
||||
|
msgid "Returned order:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:21 |
||||
|
#, python-format |
||||
|
msgid "Search Order" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:358 |
||||
|
#, python-format |
||||
|
msgid "Unable to load some order lines because the products are not available in the POS cache.\n" |
||||
|
"\n" |
||||
|
"Please check that lines :\n" |
||||
|
"\n" |
||||
|
" * " |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: pos_order_mgmt |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:357 |
||||
|
#, python-format |
||||
|
msgid "Unknown Products" |
||||
|
msgstr "" |
||||
|
|
@ -0,0 +1,2 @@ |
|||||
|
from . import pos_config |
||||
|
from . import pos_order |
@ -0,0 +1,38 @@ |
|||||
|
# Copyright 2018 GRAP - Sylvain LE GAL |
||||
|
# Copyright 2018 Tecnativa S.L. - David Vidal |
||||
|
# Copyright 2019 Coop IT Easy SCRLfs |
||||
|
# Pierrick Brun <pierrick.brun@akretion.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class PosConfig(models.Model): |
||||
|
_inherit = 'pos.config' |
||||
|
|
||||
|
iface_reprint_done_order = fields.Boolean( |
||||
|
string='Reprint Done Orders', |
||||
|
default=True, |
||||
|
help='Allows to reprint already done orders in the frontend', |
||||
|
) |
||||
|
|
||||
|
iface_return_done_order = fields.Boolean( |
||||
|
string='Return Done Orders', |
||||
|
default=True, |
||||
|
help='Allows to return already done orders in the frontend', |
||||
|
) |
||||
|
|
||||
|
iface_copy_done_order = fields.Boolean( |
||||
|
string='Duplicate Done Orders', |
||||
|
default=True, |
||||
|
help='Allows to duplicate already done orders in the frontend', |
||||
|
) |
||||
|
|
||||
|
iface_load_done_order_max_qty = fields.Integer( |
||||
|
string='Max. Done Orders Quantity To Load', |
||||
|
default=10, |
||||
|
required=True, |
||||
|
help='Maximum number of orders to load on the PoS at its init. ' |
||||
|
'Set it to 0 to load none (it\'s still possible to load them by ' |
||||
|
'ticket code).', |
||||
|
) |
@ -0,0 +1,160 @@ |
|||||
|
# Copyright 2018 GRAP - Sylvain LE GAL |
||||
|
# Copyright 2018 Tecnativa S.L. - David Vidal |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import api, models, fields |
||||
|
|
||||
|
|
||||
|
class PosOrder(models.Model): |
||||
|
_inherit = 'pos.order' |
||||
|
|
||||
|
returned_order_id = fields.Many2one( |
||||
|
comodel_name='pos.order', |
||||
|
string='Returned Order', |
||||
|
readonly=True, |
||||
|
) |
||||
|
|
||||
|
returned_order_reference = fields.Char( |
||||
|
related='returned_order_id.pos_reference', |
||||
|
string='Reference of the returned Order') |
||||
|
|
||||
|
refund_order_ids = fields.One2many( |
||||
|
comodel_name='pos.order', |
||||
|
inverse_name='returned_order_id', |
||||
|
string='Refund Orders', |
||||
|
readonly=True, |
||||
|
) |
||||
|
|
||||
|
refund_order_qty = fields.Integer( |
||||
|
compute='_compute_refund_order_qty', |
||||
|
string='Refund Orders Quantity', |
||||
|
) |
||||
|
|
||||
|
@api.multi |
||||
|
@api.depends('refund_order_ids') |
||||
|
def _compute_refund_order_qty(self): |
||||
|
for order in self: |
||||
|
order.refund_order_qty = len(order.refund_order_ids) |
||||
|
|
||||
|
@api.multi |
||||
|
def action_view_refund_orders(self): |
||||
|
self.ensure_one() |
||||
|
|
||||
|
action = self.env.ref('point_of_sale.action_pos_pos_form').read()[0] |
||||
|
|
||||
|
if self.refund_order_qty == 1: |
||||
|
action['views'] = [ |
||||
|
(self.env.ref('point_of_sale.view_pos_pos_form').id, 'form')] |
||||
|
action['res_id'] = self.refund_order_ids.ids[0] |
||||
|
else: |
||||
|
action['domain'] = [('id', 'in', self.refund_order_ids.ids)] |
||||
|
return action |
||||
|
|
||||
|
@api.multi |
||||
|
def refund(self): |
||||
|
return super(PosOrder, self.with_context(refund=True)).refund() |
||||
|
|
||||
|
@api.multi |
||||
|
@api.returns('self', lambda value: value.id) |
||||
|
def copy(self, default=None): |
||||
|
self.ensure_one() |
||||
|
order = super().copy(default=default) |
||||
|
if self.env.context.get('refund', False): |
||||
|
order.returned_order_id = self.id |
||||
|
return order |
||||
|
|
||||
|
@api.model |
||||
|
def _prepare_filter_for_pos(self, pos_session_id): |
||||
|
return [ |
||||
|
('state', 'in', ['paid', 'done', 'invoiced']), |
||||
|
] |
||||
|
|
||||
|
@api.model |
||||
|
def _prepare_filter_query_for_pos(self, pos_session_id, query): |
||||
|
return [ |
||||
|
'|', '|', |
||||
|
('name', 'ilike', query), |
||||
|
('pos_reference', 'ilike', query), |
||||
|
('partner_id.display_name', 'ilike', query), |
||||
|
] |
||||
|
|
||||
|
@api.model |
||||
|
def _prepare_fields_for_pos_list(self): |
||||
|
return [ |
||||
|
'name', 'pos_reference', 'partner_id', 'date_order', |
||||
|
'amount_total', |
||||
|
] |
||||
|
|
||||
|
@api.model |
||||
|
def search_done_orders_for_pos(self, query, pos_session_id): |
||||
|
session_obj = self.env['pos.session'] |
||||
|
config = session_obj.browse(pos_session_id).config_id |
||||
|
condition = self._prepare_filter_for_pos(pos_session_id) |
||||
|
if not query: |
||||
|
# Search only this POS orders |
||||
|
condition += [('config_id', '=', config.id)] |
||||
|
else: |
||||
|
# Search globally by criteria |
||||
|
condition += self._prepare_filter_query_for_pos( |
||||
|
pos_session_id, query) |
||||
|
field_names = self._prepare_fields_for_pos_list() |
||||
|
return self.search_read( |
||||
|
condition, field_names, limit=config.iface_load_done_order_max_qty) |
||||
|
|
||||
|
@api.multi |
||||
|
def _prepare_done_order_for_pos(self): |
||||
|
self.ensure_one() |
||||
|
order_lines = [] |
||||
|
payment_lines = [] |
||||
|
for order_line in self.lines: |
||||
|
order_line = self._prepare_done_order_line_for_pos(order_line) |
||||
|
order_lines.append(order_line) |
||||
|
for payment_line in self.statement_ids: |
||||
|
payment_line = self._prepare_done_order_payment_for_pos( |
||||
|
payment_line) |
||||
|
payment_lines.append(payment_line) |
||||
|
res = { |
||||
|
'id': self.id, |
||||
|
'date_order': self.date_order, |
||||
|
'pos_reference': self.pos_reference, |
||||
|
'name': self.name, |
||||
|
'partner_id': self.partner_id.id, |
||||
|
'fiscal_position': self.fiscal_position_id.id, |
||||
|
'line_ids': order_lines, |
||||
|
'statement_ids': payment_lines, |
||||
|
'to_invoice': bool(self.invoice_id), |
||||
|
'returned_order_id': self.returned_order_id.id, |
||||
|
'returned_order_reference': self.returned_order_reference, |
||||
|
} |
||||
|
return res |
||||
|
|
||||
|
@api.multi |
||||
|
def _prepare_done_order_line_for_pos(self, order_line): |
||||
|
self.ensure_one() |
||||
|
return { |
||||
|
'product_id': order_line.product_id.id, |
||||
|
'qty': order_line.qty, |
||||
|
'price_unit': order_line.price_unit, |
||||
|
'discount': order_line.discount, |
||||
|
} |
||||
|
|
||||
|
@api.multi |
||||
|
def _prepare_done_order_payment_for_pos(self, payment_line): |
||||
|
self.ensure_one() |
||||
|
return { |
||||
|
'journal_id': payment_line.journal_id.id, |
||||
|
'amount': payment_line.amount, |
||||
|
} |
||||
|
|
||||
|
@api.multi |
||||
|
def load_done_order_for_pos(self): |
||||
|
self.ensure_one() |
||||
|
return self._prepare_done_order_for_pos() |
||||
|
|
||||
|
@api.model |
||||
|
def _order_fields(self, ui_order): |
||||
|
res = super()._order_fields(ui_order) |
||||
|
res.update({ |
||||
|
'returned_order_id': ui_order.get('returned_order_id', False), |
||||
|
}) |
||||
|
return res |
@ -0,0 +1,12 @@ |
|||||
|
To configure this module, you need to: |
||||
|
|
||||
|
#. Go to *Point of Sale > Configuration > Point of Sale* and select one of |
||||
|
them. |
||||
|
#. Change *Max Done Orders Quantity To Load* to your desired amount (10 by |
||||
|
default). Please note that the more you load, the more it will take to load |
||||
|
them in the session opening. You can also set it to 0 and you'll just be |
||||
|
able to load them from the order list screen. |
||||
|
#. Set *Reprint Done Orders* on if you want to be able to reprint past orders |
||||
|
in that PoS. |
||||
|
#. Set *Return Done Orders* on if you want to be able to return past orders |
||||
|
in that PoS. |
@ -0,0 +1,5 @@ |
|||||
|
* David Vidal <david.vidal@tecnativa.com> |
||||
|
* Sylvain LE GAL (https://twitter.com/legalsylvain) |
||||
|
* Carlos Martínez <carlos@domatix.com> |
||||
|
* Pierrick Brun <pierrick.brun@akretion.com> |
||||
|
* Iván Todorovich <ivan.todorovich@druidoo.io> |
@ -0,0 +1,3 @@ |
|||||
|
This module extends the functionality of the PoS frontend allowing to load |
||||
|
already done PoS Orders in order to be able to operate over them, being able to |
||||
|
reprint past tickets or return them. |
@ -0,0 +1,5 @@ |
|||||
|
* It's possible to return the same order over and over. To avoid so, we should |
||||
|
load and control if there's a returned line id associated with the original |
||||
|
order. That would be a great improvement for future revisions. |
||||
|
This feature is implemented in the module ``pos_order_return`` in the back |
||||
|
office part, but not in front office part (implemented in this this module). |
@ -0,0 +1,19 @@ |
|||||
|
Once the PoS is loaded, you'll find a shopping trolley icon (🛒) in the top |
||||
|
bar that grants access to the order list screen. |
||||
|
|
||||
|
.. image:: ../static/description/order-mgmt-icon.png |
||||
|
|
||||
|
There you can find the number of past orders loaded according to your |
||||
|
configuration (see Configuration) as well as the orders you checked out in |
||||
|
the current session: |
||||
|
|
||||
|
.. image:: ../static/description/order-mgmt-list.png |
||||
|
|
||||
|
#. You can see their totals as well as their custumers if registered. |
||||
|
#. You can reprint their tickets clicking on the printer icon (⎙). |
||||
|
#. You can return them pressing on the arrow icon (↶). |
||||
|
#. You have a search input as well that lets you find past tickets by its |
||||
|
reference number. |
||||
|
|
||||
|
NOTE: You'll need your PoS to be online to be able to search or return a past |
||||
|
ticket. |
After Width: 560 | Height: 560 | Size: 15 KiB |
@ -0,0 +1,474 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
||||
|
<head> |
||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
||||
|
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" /> |
||||
|
<title>POS Frontend Orders Management</title> |
||||
|
<style type="text/css"> |
||||
|
|
||||
|
/* |
||||
|
:Author: David Goodger (goodger@python.org) |
||||
|
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ |
||||
|
:Copyright: This stylesheet has been placed in the public domain. |
||||
|
|
||||
|
Default cascading style sheet for the HTML output of Docutils. |
||||
|
|
||||
|
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to |
||||
|
customize this style sheet. |
||||
|
*/ |
||||
|
|
||||
|
/* used to remove borders from tables and images */ |
||||
|
.borderless, table.borderless td, table.borderless th { |
||||
|
border: 0 } |
||||
|
|
||||
|
table.borderless td, table.borderless th { |
||||
|
/* Override padding for "table.docutils td" with "! important". |
||||
|
The right padding separates the table cells. */ |
||||
|
padding: 0 0.5em 0 0 ! important } |
||||
|
|
||||
|
.first { |
||||
|
/* Override more specific margin styles with "! important". */ |
||||
|
margin-top: 0 ! important } |
||||
|
|
||||
|
.last, .with-subtitle { |
||||
|
margin-bottom: 0 ! important } |
||||
|
|
||||
|
.hidden { |
||||
|
display: none } |
||||
|
|
||||
|
.subscript { |
||||
|
vertical-align: sub; |
||||
|
font-size: smaller } |
||||
|
|
||||
|
.superscript { |
||||
|
vertical-align: super; |
||||
|
font-size: smaller } |
||||
|
|
||||
|
a.toc-backref { |
||||
|
text-decoration: none ; |
||||
|
color: black } |
||||
|
|
||||
|
blockquote.epigraph { |
||||
|
margin: 2em 5em ; } |
||||
|
|
||||
|
dl.docutils dd { |
||||
|
margin-bottom: 0.5em } |
||||
|
|
||||
|
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
/* Uncomment (and remove this text!) to get bold-faced definition list terms |
||||
|
dl.docutils dt { |
||||
|
font-weight: bold } |
||||
|
*/ |
||||
|
|
||||
|
div.abstract { |
||||
|
margin: 2em 5em } |
||||
|
|
||||
|
div.abstract p.topic-title { |
||||
|
font-weight: bold ; |
||||
|
text-align: center } |
||||
|
|
||||
|
div.admonition, div.attention, div.caution, div.danger, div.error, |
||||
|
div.hint, div.important, div.note, div.tip, div.warning { |
||||
|
margin: 2em ; |
||||
|
border: medium outset ; |
||||
|
padding: 1em } |
||||
|
|
||||
|
div.admonition p.admonition-title, div.hint p.admonition-title, |
||||
|
div.important p.admonition-title, div.note p.admonition-title, |
||||
|
div.tip p.admonition-title { |
||||
|
font-weight: bold ; |
||||
|
font-family: sans-serif } |
||||
|
|
||||
|
div.attention p.admonition-title, div.caution p.admonition-title, |
||||
|
div.danger p.admonition-title, div.error p.admonition-title, |
||||
|
div.warning p.admonition-title, .code .error { |
||||
|
color: red ; |
||||
|
font-weight: bold ; |
||||
|
font-family: sans-serif } |
||||
|
|
||||
|
/* Uncomment (and remove this text!) to get reduced vertical space in |
||||
|
compound paragraphs. |
||||
|
div.compound .compound-first, div.compound .compound-middle { |
||||
|
margin-bottom: 0.5em } |
||||
|
|
||||
|
div.compound .compound-last, div.compound .compound-middle { |
||||
|
margin-top: 0.5em } |
||||
|
*/ |
||||
|
|
||||
|
div.dedication { |
||||
|
margin: 2em 5em ; |
||||
|
text-align: center ; |
||||
|
font-style: italic } |
||||
|
|
||||
|
div.dedication p.topic-title { |
||||
|
font-weight: bold ; |
||||
|
font-style: normal } |
||||
|
|
||||
|
div.figure { |
||||
|
margin-left: 2em ; |
||||
|
margin-right: 2em } |
||||
|
|
||||
|
div.footer, div.header { |
||||
|
clear: both; |
||||
|
font-size: smaller } |
||||
|
|
||||
|
div.line-block { |
||||
|
display: block ; |
||||
|
margin-top: 1em ; |
||||
|
margin-bottom: 1em } |
||||
|
|
||||
|
div.line-block div.line-block { |
||||
|
margin-top: 0 ; |
||||
|
margin-bottom: 0 ; |
||||
|
margin-left: 1.5em } |
||||
|
|
||||
|
div.sidebar { |
||||
|
margin: 0 0 0.5em 1em ; |
||||
|
border: medium outset ; |
||||
|
padding: 1em ; |
||||
|
background-color: #ffffee ; |
||||
|
width: 40% ; |
||||
|
float: right ; |
||||
|
clear: right } |
||||
|
|
||||
|
div.sidebar p.rubric { |
||||
|
font-family: sans-serif ; |
||||
|
font-size: medium } |
||||
|
|
||||
|
div.system-messages { |
||||
|
margin: 5em } |
||||
|
|
||||
|
div.system-messages h1 { |
||||
|
color: red } |
||||
|
|
||||
|
div.system-message { |
||||
|
border: medium outset ; |
||||
|
padding: 1em } |
||||
|
|
||||
|
div.system-message p.system-message-title { |
||||
|
color: red ; |
||||
|
font-weight: bold } |
||||
|
|
||||
|
div.topic { |
||||
|
margin: 2em } |
||||
|
|
||||
|
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, |
||||
|
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { |
||||
|
margin-top: 0.4em } |
||||
|
|
||||
|
h1.title { |
||||
|
text-align: center } |
||||
|
|
||||
|
h2.subtitle { |
||||
|
text-align: center } |
||||
|
|
||||
|
hr.docutils { |
||||
|
width: 75% } |
||||
|
|
||||
|
img.align-left, .figure.align-left, object.align-left, table.align-left { |
||||
|
clear: left ; |
||||
|
float: left ; |
||||
|
margin-right: 1em } |
||||
|
|
||||
|
img.align-right, .figure.align-right, object.align-right, table.align-right { |
||||
|
clear: right ; |
||||
|
float: right ; |
||||
|
margin-left: 1em } |
||||
|
|
||||
|
img.align-center, .figure.align-center, object.align-center { |
||||
|
display: block; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
} |
||||
|
|
||||
|
table.align-center { |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
} |
||||
|
|
||||
|
.align-left { |
||||
|
text-align: left } |
||||
|
|
||||
|
.align-center { |
||||
|
clear: both ; |
||||
|
text-align: center } |
||||
|
|
||||
|
.align-right { |
||||
|
text-align: right } |
||||
|
|
||||
|
/* reset inner alignment in figures */ |
||||
|
div.align-right { |
||||
|
text-align: inherit } |
||||
|
|
||||
|
/* div.align-center * { */ |
||||
|
/* text-align: left } */ |
||||
|
|
||||
|
.align-top { |
||||
|
vertical-align: top } |
||||
|
|
||||
|
.align-middle { |
||||
|
vertical-align: middle } |
||||
|
|
||||
|
.align-bottom { |
||||
|
vertical-align: bottom } |
||||
|
|
||||
|
ol.simple, ul.simple { |
||||
|
margin-bottom: 1em } |
||||
|
|
||||
|
ol.arabic { |
||||
|
list-style: decimal } |
||||
|
|
||||
|
ol.loweralpha { |
||||
|
list-style: lower-alpha } |
||||
|
|
||||
|
ol.upperalpha { |
||||
|
list-style: upper-alpha } |
||||
|
|
||||
|
ol.lowerroman { |
||||
|
list-style: lower-roman } |
||||
|
|
||||
|
ol.upperroman { |
||||
|
list-style: upper-roman } |
||||
|
|
||||
|
p.attribution { |
||||
|
text-align: right ; |
||||
|
margin-left: 50% } |
||||
|
|
||||
|
p.caption { |
||||
|
font-style: italic } |
||||
|
|
||||
|
p.credits { |
||||
|
font-style: italic ; |
||||
|
font-size: smaller } |
||||
|
|
||||
|
p.label { |
||||
|
white-space: nowrap } |
||||
|
|
||||
|
p.rubric { |
||||
|
font-weight: bold ; |
||||
|
font-size: larger ; |
||||
|
color: maroon ; |
||||
|
text-align: center } |
||||
|
|
||||
|
p.sidebar-title { |
||||
|
font-family: sans-serif ; |
||||
|
font-weight: bold ; |
||||
|
font-size: larger } |
||||
|
|
||||
|
p.sidebar-subtitle { |
||||
|
font-family: sans-serif ; |
||||
|
font-weight: bold } |
||||
|
|
||||
|
p.topic-title { |
||||
|
font-weight: bold } |
||||
|
|
||||
|
pre.address { |
||||
|
margin-bottom: 0 ; |
||||
|
margin-top: 0 ; |
||||
|
font: inherit } |
||||
|
|
||||
|
pre.literal-block, pre.doctest-block, pre.math, pre.code { |
||||
|
margin-left: 2em ; |
||||
|
margin-right: 2em } |
||||
|
|
||||
|
pre.code .ln { color: grey; } /* line numbers */ |
||||
|
pre.code, code { background-color: #eeeeee } |
||||
|
pre.code .comment, code .comment { color: #5C6576 } |
||||
|
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } |
||||
|
pre.code .literal.string, code .literal.string { color: #0C5404 } |
||||
|
pre.code .name.builtin, code .name.builtin { color: #352B84 } |
||||
|
pre.code .deleted, code .deleted { background-color: #DEB0A1} |
||||
|
pre.code .inserted, code .inserted { background-color: #A3D289} |
||||
|
|
||||
|
span.classifier { |
||||
|
font-family: sans-serif ; |
||||
|
font-style: oblique } |
||||
|
|
||||
|
span.classifier-delimiter { |
||||
|
font-family: sans-serif ; |
||||
|
font-weight: bold } |
||||
|
|
||||
|
span.interpreted { |
||||
|
font-family: sans-serif } |
||||
|
|
||||
|
span.option { |
||||
|
white-space: nowrap } |
||||
|
|
||||
|
span.pre { |
||||
|
white-space: pre } |
||||
|
|
||||
|
span.problematic { |
||||
|
color: red } |
||||
|
|
||||
|
span.section-subtitle { |
||||
|
/* font-size relative to parent (h1..h6 element) */ |
||||
|
font-size: 80% } |
||||
|
|
||||
|
table.citation { |
||||
|
border-left: solid 1px gray; |
||||
|
margin-left: 1px } |
||||
|
|
||||
|
table.docinfo { |
||||
|
margin: 2em 4em } |
||||
|
|
||||
|
table.docutils { |
||||
|
margin-top: 0.5em ; |
||||
|
margin-bottom: 0.5em } |
||||
|
|
||||
|
table.footnote { |
||||
|
border-left: solid 1px black; |
||||
|
margin-left: 1px } |
||||
|
|
||||
|
table.docutils td, table.docutils th, |
||||
|
table.docinfo td, table.docinfo th { |
||||
|
padding-left: 0.5em ; |
||||
|
padding-right: 0.5em ; |
||||
|
vertical-align: top } |
||||
|
|
||||
|
table.docutils th.field-name, table.docinfo th.docinfo-name { |
||||
|
font-weight: bold ; |
||||
|
text-align: left ; |
||||
|
white-space: nowrap ; |
||||
|
padding-left: 0 } |
||||
|
|
||||
|
/* "booktabs" style (no vertical lines) */ |
||||
|
table.docutils.booktabs { |
||||
|
border: 0px; |
||||
|
border-top: 2px solid; |
||||
|
border-bottom: 2px solid; |
||||
|
border-collapse: collapse; |
||||
|
} |
||||
|
table.docutils.booktabs * { |
||||
|
border: 0px; |
||||
|
} |
||||
|
table.docutils.booktabs th { |
||||
|
border-bottom: thin solid; |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, |
||||
|
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { |
||||
|
font-size: 100% } |
||||
|
|
||||
|
ul.auto-toc { |
||||
|
list-style-type: none } |
||||
|
|
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div class="document" id="pos-frontend-orders-management"> |
||||
|
<h1 class="title">POS Frontend Orders Management</h1> |
||||
|
|
||||
|
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||||
|
!! This file is generated by oca-gen-addon-readme !! |
||||
|
!! changes will be overwritten. !! |
||||
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> |
||||
|
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/pos/tree/12.0/pos_order_mgmt"><img alt="OCA/pos" src="https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_order_mgmt"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/184/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> |
||||
|
<p>This module extends the functionality of the PoS frontend allowing to load |
||||
|
already done PoS Orders in order to be able to operate over them, being able to |
||||
|
reprint past tickets or return them.</p> |
||||
|
<p><strong>Table of contents</strong></p> |
||||
|
<div class="contents local topic" id="contents"> |
||||
|
<ul class="simple"> |
||||
|
<li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li> |
||||
|
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li> |
||||
|
<li><a class="reference internal" href="#known-issues-roadmap" id="id3">Known issues / Roadmap</a></li> |
||||
|
<li><a class="reference internal" href="#bug-tracker" id="id4">Bug Tracker</a></li> |
||||
|
<li><a class="reference internal" href="#credits" id="id5">Credits</a><ul> |
||||
|
<li><a class="reference internal" href="#authors" id="id6">Authors</a></li> |
||||
|
<li><a class="reference internal" href="#contributors" id="id7">Contributors</a></li> |
||||
|
<li><a class="reference internal" href="#maintainers" id="id8">Maintainers</a></li> |
||||
|
</ul> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="configuration"> |
||||
|
<h1><a class="toc-backref" href="#id1">Configuration</a></h1> |
||||
|
<p>To configure this module, you need to:</p> |
||||
|
<ol class="arabic simple"> |
||||
|
<li>Go to <em>Point of Sale > Configuration > Point of Sale</em> and select one of |
||||
|
them.</li> |
||||
|
<li>Change <em>Max Done Orders Quantity To Load</em> to your desired amount (10 by |
||||
|
default). Please note that the more you load, the more it will take to load |
||||
|
them in the session opening. You can also set it to 0 and you’ll just be |
||||
|
able to load them from the order list screen.</li> |
||||
|
<li>Set <em>Reprint Done Orders</em> on if you want to be able to reprint past orders |
||||
|
in that PoS.</li> |
||||
|
<li>Set <em>Return Done Orders</em> on if you want to be able to return past orders |
||||
|
in that PoS.</li> |
||||
|
</ol> |
||||
|
</div> |
||||
|
<div class="section" id="usage"> |
||||
|
<h1><a class="toc-backref" href="#id2">Usage</a></h1> |
||||
|
<p>Once the PoS is loaded, you’ll find a shopping trolley icon (🛒) in the top |
||||
|
bar that grants access to the order list screen.</p> |
||||
|
<img alt="https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-icon.png" src="https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-icon.png" /> |
||||
|
<p>There you can find the number of past orders loaded according to your |
||||
|
configuration (see Configuration) as well as the orders you checked out in |
||||
|
the current session:</p> |
||||
|
<img alt="https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-list.png" src="https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-list.png" /> |
||||
|
<ol class="arabic simple"> |
||||
|
<li>You can see their totals as well as their custumers if registered.</li> |
||||
|
<li>You can reprint their tickets clicking on the printer icon (⎙).</li> |
||||
|
<li>You can return them pressing on the arrow icon (↶).</li> |
||||
|
<li>You have a search input as well that lets you find past tickets by its |
||||
|
reference number.</li> |
||||
|
</ol> |
||||
|
<p>NOTE: You’ll need your PoS to be online to be able to search or return a past |
||||
|
ticket.</p> |
||||
|
</div> |
||||
|
<div class="section" id="known-issues-roadmap"> |
||||
|
<h1><a class="toc-backref" href="#id3">Known issues / Roadmap</a></h1> |
||||
|
<ul class="simple"> |
||||
|
<li>It’s possible to return the same order over and over. To avoid so, we should |
||||
|
load and control if there’s a returned line id associated with the original |
||||
|
order. That would be a great improvement for future revisions. |
||||
|
This feature is implemented in the module <tt class="docutils literal">pos_order_return</tt> in the back |
||||
|
office part, but not in front office part (implemented in this this module).</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="bug-tracker"> |
||||
|
<h1><a class="toc-backref" href="#id4">Bug Tracker</a></h1> |
||||
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/pos/issues">GitHub Issues</a>. |
||||
|
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 |
||||
|
<a class="reference external" href="https://github.com/OCA/pos/issues/new?body=module:%20pos_order_mgmt%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> |
||||
|
<p>Do not contact contributors directly about support or help with technical issues.</p> |
||||
|
</div> |
||||
|
<div class="section" id="credits"> |
||||
|
<h1><a class="toc-backref" href="#id5">Credits</a></h1> |
||||
|
<div class="section" id="authors"> |
||||
|
<h2><a class="toc-backref" href="#id6">Authors</a></h2> |
||||
|
<ul class="simple"> |
||||
|
<li>GRAP</li> |
||||
|
<li>Tecnativa</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="contributors"> |
||||
|
<h2><a class="toc-backref" href="#id7">Contributors</a></h2> |
||||
|
<ul class="simple"> |
||||
|
<li>David Vidal <<a class="reference external" href="mailto:david.vidal@tecnativa.com">david.vidal@tecnativa.com</a>></li> |
||||
|
<li>Sylvain LE GAL (<a class="reference external" href="https://twitter.com/legalsylvain">https://twitter.com/legalsylvain</a>)</li> |
||||
|
<li>Carlos Martínez <<a class="reference external" href="mailto:carlos@domatix.com">carlos@domatix.com</a>></li> |
||||
|
<li>Pierrick Brun <<a class="reference external" href="mailto:pierrick.brun@akretion.com">pierrick.brun@akretion.com</a>></li> |
||||
|
<li>Iván Todorovich <<a class="reference external" href="mailto:ivan.todorovich@druidoo.io">ivan.todorovich@druidoo.io</a>></li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="section" id="maintainers"> |
||||
|
<h2><a class="toc-backref" href="#id8">Maintainers</a></h2> |
||||
|
<p>This module is maintained by the OCA.</p> |
||||
|
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> |
||||
|
<p>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.</p> |
||||
|
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/pos/tree/12.0/pos_order_mgmt">OCA/pos</a> project on GitHub.</p> |
||||
|
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</body> |
||||
|
</html> |
After Width: 678 | Height: 271 | Size: 26 KiB |
After Width: 825 | Height: 279 | Size: 38 KiB |
@ -0,0 +1,35 @@ |
|||||
|
/* Copyright 2018 Tecnativa - David Vidal |
||||
|
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). |
||||
|
*/ |
||||
|
|
||||
|
.order-list-button { |
||||
|
font-size: 20px; |
||||
|
} |
||||
|
|
||||
|
.order-line .button { |
||||
|
cursor: pointer; |
||||
|
top: 0px; |
||||
|
line-height: 32px; |
||||
|
padding: 3px 13px; |
||||
|
font-size: 20px; |
||||
|
background: rgb(230, 230, 230); |
||||
|
margin-left: 12px; |
||||
|
border-radius: 3px; |
||||
|
border: solid 1px rgb(209, 209, 209); |
||||
|
transition: all 150ms linear; |
||||
|
} |
||||
|
|
||||
|
.order-line .button:active { |
||||
|
background: black; |
||||
|
border-color: black; |
||||
|
color: white; |
||||
|
} |
||||
|
|
||||
|
.order-returned-warning { |
||||
|
font-size: 16px; |
||||
|
font-style: italic; |
||||
|
padding: 8px 0; |
||||
|
background-color: rgb(239, 153, 65); |
||||
|
color: white; |
||||
|
text-align: center; |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
/* Copyright 2018 Tecnativa - David Vidal |
||||
|
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). */
|
||||
|
|
||||
|
odoo.define('pos_order_mgmt.models', function (require) { |
||||
|
'use strict'; |
||||
|
|
||||
|
var models = require('point_of_sale.models'); |
||||
|
|
||||
|
var order_super = models.Order.prototype; |
||||
|
|
||||
|
models.Order = models.Order.extend({ |
||||
|
init_from_JSON: function (json) { |
||||
|
order_super.init_from_JSON.apply(this, arguments); |
||||
|
this.returned_order_id = json.returned_order_id; |
||||
|
this.returned_order_reference = json.returned_order_reference; |
||||
|
}, |
||||
|
export_as_JSON: function () { |
||||
|
var res = order_super.export_as_JSON.apply(this, arguments); |
||||
|
res.returned_order_id = this.returned_order_id; |
||||
|
res.returned_order_reference = this.returned_order_reference; |
||||
|
return res; |
||||
|
}, |
||||
|
export_for_printing: function () { |
||||
|
var res = order_super.export_for_printing.apply(this, arguments); |
||||
|
res.returned_order_id = this.returned_order_id; |
||||
|
res.returned_order_reference = this.returned_order_reference; |
||||
|
return res; |
||||
|
}, |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,464 @@ |
|||||
|
/* Copyright 2018 GRAP - Sylvain LE GAL |
||||
|
Copyright 2018 Tecnativa - David Vidal |
||||
|
Copyright 2019 Druidoo - Ivan Todorovich |
||||
|
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). */
|
||||
|
odoo.define('pos_order_mgmt.widgets', function (require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var core = require('web.core'); |
||||
|
var _t = core._t; |
||||
|
var PosBaseWidget = require('point_of_sale.BaseWidget'); |
||||
|
var screens = require('point_of_sale.screens'); |
||||
|
var gui = require('point_of_sale.gui'); |
||||
|
var chrome = require('point_of_sale.chrome'); |
||||
|
var pos = require('point_of_sale.models'); |
||||
|
|
||||
|
var QWeb = core.qweb; |
||||
|
var ScreenWidget = screens.ScreenWidget; |
||||
|
var DomCache = screens.DomCache; |
||||
|
|
||||
|
screens.ReceiptScreenWidget.include({ |
||||
|
render_receipt: function () { |
||||
|
if (!this.pos.reloaded_order) { |
||||
|
return this._super(); |
||||
|
} |
||||
|
var order = this.pos.reloaded_order; |
||||
|
this.$('.pos-receipt-container').html(QWeb.render('PosTicket', { |
||||
|
widget: this, |
||||
|
pos: this.pos, |
||||
|
order: order, |
||||
|
receipt: order.export_for_printing(), |
||||
|
orderlines: order.get_orderlines(), |
||||
|
paymentlines: order.get_paymentlines(), |
||||
|
})); |
||||
|
this.pos.from_loaded_order = true; |
||||
|
}, |
||||
|
click_next: function () { |
||||
|
if (!this.pos.from_loaded_order) { |
||||
|
return this._super(); |
||||
|
} |
||||
|
this.pos.from_loaded_order = false; |
||||
|
// When reprinting a loaded order we temporarily set it as the
|
||||
|
// active one. When we get out from the printing screen, we set
|
||||
|
// it back to the one that was active
|
||||
|
if (this.pos.current_order) { |
||||
|
this.pos.set_order(this.pos.current_order); |
||||
|
this.pos.current_order = false; |
||||
|
} |
||||
|
return this.gui.show_screen(this.gui.startup_screen); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
var OrderListScreenWidget = ScreenWidget.extend({ |
||||
|
template: 'OrderListScreenWidget', |
||||
|
|
||||
|
init: function (parent, options) { |
||||
|
this._super(parent, options); |
||||
|
this.order_cache = new DomCache(); |
||||
|
this.orders = []; |
||||
|
this.unknown_products = []; |
||||
|
this.search_query = false; |
||||
|
this.perform_search(); |
||||
|
}, |
||||
|
|
||||
|
auto_back: true, |
||||
|
|
||||
|
show: function () { |
||||
|
var self = this; |
||||
|
var previous_screen = false; |
||||
|
if (this.pos.get_order()) { |
||||
|
previous_screen = this.pos.get_order().get_screen_data( |
||||
|
'previous-screen'); |
||||
|
} |
||||
|
if (previous_screen === 'receipt') { |
||||
|
this.gui.screen_instances.receipt.click_next(); |
||||
|
this.gui.show_screen('orderlist'); |
||||
|
} |
||||
|
this._super(); |
||||
|
this.renderElement(); |
||||
|
this.old_order = this.pos.get_order(); |
||||
|
this.$('.back').click(function () { |
||||
|
return self.gui.show_screen(self.gui.startup_screen); |
||||
|
}); |
||||
|
|
||||
|
if (this.pos.config.iface_vkeyboard && |
||||
|
this.chrome.widget.keyboard) { |
||||
|
this.chrome.widget.keyboard.connect( |
||||
|
this.$('.searchbox input')); |
||||
|
} |
||||
|
|
||||
|
var search_timeout = null; |
||||
|
this.$('.searchbox input').on('keyup', function () { |
||||
|
self.search_query = this.value; |
||||
|
clearTimeout(search_timeout); |
||||
|
search_timeout = setTimeout(function () { |
||||
|
self.perform_search(); |
||||
|
}, 70); |
||||
|
}); |
||||
|
|
||||
|
this.$('.searchbox .search-clear').click(function () { |
||||
|
self.clear_search(); |
||||
|
}); |
||||
|
|
||||
|
this.perform_search(); |
||||
|
}, |
||||
|
|
||||
|
render_list: function () { |
||||
|
var self = this; |
||||
|
var orders = this.orders; |
||||
|
var contents = this.$el[0].querySelector('.order-list-contents'); |
||||
|
contents.innerHTML = ""; |
||||
|
for ( |
||||
|
var i = 0, len = Math.min(orders.length, 1000); i < len; i++ |
||||
|
) { |
||||
|
var order = orders[i]; |
||||
|
var orderline = this.order_cache.get_node( |
||||
|
order.id || order.uid); |
||||
|
if (!orderline) { |
||||
|
var orderline_html = QWeb.render('OrderLine', { |
||||
|
widget: this, |
||||
|
order: order, |
||||
|
}); |
||||
|
orderline = document.createElement('tbody'); |
||||
|
orderline.innerHTML = orderline_html; |
||||
|
orderline = orderline.childNodes[1]; |
||||
|
this.order_cache.cache_node( |
||||
|
order.id || order.uid, orderline); |
||||
|
} |
||||
|
if (order === this.old_order) { |
||||
|
orderline.classList.add('highlight'); |
||||
|
} else { |
||||
|
orderline.classList.remove('highlight'); |
||||
|
} |
||||
|
contents.appendChild(orderline); |
||||
|
} |
||||
|
// FIXME: Everytime the list is rendered we need to reassing the
|
||||
|
// button events.
|
||||
|
this.$('.order-list-return').off('click'); |
||||
|
this.$('.order-list-reprint').off('click'); |
||||
|
this.$('.order-list-copy').off('click'); |
||||
|
this.$('.order-list-reprint').click(function (event) { |
||||
|
self.order_list_actions(event, 'print'); |
||||
|
}); |
||||
|
this.$('.order-list-copy').click(function (event) { |
||||
|
self.order_list_actions(event, 'copy'); |
||||
|
}); |
||||
|
this.$('.order-list-return').click(function (event) { |
||||
|
self.order_list_actions(event, 'return'); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
order_list_actions: function (event, action) { |
||||
|
var self = this; |
||||
|
var dataset = event.target.parentNode.dataset; |
||||
|
self.load_order_data(parseInt(dataset.orderId, 10)) |
||||
|
.then(function (order_data) { |
||||
|
self.order_action(order_data, action); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
order_action: function (order_data, action) { |
||||
|
if (this.old_order !== null) { |
||||
|
this.gui.back(); |
||||
|
} |
||||
|
var order = this.load_order_from_data(order_data, action); |
||||
|
if (!order) { |
||||
|
// The load of the order failed. (products not found, ...
|
||||
|
// We cancel the action
|
||||
|
return; |
||||
|
} |
||||
|
this['action_' + action](order_data, order); |
||||
|
}, |
||||
|
|
||||
|
action_print: function (order_data, order) { |
||||
|
// We store temporarily the current order so we can safely compute
|
||||
|
// taxes based on fiscal position
|
||||
|
this.pos.current_order = this.pos.get_order(); |
||||
|
|
||||
|
this.pos.set_order(order); |
||||
|
|
||||
|
if (this.pos.config.iface_print_via_proxy) { |
||||
|
this.pos.proxy.print_receipt(QWeb.render( |
||||
|
'XmlReceipt', { |
||||
|
receipt: order.export_for_printing(), |
||||
|
widget: this, |
||||
|
pos: this.pos, |
||||
|
order: order, |
||||
|
orderlines: order.get_orderlines(), |
||||
|
paymentlines: order.get_paymentlines(), |
||||
|
})); |
||||
|
this.pos.set_order(this.pos.current_order); |
||||
|
this.pos.current_order = false; |
||||
|
} else { |
||||
|
this.pos.reloaded_order = order; |
||||
|
this.gui.show_screen('receipt'); |
||||
|
this.pos.reloaded_order = false; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
action_copy: function (order_data, order) { |
||||
|
order.trigger('change'); |
||||
|
this.pos.get('orders').add(order); |
||||
|
this.pos.set('selectedOrder', order); |
||||
|
return order; |
||||
|
}, |
||||
|
|
||||
|
action_return: function (order_data, order) { |
||||
|
order.trigger('change'); |
||||
|
this.pos.get('orders').add(order); |
||||
|
this.pos.set('selectedOrder', order); |
||||
|
return order; |
||||
|
}, |
||||
|
|
||||
|
_prepare_order_from_order_data: function (order_data, action) { |
||||
|
var self = this; |
||||
|
var order = new pos.Order({}, { |
||||
|
pos: this.pos, |
||||
|
}); |
||||
|
|
||||
|
// Get Customer
|
||||
|
if (order_data.partner_id) { |
||||
|
order.set_client( |
||||
|
this.pos.db.get_partner_by_id(order_data.partner_id)); |
||||
|
} |
||||
|
|
||||
|
// Get fiscal position
|
||||
|
if (order_data.fiscal_position && this.pos.fiscal_positions) { |
||||
|
var fiscal_positions = this.pos.fiscal_positions; |
||||
|
order.fiscal_position = fiscal_positions.filter(function (p) { |
||||
|
return p.id === order_data.fiscal_position; |
||||
|
})[0]; |
||||
|
order.trigger('change'); |
||||
|
} |
||||
|
|
||||
|
// Get order lines
|
||||
|
self._prepare_orderlines_from_order_data( |
||||
|
order, order_data, action); |
||||
|
|
||||
|
// Get Name
|
||||
|
if (['print'].indexOf(action) !== -1) { |
||||
|
order.name = order_data.pos_reference; |
||||
|
} else if (['return'].indexOf(action) !== -1) { |
||||
|
order.name = _t("Refund ") + order.uid; |
||||
|
} |
||||
|
|
||||
|
// Get to invoice
|
||||
|
if (['return', 'copy'].indexOf(action) !== -1) { |
||||
|
// If previous order was invoiced, we need a refund too
|
||||
|
order.set_to_invoice(order_data.to_invoice); |
||||
|
} |
||||
|
|
||||
|
// Get returned Order
|
||||
|
if (['print'].indexOf(action) !== -1) { |
||||
|
// Get the same value as the original
|
||||
|
order.returned_order_id = order_data.returned_order_id; |
||||
|
order.returned_order_reference = |
||||
|
order_data.returned_order_reference; |
||||
|
} else if (['return'].indexOf(action) !== -1) { |
||||
|
order.returned_order_id = order_data.id; |
||||
|
order.returned_order_reference = order_data.pos_reference; |
||||
|
} |
||||
|
|
||||
|
// Get Date
|
||||
|
if (['print'].indexOf(action) !== -1) { |
||||
|
order.formatted_validation_date = |
||||
|
moment(order_data.date_order).format('YYYY-MM-DD HH:mm:ss'); |
||||
|
} |
||||
|
|
||||
|
// Get Payment lines
|
||||
|
if (['print'].indexOf(action) !== -1) { |
||||
|
var paymentLines = order_data.statement_ids || []; |
||||
|
_.each(paymentLines, function (paymentLine) { |
||||
|
var line = paymentLine; |
||||
|
// In case of local data
|
||||
|
if (line.length === 3) { |
||||
|
line = line[2]; |
||||
|
} |
||||
|
_.each(self.pos.cashregisters, function (cashregister) { |
||||
|
if (cashregister.journal.id === line.journal_id) { |
||||
|
if (line.amount > 0) { |
||||
|
// If it is not change
|
||||
|
order.add_paymentline(cashregister); |
||||
|
order.selected_paymentline.set_amount( |
||||
|
line.amount); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
return order; |
||||
|
}, |
||||
|
|
||||
|
_prepare_orderlines_from_order_data: function ( |
||||
|
order, order_data, action) { |
||||
|
var orderLines = order_data.line_ids || order_data.lines || []; |
||||
|
|
||||
|
var self = this; |
||||
|
_.each(orderLines, function (orderLine) { |
||||
|
var line = orderLine; |
||||
|
// In case of local data
|
||||
|
if (line.length === 3) { |
||||
|
line = line[2]; |
||||
|
} |
||||
|
var product = self.pos.db.get_product_by_id(line.product_id); |
||||
|
// Check if product are available in pos
|
||||
|
if (_.isUndefined(product)) { |
||||
|
self.unknown_products.push(String(line.product_id)); |
||||
|
} else { |
||||
|
var qty = line.qty; |
||||
|
if (['return'].indexOf(action) !== -1) { |
||||
|
// Invert line quantities
|
||||
|
qty *= -1; |
||||
|
} |
||||
|
// Create a new order line
|
||||
|
order.add_product(product, { |
||||
|
price: line.price_unit, |
||||
|
quantity: qty, |
||||
|
discount: line.discount, |
||||
|
merge: false, |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
load_order_data: function (order_id) { |
||||
|
var self = this; |
||||
|
return this._rpc({ |
||||
|
model: 'pos.order', |
||||
|
method: 'load_done_order_for_pos', |
||||
|
args: [order_id], |
||||
|
}).fail(function (error) { |
||||
|
if (parseInt(error.code, 10) === 200) { |
||||
|
// Business Logic Error, not a connection problem
|
||||
|
self.gui.show_popup( |
||||
|
'error-traceback', { |
||||
|
'title': error.data.message, |
||||
|
'body': error.data.debug, |
||||
|
}); |
||||
|
} else { |
||||
|
self.gui.show_popup('error', { |
||||
|
'title': _t('Connection error'), |
||||
|
'body': _t( |
||||
|
'Can not execute this action because the POS' + |
||||
|
' is currently offline'), |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
load_order_from_data: function (order_data, action) { |
||||
|
var self = this; |
||||
|
this.unknown_products = []; |
||||
|
var order = self._prepare_order_from_order_data( |
||||
|
order_data, action); |
||||
|
// Forbid POS Order loading if some products are unknown
|
||||
|
if (self.unknown_products.length > 0) { |
||||
|
self.gui.show_popup('error-traceback', { |
||||
|
'title': _t('Unknown Products'), |
||||
|
'body': _t('Unable to load some order lines because the ' + |
||||
|
'products are not available in the POS cache.\n\n' + |
||||
|
'Please check that lines :\n\n * ') + |
||||
|
self.unknown_products.join("; \n *"), |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
return order; |
||||
|
}, |
||||
|
|
||||
|
// Search Part
|
||||
|
search_done_orders: function (query) { |
||||
|
var self = this; |
||||
|
return this._rpc({ |
||||
|
model: 'pos.order', |
||||
|
method: 'search_done_orders_for_pos', |
||||
|
args: [query || '', this.pos.pos_session.id], |
||||
|
}).then(function (result) { |
||||
|
self.orders = result; |
||||
|
// Get the date in local time
|
||||
|
_.each(self.orders, function (order) { |
||||
|
if (order.date_order) { |
||||
|
order.date_order = moment.utc(order.date_order) |
||||
|
.local().format('YYYY-MM-DD HH:mm:ss'); |
||||
|
} |
||||
|
}); |
||||
|
}).fail(function (error, event) { |
||||
|
if (parseInt(error.code, 10) === 200) { |
||||
|
// Business Logic Error, not a connection problem
|
||||
|
self.gui.show_popup( |
||||
|
'error-traceback', { |
||||
|
'title': error.data.message, |
||||
|
'body': error.data.debug, |
||||
|
} |
||||
|
); |
||||
|
} else { |
||||
|
self.gui.show_popup('error', { |
||||
|
'title': _t('Connection error'), |
||||
|
'body': _t( |
||||
|
'Can not execute this action because the POS' + |
||||
|
' is currently offline'), |
||||
|
}); |
||||
|
} |
||||
|
event.preventDefault(); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
perform_search: function () { |
||||
|
var self = this; |
||||
|
return this.search_done_orders(self.search_query) |
||||
|
.done(function () { |
||||
|
self.render_list(); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
clear_search: function () { |
||||
|
var self = this; |
||||
|
self.$('.searchbox input')[0].value = ''; |
||||
|
self.$('.searchbox input').focus(); |
||||
|
self.search_query = false; |
||||
|
self.perform_search(); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
gui.define_screen({ |
||||
|
name: 'orderlist', |
||||
|
widget: OrderListScreenWidget, |
||||
|
}); |
||||
|
|
||||
|
var ListOrderButtonWidget = PosBaseWidget.extend({ |
||||
|
template: 'ListOrderButtonWidget', |
||||
|
init: function (parent, options) { |
||||
|
var opts = options || {}; |
||||
|
this._super(parent, opts); |
||||
|
this.action = opts.action; |
||||
|
this.label = opts.label; |
||||
|
}, |
||||
|
|
||||
|
button_click: function () { |
||||
|
this.gui.show_screen('orderlist'); |
||||
|
}, |
||||
|
|
||||
|
renderElement: function () { |
||||
|
var self = this; |
||||
|
this._super(); |
||||
|
this.$el.click(function () { |
||||
|
self.button_click(); |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
var widgets = chrome.Chrome.prototype.widgets; |
||||
|
widgets.push({ |
||||
|
'name': 'list_orders', |
||||
|
'widget': ListOrderButtonWidget, |
||||
|
'prepend': '.pos-rightheader', |
||||
|
'args': { |
||||
|
'label': 'All Orders', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
return { |
||||
|
ListOrderButtonWidget: ListOrderButtonWidget, |
||||
|
OrderListScreenWidget: OrderListScreenWidget, |
||||
|
}; |
||||
|
|
||||
|
}); |
@ -0,0 +1,104 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates id="template" xml:space="preserve"> |
||||
|
|
||||
|
<t t-name="ListOrderButtonWidget"> |
||||
|
<t t-if="widget.pos.config.iface_load_done_order_max_qty"> |
||||
|
<div class="header-button order-list-button"> |
||||
|
<i class='fa fa-fw fa-shopping-cart'/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="OrderListScreenWidget"> |
||||
|
<div class="clientlist-screen screen"> |
||||
|
<div class="screen-content"> |
||||
|
<section class="top-content"> |
||||
|
<span class='button back'> |
||||
|
<i class='fa fa-angle-double-left'></i> |
||||
|
Back |
||||
|
</span> |
||||
|
<span class='searchbox'> |
||||
|
<input placeholder='Search Order' /> |
||||
|
<span class='search-clear'></span> |
||||
|
</span> |
||||
|
<span class='searchbox'></span> |
||||
|
</section> |
||||
|
<section class="full-content"> |
||||
|
<div class="window"> |
||||
|
<section class="subwindow"> |
||||
|
<div class="subwindow-container"> |
||||
|
<div class="subwindow-container-fix touch-scrollable scrollable-y"> |
||||
|
<table class="client-list"> |
||||
|
<thead> |
||||
|
<th name="th_ol_ref">Ref.</th> |
||||
|
<th name="th_ol_customer">Customer</th> |
||||
|
<th name="th_ol_date">Date</th> |
||||
|
<th name="th_ol_amount_total">Amount Total</th> |
||||
|
<th name="th_ol_reprint"/> |
||||
|
</thead> |
||||
|
<tbody class="order-list-contents"> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
</div> |
||||
|
</section> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="OrderLine"> |
||||
|
<tr class='order-line' t-att-data-id='order.id' t-att-data-Uid='order.uid'> |
||||
|
<td name="td_ol_name"><t t-esc='order.pos_reference or order.name' /></td> |
||||
|
<td name="td_ol_customer"><t t-esc='order.partner_id[1]' /></td> |
||||
|
<td name="td_ol_date"><t t-esc='order.date_order' /></td> |
||||
|
<td name="td_ol_amount_total"><t t-esc='widget.format_currency(order.amount_total)' /></td> |
||||
|
<td name="td_ol_reprint" t-att-data-order-id="order.id" t-att-data-Uid='order.uid'> |
||||
|
<span t-if="widget.pos.config.iface_reprint_done_order" class="button order-list-reprint" t-att-data-order-id="order.id" t-att-data-Uid='order.uid' title="Print a duplicate for this order"> |
||||
|
<i class='fa fa-fw fa-print'/> |
||||
|
</span> |
||||
|
<span t-if="widget.pos.config.iface_copy_done_order" class="button order-list-copy" t-att-data-order-id="order.id" t-att-data-Uid='order.uid' title="Create a new order based on this one"> |
||||
|
<i class='fa fa-fw fa-copy'/> |
||||
|
</span> |
||||
|
<span t-if="widget.pos.config.iface_return_done_order and order.amount_total >= 0" class="button order-list-return" t-att-data-order-id="order.id" t-att-data-Uid='order.uid' title="Create a refund order of this order"> |
||||
|
<i class='fa fa-fw fa-undo'/> |
||||
|
</span> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
|
||||
|
<t t-extend="OrderWidget"> |
||||
|
<t t-jquery=".summary" t-operation="after"> |
||||
|
<div class="order-returned-warning" t-if="order.returned_order_id"> |
||||
|
<span>Returned order: </span><t name="returned-order-reference" t-esc="order.returned_order_reference"></t> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
<t t-extend="PosTicket"> |
||||
|
<t t-jquery="t[t-esc='order.name']" t-operation="after"> |
||||
|
<t t-if="order.returned_order_id"> |
||||
|
<br/> |
||||
|
<span name="returned-order-reference">Rectifies: </span><t t-esc="order.returned_order_reference"/> |
||||
|
</t> |
||||
|
</t> |
||||
|
<t t-jquery=".receipt-user" t-operation="after"> |
||||
|
<t t-if="pos.reloaded_order"> |
||||
|
<br/> |
||||
|
<div style='text-align:center'>DUPLICATE</div> |
||||
|
<br/> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
<t t-extend="XmlReceipt"> |
||||
|
<t t-jquery=".orderlines" t-operation="before"> |
||||
|
<t t-if="pos.current_order"> |
||||
|
<div>DUPLICATE</div> |
||||
|
<br/> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
</templates> |
@ -0,0 +1 @@ |
|||||
|
from . import test_module |
@ -0,0 +1,80 @@ |
|||||
|
# Copyright (C) 2019 - Today: GRAP (http://www.grap.coop) |
||||
|
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import fields |
||||
|
from odoo.tests.common import TransactionCase |
||||
|
|
||||
|
|
||||
|
class TestModule(TransactionCase): |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(TestModule, self).setUp() |
||||
|
|
||||
|
# Get Registry |
||||
|
self.PosOrder = self.env['pos.order'] |
||||
|
self.AccountPayment = self.env['account.payment'] |
||||
|
|
||||
|
# Get Object |
||||
|
self.pos_product = self.env.ref('point_of_sale.whiteboard_pen') |
||||
|
self.pricelist = self.env.ref('product.list0') |
||||
|
self.partner = self.env.ref('base.res_partner_12') |
||||
|
|
||||
|
# Create a new pos config and open it |
||||
|
self.pos_config = self.env.ref('point_of_sale.pos_config_main').copy() |
||||
|
self.pos_config.open_session_cb() |
||||
|
|
||||
|
# Test Section |
||||
|
def test_load_order(self): |
||||
|
order = self._create_order() |
||||
|
orders_data = self.PosOrder.search_done_orders_for_pos( |
||||
|
[], self.pos_config.current_session_id.id) |
||||
|
self.assertEqual(len(orders_data), 1) |
||||
|
self.assertEqual( |
||||
|
orders_data[0]['id'], order.id) |
||||
|
|
||||
|
detail_data = order.load_done_order_for_pos() |
||||
|
self.assertEqual( |
||||
|
len(detail_data.get('line_ids', [])), 1, |
||||
|
"Loading order detail failed") |
||||
|
|
||||
|
def _create_order(self): |
||||
|
# Create order |
||||
|
order_data = { |
||||
|
'id': u'0006-001-0010', |
||||
|
'to_invoice': True, |
||||
|
'data': { |
||||
|
'pricelist_id': self.pricelist.id, |
||||
|
'user_id': 1, |
||||
|
'name': 'Order 0006-001-0010', |
||||
|
'partner_id': self.partner.id, |
||||
|
'amount_paid': 0.9, |
||||
|
'pos_session_id': self.pos_config.current_session_id.id, |
||||
|
'lines': [[0, 0, { |
||||
|
'product_id': self.pos_product.id, |
||||
|
'price_unit': 0.9, |
||||
|
'qty': 1, |
||||
|
'price_subtotal': 0.9, |
||||
|
'price_subtotal_incl': 0.9, |
||||
|
}]], |
||||
|
'statement_ids': [[0, 0, { |
||||
|
'journal_id': self.pos_config.journal_ids[0].id, |
||||
|
'amount': 0.9, |
||||
|
'name': fields.Datetime.now(), |
||||
|
'account_id': |
||||
|
self.env.user.partner_id.property_account_receivable_id.id, |
||||
|
'statement_id': |
||||
|
self.pos_config.current_session_id.statement_ids[0].id, |
||||
|
}]], |
||||
|
'creation_date': u'2018-09-27 15:51:03', |
||||
|
'amount_tax': 0, |
||||
|
'fiscal_position_id': False, |
||||
|
'uid': u'00001-001-0001', |
||||
|
'amount_return': 0, |
||||
|
'sequence_number': 1, |
||||
|
'amount_total': 0.9, |
||||
|
}} |
||||
|
|
||||
|
result = self.PosOrder.create_from_ui([order_data]) |
||||
|
order = self.PosOrder.browse(result[0]) |
||||
|
return order |
@ -0,0 +1,13 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<template id="assets" inherit_id="point_of_sale.assets"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<script type="text/javascript" src="/pos_order_mgmt/static/src/js/widgets.js"/> |
||||
|
<script type="text/javascript" src="/pos_order_mgmt/static/src/js/models.js"/> |
||||
|
<link rel="stylesheet" href="/pos_order_mgmt/static/src/css/pos.css"/> |
||||
|
</xpath> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,63 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- Copyright 2018 GRAP - Sylvain LE GAL |
||||
|
Copyright 2018 Tecnativa - David Vidal |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
--> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_pos_config_form" model="ir.ui.view"> |
||||
|
<field name="model">pos.config</field> |
||||
|
<field name="inherit_id" ref="point_of_sale.pos_config_view_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//div[@id='receipt']" position="inside"> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box" id="reprint_done_order"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="iface_reprint_done_order"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label string="Reprint Done Orders" for="iface_reprint_done_order"/> |
||||
|
<div class="text-muted"> |
||||
|
Allow to reprint done orders in this POS |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box" id="return_done_order"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="iface_return_done_order"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label string="Return Done Orders" for="iface_return_done_order"/> |
||||
|
<div class="text-muted"> |
||||
|
Allow to return done orders in this POS |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box" id="copy_done_order"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="iface_copy_done_order"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label string="Duplicate Done Orders" for="iface_copy_done_order"/> |
||||
|
<div class="text-muted"> |
||||
|
Allow to duplicate done orders in this POS |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box" id="load_done_order_max_qty" |
||||
|
attrs="{'invisible': [('iface_reprint_done_order', '=', False), |
||||
|
('iface_return_done_order', '=', False)]}"> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label string="Load Done Order Max Qty." for="iface_load_done_order_max_qty"/> |
||||
|
<div class="text-muted"> |
||||
|
Maximum number orders to load |
||||
|
</div> |
||||
|
<div class="content-group mt16"> |
||||
|
<field name="iface_load_done_order_max_qty" class="oe_inline"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,22 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- Copyright 2018 GRAP - Sylvain LE GAL |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
--> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_pos_order_form" model="ir.ui.view"> |
||||
|
<field name="model">pos.order</field> |
||||
|
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="session_id" position="after"> |
||||
|
<field name="returned_order_id" attrs="{'invisible': [('returned_order_id', '=', False)]}" /> |
||||
|
</field> |
||||
|
<xpath expr="//div[@name='button_box']" position="inside"> |
||||
|
<button name="action_view_refund_orders" type="object" icon="fa-undo" class="oe_stat_button" attrs="{'invisible': [('refund_order_qty', '=', 0)]}"> |
||||
|
<field string="Refunds" name="refund_order_qty" widget="statinfo"/> |
||||
|
</button> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -1 +1 @@ |
|||||
12.0.20190320.0 |
|
||||
|
12.0.20190718.0 |
@ -0,0 +1 @@ |
|||||
|
../../../../pos_order_mgmt |
@ -0,0 +1,6 @@ |
|||||
|
import setuptools |
||||
|
|
||||
|
setuptools.setup( |
||||
|
setup_requires=['setuptools-odoo'], |
||||
|
odoo_addon=True, |
||||
|
) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue