Browse Source

[FIX] loaded orders date to local https://github.com/OCA/pos/pull/361 cortesy @chienandalu

[FIX] compatibility with pos_restaurant https://github.com/OCA/pos/pull/339 cortesy @carlosDomatix
[FIX] add _compute_refund_order_qty
[ADD] pos order view form. Add links to original returned order and refund orders.
[IMP] when refunding an order via the 'Refund' button in back office, set the correct returned_order_id.
[IMP] Add helper on each button
[ADD] python test
[REF] JS remove useless code
[REF] Python remove useless code
[FIX] remove bad oldname
[FIX] remove gap in bill display, when it is a refund
[FIX] when reprinting a bill, the returned order name is displayed, if any
[FIX] JS lint, with OCA eslint file
[ADD] french translation
pull/378/head
Sylvain LE GAL 5 years ago
committed by OCA-git-bot
parent
commit
9946e1e0b3
  1. 1
      pos_order_mgmt/__manifest__.py
  2. 249
      pos_order_mgmt/i18n/fr.po
  3. 151
      pos_order_mgmt/i18n/pos_order_mgmt.pot
  4. 4
      pos_order_mgmt/models/pos_config.py
  5. 73
      pos_order_mgmt/models/pos_order.py
  6. 1
      pos_order_mgmt/static/src/css/pos.css
  7. 36
      pos_order_mgmt/static/src/js/models.js
  8. 246
      pos_order_mgmt/static/src/js/widgets.js
  9. 16
      pos_order_mgmt/static/src/xml/pos.xml
  10. 1
      pos_order_mgmt/tests/__init__.py
  11. 80
      pos_order_mgmt/tests/test_module.py
  12. 1
      pos_order_mgmt/views/view_pos_config.xml
  13. 22
      pos_order_mgmt/views/view_pos_order.xml

1
pos_order_mgmt/__manifest__.py

@ -18,6 +18,7 @@
'data': [ 'data': [
'views/assets.xml', 'views/assets.xml',
'views/view_pos_config.xml', 'views/view_pos_config.xml',
'views/view_pos_order.xml',
], ],
'qweb': [ 'qweb': [
'static/src/xml/pos.xml' 'static/src/xml/pos.xml'

249
pos_order_mgmt/i18n/fr.po

@ -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"

151
pos_order_mgmt/i18n/pos_order_mgmt.pot

@ -1,11 +1,13 @@
# Translation of Odoo Server. # Translation of Odoo Server.
# This file contains the translation of the following modules: # This file contains the translation of the following modules:
# * pos_order_mgmt
# * pos_order_mgmt
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-15 20:53+0000\n"
"PO-Revision-Date: 2019-07-15 20:53+0000\n"
"Last-Translator: <>\n" "Last-Translator: <>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -14,13 +16,33 @@ msgstr ""
"Plural-Forms: \n" "Plural-Forms: \n"
#. module: pos_order_mgmt #. 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"
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form
msgid "Allow to duplicate done orders in this POS"
msgstr "" msgstr ""
#. module: pos_order_mgmt #. 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."
#: 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 "" msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
@ -39,20 +61,34 @@ msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
#. openerp-web #. openerp-web
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:303
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:331
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:341
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:396
#, python-format #, python-format
msgid "Can not execute this action because the POS is currently offline" msgid "Can not execute this action because the POS is currently offline"
msgstr "" msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
#. openerp-web #. openerp-web
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:302
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:330
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:340
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:395
#, python-format #, python-format
msgid "Connection error" msgid "Connection error"
msgstr "" 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 #. module: pos_order_mgmt
#. openerp-web #. openerp-web
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:34 #: code:addons/pos_order_mgmt/static/src/xml/pos.xml:34
@ -60,6 +96,14 @@ msgstr ""
msgid "Customer" msgid "Customer"
msgstr "" 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 #. module: pos_order_mgmt
#. openerp-web #. openerp-web
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:35 #: code:addons/pos_order_mgmt/static/src/xml/pos.xml:35
@ -68,31 +112,36 @@ msgid "Date"
msgstr "" msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
#: model:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form
msgid "Load Done Order Max Qty."
#: 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 "" msgstr ""
#. module: pos_order_mgmt #. 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"
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form
msgid "Load Done Order Max Qty."
msgstr "" msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
#: model:ir.model.fields,field_description:pos_order_mgmt.field_pos_config_iface_load_done_order_max_qty
#: 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" msgid "Max. Done Orders Quantity To Load"
msgstr "" msgstr ""
#. module: pos_order_mgmt #. 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)."
#: 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 "" msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
#: model:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form
#: model_terms:ir.ui.view,arch_db:pos_order_mgmt.view_pos_config_form
msgid "Maximum number orders to load" msgid "Maximum number orders to load"
msgstr "" 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 #. module: pos_order_mgmt
#: model:ir.model,name:pos_order_mgmt.model_pos_order #: model:ir.model,name:pos_order_mgmt.model_pos_order
msgid "Point of Sale Orders" msgid "Point of Sale Orders"
@ -100,7 +149,14 @@ msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
#. openerp-web #. openerp-web
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:80
#: 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 #, python-format
msgid "Rectifies:" msgid "Rectifies:"
msgstr "" msgstr ""
@ -112,9 +168,53 @@ msgstr ""
msgid "Ref." msgid "Ref."
msgstr "" 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 #. module: pos_order_mgmt
#. openerp-web #. openerp-web
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:71
#: code:addons/pos_order_mgmt/static/src/xml/pos.xml:74
#, python-format #, python-format
msgid "Returned order:" msgid "Returned order:"
msgstr "" msgstr ""
@ -128,7 +228,7 @@ msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
#. openerp-web #. openerp-web
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:280
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:358
#, python-format #, python-format
msgid "Unable to load some order lines because the products are not available in the POS cache.\n" msgid "Unable to load some order lines because the products are not available in the POS cache.\n"
"\n" "\n"
@ -139,13 +239,8 @@ msgstr ""
#. module: pos_order_mgmt #. module: pos_order_mgmt
#. openerp-web #. openerp-web
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:279
#: code:addons/pos_order_mgmt/static/src/js/widgets.js:357
#, python-format #, python-format
msgid "Unknown Products" msgid "Unknown Products"
msgstr "" msgstr ""
#. module: pos_order_mgmt
#: model:ir.model,name:pos_order_mgmt.model_pos_config
msgid "pos.config"
msgstr ""

4
pos_order_mgmt/models/pos_config.py

@ -14,14 +14,12 @@ class PosConfig(models.Model):
string='Reprint Done Orders', string='Reprint Done Orders',
default=True, default=True,
help='Allows to reprint already done orders in the frontend', help='Allows to reprint already done orders in the frontend',
oldname='iface_load_done_order',
) )
iface_return_done_order = fields.Boolean( iface_return_done_order = fields.Boolean(
string='Return Done Orders', string='Return Done Orders',
default=True, default=True,
help='Allows to return already done orders in the frontend', help='Allows to return already done orders in the frontend',
oldname='iface_load_done_order',
) )
iface_copy_done_order = fields.Boolean( iface_copy_done_order = fields.Boolean(
@ -35,6 +33,6 @@ class PosConfig(models.Model):
default=10, default=10,
required=True, required=True,
help='Maximum number of orders to load on the PoS at its init. ' help='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 '
'Set it to 0 to load none (it\'s still possible to load them by '
'ticket code).', 'ticket code).',
) )

73
pos_order_mgmt/models/pos_order.py

@ -13,17 +13,56 @@ class PosOrder(models.Model):
string='Returned Order', string='Returned Order',
readonly=True, readonly=True,
) )
returned_order_reference = fields.Char(
related='returned_order_id.pos_reference',
string='Reference of the returned Order')
refund_order_ids = fields.One2many( refund_order_ids = fields.One2many(
comodel_name='pos.order', comodel_name='pos.order',
inverse_name='returned_order_id', inverse_name='returned_order_id',
string='Refund Orders', string='Refund Orders',
readonly=True, readonly=True,
) )
refund_order_qty = fields.Integer( refund_order_qty = fields.Integer(
compute='_compute_refund_order_qty', compute='_compute_refund_order_qty',
string='Refund Orders Quantity', 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 @api.model
def _prepare_filter_for_pos(self, pos_session_id): def _prepare_filter_for_pos(self, pos_session_id):
return [ return [
@ -43,9 +82,7 @@ class PosOrder(models.Model):
def _prepare_fields_for_pos_list(self): def _prepare_fields_for_pos_list(self):
return [ return [
'name', 'pos_reference', 'partner_id', 'date_order', 'name', 'pos_reference', 'partner_id', 'date_order',
'amount_total', 'amount_paid', 'amount_return', 'session_id',
'amount_tax', 'statement_ids', 'lines', 'invoice_id',
'returned_order_id', 'fiscal_position_id'
'amount_total',
] ]
@api.model @api.model
@ -76,7 +113,7 @@ class PosOrder(models.Model):
payment_line = self._prepare_done_order_payment_for_pos( payment_line = self._prepare_done_order_payment_for_pos(
payment_line) payment_line)
payment_lines.append(payment_line) payment_lines.append(payment_line)
return {
res = {
'id': self.id, 'id': self.id,
'date_order': self.date_order, 'date_order': self.date_order,
'pos_reference': self.pos_reference, 'pos_reference': self.pos_reference,
@ -85,11 +122,11 @@ class PosOrder(models.Model):
'fiscal_position': self.fiscal_position_id.id, 'fiscal_position': self.fiscal_position_id.id,
'line_ids': order_lines, 'line_ids': order_lines,
'statement_ids': payment_lines, 'statement_ids': payment_lines,
'origin_invoice_id': bool(self.invoice_id),
'returned_order_id': (self.returned_order_id and
self.returned_order_id.pos_reference or
False),
'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 @api.multi
def _prepare_done_order_line_for_pos(self, order_line): def _prepare_done_order_line_for_pos(self, order_line):
@ -115,17 +152,9 @@ class PosOrder(models.Model):
return self._prepare_done_order_for_pos() return self._prepare_done_order_for_pos()
@api.model @api.model
def _process_order(self, pos_order):
if (not pos_order.get('return') or
not pos_order.get('returned_order_id')):
return super()._process_order(pos_order)
order = super(PosOrder, self)._process_order(pos_order)
returned_order_id = pos_order.get('returned_order_id')
if isinstance(returned_order_id, int):
order.returned_order_id = self.browse(returned_order_id)
# Only if the order is returned from the browser saved orders.
else:
order.returned_order_id = self.search([
('pos_reference', '=', returned_order_id)])
order.returned_order_id.refund_order_ids |= order
return order
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

1
pos_order_mgmt/static/src/css/pos.css

@ -31,4 +31,5 @@
padding: 8px 0; padding: 8px 0;
background-color: rgb(239, 153, 65); background-color: rgb(239, 153, 65);
color: white; color: white;
text-align: center;
} }

36
pos_order_mgmt/static/src/js/models.js

@ -6,40 +6,24 @@ odoo.define('pos_order_mgmt.models', function (require) {
var models = require('point_of_sale.models'); var models = require('point_of_sale.models');
var _PosModel_push_order = models.PosModel.prototype.push_order;
models.PosModel.prototype.push_order = function () {
var res = _PosModel_push_order.apply(this, arguments);
if (arguments.length && arguments[0] && arguments[0].uid) {
var order = this.db.get_order(arguments[0].uid);
if (order && order.data) {
var data = _.extend({}, order.data);
var partner = this.db.get_partner_by_id(data.partner_id);
if (partner && partner.id && partner.name) {
data.partner_id = [partner.id, partner.name];
}
data.date_order = moment(order.data.creation_date)
.format('YYYY-MM-DD HH:mm:ss');
this.gui.screen_instances.orderlist.orders.unshift(data);
}
}
return res;
};
var order_super = models.Order.prototype; var order_super = models.Order.prototype;
models.Order = models.Order.extend({ models.Order = models.Order.extend({
init_from_JSON: function (json) { init_from_JSON: function (json) {
order_super.init_from_JSON.apply(this, arguments); order_super.init_from_JSON.apply(this, arguments);
this.return = json.return;
this.returned_order_id = json.returned_order_id; this.returned_order_id = json.returned_order_id;
this.origin_name = json.origin_name;
this.returned_order_reference = json.returned_order_reference;
}, },
export_as_JSON: function () { export_as_JSON: function () {
var res = order_super.export_as_JSON.apply(this, arguments); var res = order_super.export_as_JSON.apply(this, arguments);
if (this.return) {
res.origin_name = this.origin_name;
res.returned_order_id = this.returned_order_id;
res.return = this.return;
}
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; return res;
}, },
}); });

246
pos_order_mgmt/static/src/js/widgets.js

@ -65,9 +65,10 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
show: function () { show: function () {
var self = this; var self = this;
var previous_screen;
var previous_screen = false;
if (this.pos.get_order()) { if (this.pos.get_order()) {
previous_screen = this.pos.get_order().get_screen_data('previous-screen');
previous_screen = this.pos.get_order().get_screen_data(
'previous-screen');
} }
if (previous_screen === 'receipt') { if (previous_screen === 'receipt') {
this.gui.screen_instances.receipt.click_next(); this.gui.screen_instances.receipt.click_next();
@ -80,12 +81,14 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
return self.gui.show_screen(self.gui.startup_screen); 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'));
if (this.pos.config.iface_vkeyboard &&
this.chrome.widget.keyboard) {
this.chrome.widget.keyboard.connect(
this.$('.searchbox input'));
} }
var search_timeout = null; var search_timeout = null;
this.$('.searchbox input').on('keyup', function (event) {
this.$('.searchbox input').on('keyup', function () {
self.search_query = this.value; self.search_query = this.value;
clearTimeout(search_timeout); clearTimeout(search_timeout);
search_timeout = setTimeout(function () { search_timeout = setTimeout(function () {
@ -105,9 +108,12 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
var orders = this.orders; var orders = this.orders;
var contents = this.$el[0].querySelector('.order-list-contents'); var contents = this.$el[0].querySelector('.order-list-contents');
contents.innerHTML = ""; contents.innerHTML = "";
for (var i = 0, len = Math.min(orders.length, 1000); i < len; i++) {
for (
var i = 0, len = Math.min(orders.length, 1000); i < len; i++
) {
var order = orders[i]; var order = orders[i];
var orderline = this.order_cache.get_node(order.id || order.uid);
var orderline = this.order_cache.get_node(
order.id || order.uid);
if (!orderline) { if (!orderline) {
var orderline_html = QWeb.render('OrderLine', { var orderline_html = QWeb.render('OrderLine', {
widget: this, widget: this,
@ -116,7 +122,8 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
orderline = document.createElement('tbody'); orderline = document.createElement('tbody');
orderline.innerHTML = orderline_html; orderline.innerHTML = orderline_html;
orderline = orderline.childNodes[1]; orderline = orderline.childNodes[1];
this.order_cache.cache_node(order.id || order.uid, orderline);
this.order_cache.cache_node(
order.id || order.uid, orderline);
} }
if (order === this.old_order) { if (order === this.old_order) {
orderline.classList.add('highlight'); orderline.classList.add('highlight');
@ -130,54 +137,50 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
this.$('.order-list-return').off('click'); this.$('.order-list-return').off('click');
this.$('.order-list-reprint').off('click'); this.$('.order-list-reprint').off('click');
this.$('.order-list-copy').off('click'); this.$('.order-list-copy').off('click');
this.$('.order-list-return').click(function (event) {
self.order_list_actions(event, 'return');
});
this.$('.order-list-reprint').click(function (event) { this.$('.order-list-reprint').click(function (event) {
self.order_list_actions(event, 'print'); self.order_list_actions(event, 'print');
}); });
this.$('.order-list-copy').click(function(event) {
this.$('.order-list-copy').click(function (event) {
self.order_list_actions(event, 'copy'); 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) { order_list_actions: function (event, action) {
var self = this; var self = this;
var order_data;
var dataset = event.target.parentNode.dataset; var dataset = event.target.parentNode.dataset;
if (dataset.orderId) {
self.load_order_data(parseInt(dataset.orderId, 10))
.then(function(order_data) {
self.load_order_data(parseInt(dataset.orderId, 10))
.then(function (order_data) {
self.order_action(order_data, action); self.order_action(order_data, action);
})
} else {
_.each(this.orders, function (order_data) {
if (order.uid === dataset.uid) {
self.order_action(order_data, action);
}
}); });
}
}, },
order_action: function(order_data, action) {
this.gui.back();
this['action_' + action](order_data);
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) {
var order = this.load_order_from_data(order_data, true);
if (!order) return false;
// Restore the previous name
order.name = order_data.pos_reference || order_data.name;
var receipt = order.export_for_printing();
action_print: function (order_data, order) {
// We store temporarily the current order so we can safely compute // We store temporarily the current order so we can safely compute
// taxes based on fiscal position // taxes based on fiscal position
this.pos.current_order = this.pos.get_order()
this.pos.current_order = this.pos.get_order();
this.pos.set_order(order); this.pos.set_order(order);
if (this.pos.config.iface_print_via_proxy) { if (this.pos.config.iface_print_via_proxy) {
this.pos.proxy.print_receipt(QWeb.render( this.pos.proxy.print_receipt(QWeb.render(
'XmlReceipt', { 'XmlReceipt', {
receipt: receipt,
receipt: order.export_for_printing(),
widget: this, widget: this,
pos: this.pos, pos: this.pos,
order: order, order: order,
@ -193,57 +196,33 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
} }
}, },
action_copy: function(order_data) {
// Remove payments from original data
order_data.statement_ids = false;
var order = this.load_order_from_data(order_data, true);
if (!order) { return false; }
// If previous order was invoiced, we need a refund too
order.set_to_invoice(order_data.origin_invoice_id);
order.formatted_validation_date = false;
action_copy: function (order_data, order) {
order.trigger('change'); order.trigger('change');
this.pos.get('orders').add(order); this.pos.get('orders').add(order);
this.pos.set('selectedOrder', order); this.pos.set('selectedOrder', order);
return order; return order;
}, },
action_return: function (order_data) {
//var order_data = _.cloneDeep(order_data);
// Remove payments from original data
order_data.statement_ids = false;
// Invert line quantities
var order_lines = order_data.line_ids || order_data.lines || [];
_.each(order_lines, function(line) { line.qty = -1 * line.qty })
// Load from new data and change some stuff
var order = this.load_order_from_data(order_data);
if (!order) { return false; }
order.return = true;
order.name = _t("Refund ") + order.uid;;
order.origin_name = order_data.pos_reference || order.returned_order_id;
// If previous order was invoiced, we need a refund too
order.set_to_invoice(order_data.origin_invoice_id);
order.formatted_validation_date = false;
action_return: function (order_data, order) {
order.trigger('change'); order.trigger('change');
// Add to pos
this.pos.get('orders').add(order); this.pos.get('orders').add(order);
this.pos.set('selectedOrder', order); this.pos.set('selectedOrder', order);
return order; return order;
}, },
_prepare_order_from_order_data: function (order_data, temporary) {
_prepare_order_from_order_data: function (order_data, action) {
var self = this; var self = this;
var order = new pos.Order({}, { var order = new pos.Order({}, {
pos: this.pos, pos: this.pos,
temporary: !!temporary,
}); });
if (order_data.partner_id.length) {
order_data.partner_id = order_data.partner_id[0];
// Get Customer
if (order_data.partner_id) {
order.set_client(
this.pos.db.get_partner_by_id(order_data.partner_id));
} }
order.set_client(this.pos.db.get_partner_by_id(order_data.partner_id));
// Set fiscal position
// Get fiscal position
if (order_data.fiscal_position && this.pos.fiscal_positions) { if (order_data.fiscal_position && this.pos.fiscal_positions) {
var fiscal_positions = this.pos.fiscal_positions; var fiscal_positions = this.pos.fiscal_positions;
order.fiscal_position = fiscal_positions.filter(function (p) { order.fiscal_position = fiscal_positions.filter(function (p) {
@ -252,40 +231,71 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
order.trigger('change'); order.trigger('change');
} }
// Set order lines
var orderLines = order_data.line_ids || order_data.lines || [];
self._prepare_orderlines_from_order_data(order, order_data, orderLines);
// Get order lines
self._prepare_orderlines_from_order_data(
order, order_data, action);
if (order_data.returned_order_id) {
order.origin_name = order_data.returned_order_id;
// 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;
} }
order.formatted_validation_date = moment(order_data.date_order).format('YYYY-MM-DD HH:mm:ss');
// 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);
}
// Set Payment lines
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);
}
// 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; return order;
}, },
_prepare_orderlines_from_order_data: function(order, order_data, orderLines) {
_prepare_orderlines_from_order_data: function (
order, order_data, action) {
var orderLines = order_data.line_ids || order_data.lines || [];
var self = this; var self = this;
_.each(orderLines, function(line) {
_.each(orderLines, function (orderLine) {
var line = orderLine;
// In case of local data // In case of local data
if (line.length === 3) { if (line.length === 3) {
line = line[2]; line = line[2];
@ -295,10 +305,15 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
if (_.isUndefined(product)) { if (_.isUndefined(product)) {
self.unknown_products.push(String(line.product_id)); self.unknown_products.push(String(line.product_id));
} else { } else {
var qty = line.qty;
if (['return'].indexOf(action) !== -1) {
// Invert line quantities
qty *= -1;
}
// Create a new order line // Create a new order line
order.add_product(product, { order.add_product(product, {
price: line.price_unit, price: line.price_unit,
quantity: line.qty,
quantity: qty,
discount: line.discount, discount: line.discount,
merge: false, merge: false,
}); });
@ -306,13 +321,13 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
}); });
}, },
load_order_data: function(order_id) {
load_order_data: function (order_id) {
var self = this; var self = this;
return this._rpc({ return this._rpc({
model: 'pos.order', model: 'pos.order',
method: 'load_done_order_for_pos', method: 'load_done_order_for_pos',
args: [order_id], args: [order_id],
}).fail(function (error, event) {
}).fail(function (error) {
if (parseInt(error.code, 10) === 200) { if (parseInt(error.code, 10) === 200) {
// Business Logic Error, not a connection problem // Business Logic Error, not a connection problem
self.gui.show_popup( self.gui.show_popup(
@ -323,45 +338,33 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
} else { } else {
self.gui.show_popup('error', { self.gui.show_popup('error', {
'title': _t('Connection error'), 'title': _t('Connection error'),
'body': _t('Can not execute this action because the POS is currently offline'),
'body': _t(
'Can not execute this action because the POS' +
' is currently offline'),
}); });
} }
}); });
}, },
load_order_from_data: function(order_data) {
load_order_from_data: function (order_data, action) {
var self = this; var self = this;
this.unknown_products = []; this.unknown_products = [];
var order = self._prepare_order_from_order_data(order_data);
var order = self._prepare_order_from_order_data(
order_data, action);
// Forbid POS Order loading if some products are unknown // Forbid POS Order loading if some products are unknown
if (self.unknown_products.length > 0) { if (self.unknown_products.length > 0) {
self.gui.show_popup('error-traceback', { self.gui.show_popup('error-traceback', {
'title': _t('Unknown Products'), 'title': _t('Unknown Products'),
'body': _t('Unable to load some order lines because the ' + 'body': _t('Unable to load some order lines because the ' +
'products are not available in the POS cache.\n\n' + 'products are not available in the POS cache.\n\n' +
'Please check that lines :\n\n * ') + self.unknown_products.join("; \n *"),
'Please check that lines :\n\n * ') +
self.unknown_products.join("; \n *"),
}); });
return false; return false;
} }
return order; return order;
}, },
/* deprecated */
load_order: function (order_id) {
var self = this;
var done = new $.Deferred();
this.load_order_data(order_id)
.then(function(order_data) {
self.gui.show_screen('orderlist');
var order = self.load_order_from_data(order_data);
if (!order) { return done.fail(); }
done.resolve(order);
}).fail(function() {
done.fail();
});
return done;
},
// Search Part // Search Part
search_done_orders: function (query) { search_done_orders: function (query) {
var self = this; var self = this;
@ -371,6 +374,13 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
args: [query || '', this.pos.pos_session.id], args: [query || '', this.pos.pos_session.id],
}).then(function (result) { }).then(function (result) {
self.orders = 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) { }).fail(function (error, event) {
if (parseInt(error.code, 10) === 200) { if (parseInt(error.code, 10) === 200) {
// Business Logic Error, not a connection problem // Business Logic Error, not a connection problem
@ -383,17 +393,21 @@ odoo.define('pos_order_mgmt.widgets', function (require) {
} else { } else {
self.gui.show_popup('error', { self.gui.show_popup('error', {
'title': _t('Connection error'), 'title': _t('Connection error'),
'body': _t('Can not execute this action because the POS is currently offline'),
'body': _t(
'Can not execute this action because the POS' +
' is currently offline'),
}); });
} }
event.preventDefault(); event.preventDefault();
}); });
}, },
perform_search: function() {
perform_search: function () {
var self = this; var self = this;
return this.search_done_orders(self.search_query) return this.search_done_orders(self.search_query)
.done(function () { self.render_list(); });
.done(function () {
self.render_list();
});
}, },
clear_search: function () { clear_search: function () {

16
pos_order_mgmt/static/src/xml/pos.xml

@ -55,13 +55,13 @@
<td name="td_ol_date"><t t-esc='order.date_order' /></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_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'> <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'>
<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'/> <i class='fa fa-fw fa-print'/>
</span> </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'>
<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'/> <i class='fa fa-fw fa-copy'/>
</span> </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'>
<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'/> <i class='fa fa-fw fa-undo'/>
</span> </span>
</td> </td>
@ -69,18 +69,18 @@
</t> </t>
<t t-extend="OrderWidget"> <t t-extend="OrderWidget">
<t t-jquery=".order-scroller.touch-scrollable" t-operation="before">
<div class="order-returned-warning" t-if="order.return">
<span>Returned order: </span><t name="order-return-uid" t-esc="order.origin_name"></t>
<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> </div>
</t> </t>
</t> </t>
<t t-extend="PosTicket"> <t t-extend="PosTicket">
<t t-jquery="t[t-esc='order.name']" t-operation="after"> <t t-jquery="t[t-esc='order.name']" t-operation="after">
<t t-if="order.origin_name">
<t t-if="order.returned_order_id">
<br/> <br/>
<span name="order-origin-name">Rectifies: </span><t t-esc="order.origin_name"/>
<span name="returned-order-reference">Rectifies: </span><t t-esc="order.returned_order_reference"/>
</t> </t>
</t> </t>
<t t-jquery=".receipt-user" t-operation="after"> <t t-jquery=".receipt-user" t-operation="after">

1
pos_order_mgmt/tests/__init__.py

@ -0,0 +1 @@
from . import test_module

80
pos_order_mgmt/tests/test_module.py

@ -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

1
pos_order_mgmt/views/view_pos_config.xml

@ -6,7 +6,6 @@
<odoo> <odoo>
<record id="view_pos_config_form" model="ir.ui.view"> <record id="view_pos_config_form" model="ir.ui.view">
<field name="name">pos.config.form</field>
<field name="model">pos.config</field> <field name="model">pos.config</field>
<field name="inherit_id" ref="point_of_sale.pos_config_view_form"/> <field name="inherit_id" ref="point_of_sale.pos_config_view_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">

22
pos_order_mgmt/views/view_pos_order.xml

@ -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>
Loading…
Cancel
Save