-
144pos_meal_voucher/README.rst
-
1pos_meal_voucher/__init__.py
-
32pos_meal_voucher/__manifest__.py
-
18pos_meal_voucher/data/barcode_rule.xml
-
15pos_meal_voucher/demo/product_category.xml
-
18pos_meal_voucher/demo/product_product.xml
-
294pos_meal_voucher/i18n/fr.po
-
6pos_meal_voucher/models/__init__.py
-
24pos_meal_voucher/models/account_journal.py
-
13pos_meal_voucher/models/barcode_rule.py
-
18pos_meal_voucher/models/pos_config.py
-
19pos_meal_voucher/models/pos_order.py
-
22pos_meal_voucher/models/product_category.py
-
19pos_meal_voucher/models/product_template.py
-
24pos_meal_voucher/readme/CONFIGURE.rst
-
1pos_meal_voucher/readme/CONTRIBUTORS.rst
-
4pos_meal_voucher/readme/CREDITS.rst
-
5pos_meal_voucher/readme/DESCRIPTION.rst
-
6pos_meal_voucher/readme/ROADMAP.rst
-
33pos_meal_voucher/readme/USAGE.rst
-
BINpos_meal_voucher/static/description/account_journal_form.png
-
BINpos_meal_voucher/static/description/front_ui_pos_order_screen.png
-
BINpos_meal_voucher/static/description/front_ui_pos_payment_screen.png
-
BINpos_meal_voucher/static/description/front_ui_pos_payment_screen_summary.png
-
BINpos_meal_voucher/static/description/front_ui_pos_payment_screen_warning.png
-
BINpos_meal_voucher/static/description/issuer_1_up_dejeuner.jpg
-
BINpos_meal_voucher/static/description/issuer_2_ticket_restaurant.jpeg
-
BINpos_meal_voucher/static/description/issuer_3_apetiz.png
-
BINpos_meal_voucher/static/description/issuer_4_pass_restaurant.png
-
BINpos_meal_voucher/static/description/pos_config_form.png
-
BINpos_meal_voucher/static/description/product_category_form.png
-
BINpos_meal_voucher/static/description/product_product_form.png
-
65pos_meal_voucher/static/src/css/pos_meal_voucher.css
-
79pos_meal_voucher/static/src/js/models.js
-
158pos_meal_voucher/static/src/js/screens.js
-
82pos_meal_voucher/static/src/xml/pos_meal_voucher.xml
-
16pos_meal_voucher/views/templates.xml
-
23pos_meal_voucher/views/view_account_journal.xml
-
44pos_meal_voucher/views/view_pos_config.xml
-
24pos_meal_voucher/views/view_product_category.xml
-
19pos_meal_voucher/views/view_product_template.xml
@ -0,0 +1,144 @@ |
|||||
|
============================ |
||||
|
Point Of Sale - Meal Voucher |
||||
|
============================ |
||||
|
|
||||
|
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||||
|
!! 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-legalsylvain%2Fpos-lightgray.png?logo=github |
||||
|
:target: https://github.com/legalsylvain/pos/tree/12.0-ADD-pos_meal_voucher/pos_meal_voucher |
||||
|
:alt: legalsylvain/pos |
||||
|
|
||||
|
|badge1| |badge2| |badge3| |
||||
|
|
||||
|
This module extend the Point of Sale Odoo module, regarding Meal Vouchers. |
||||
|
|
||||
|
Meal voucher is a payment method, available in some countries (France, Belgium, Romania, ...) |
||||
|
that allows customer to buy food products in grocery stores or pay in restaurants. |
||||
|
|
||||
|
|
||||
|
**Table of contents** |
||||
|
|
||||
|
.. contents:: |
||||
|
:local: |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
Products |
||||
|
~~~~~~~~ |
||||
|
|
||||
|
* go to your products, and click on the 'Meal Voucher' checkbox, if your product |
||||
|
can be paid with meal vouchers. |
||||
|
|
||||
|
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/product_product_form.png |
||||
|
|
||||
|
* You can configure your product categories to have a default value for the products |
||||
|
that belong to this category. |
||||
|
|
||||
|
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/product_category_form.png |
||||
|
|
||||
|
* configures your Account journals, mentioning the type of Meal Voucher: |
||||
|
|
||||
|
- Paper : the journal will be used when scanning meal voucher barcodes |
||||
|
- Dematerialized: the journal will be used for dematerialized meal vouchers |
||||
|
- Mixed: Specific configuration if your accountant want to use a single journal for Credit card AND dematerialized meal vouchers. In that case, the button of this journal will be duplicated, and an extra text can be set to display an alternative label. |
||||
|
|
||||
|
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/account_journal_form.png |
||||
|
|
||||
|
* go your point of sale configuration form, and set the maximum amount allowed by ticket. (optional) |
||||
|
|
||||
|
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/pos_config_form.png |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
* Open your Point of Sale |
||||
|
|
||||
|
* Cashier can see the food products, eligible for meal voucher payment, and see the total for |
||||
|
Meal Voucher amount |
||||
|
|
||||
|
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/front_ui_pos_order_screen.png |
||||
|
|
||||
|
* go to the payment screen |
||||
|
|
||||
|
A Meal Voucher Summary is available: |
||||
|
|
||||
|
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/front_ui_pos_payment_screen.png |
||||
|
|
||||
|
If the amount received is too important, a warning icon is displayed |
||||
|
|
||||
|
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/front_ui_pos_payment_screen_summary.png |
||||
|
|
||||
|
If the cashier try to validate the order, a warning is also display, asking confirmation |
||||
|
|
||||
|
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/front_ui_pos_payment_screen_warning.png |
||||
|
|
||||
|
It is a non blocking warning, because we don't want to prevent an order to be done, |
||||
|
if products are not correctly set, or if a recent law changed the maximum amount that can |
||||
|
be used each day. (A recent case occured in France, during the Covid-19 pandemy) |
||||
|
|
||||
|
Note |
||||
|
~~~~ |
||||
|
|
||||
|
A new barcode rule is available for Paper Meal Voucher of 24 chars: |
||||
|
|
||||
|
``...........{NNNDD}........`` |
||||
|
|
||||
|
If you scan the following barcode ``052566641320080017000000``, a new payment line will be added, with an amount of 8,00€ (``00800``) |
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
* Introduce the Meal Voucher Issuer model |
||||
|
* When scaning Meal Voucher, deduce the Issuer |
||||
|
* Add a reporting to make easily the deposit of Meal Vouchers, per issuers. |
||||
|
* Add an option to add subtotal of products that can be paid with meal vouchers, |
||||
|
on the bill. |
||||
|
* Prevent to scan twice the same Meal Voucher barcode. |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues <https://github.com/legalsylvain/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/legalsylvain/pos/issues/new?body=module:%20pos_meal_voucher%0Aversion:%2012.0-ADD-pos_meal_voucher%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 |
||||
|
|
||||
|
Contributors |
||||
|
~~~~~~~~~~~~ |
||||
|
|
||||
|
* Sylvain LE GAL <https://twitter.com/legalsylvain> |
||||
|
|
||||
|
Other credits |
||||
|
~~~~~~~~~~~~~ |
||||
|
|
||||
|
The development of this module has been financially supported by: |
||||
|
|
||||
|
* Vracoop (https://portail.vracoop.fr/) |
||||
|
* Demain Supermarché (http://www.demainsupermarche.org/) |
||||
|
|
||||
|
Maintainers |
||||
|
~~~~~~~~~~~ |
||||
|
|
||||
|
This module is part of the `legalsylvain/pos <https://github.com/legalsylvain/pos/tree/12.0-ADD-pos_meal_voucher/pos_meal_voucher>`_ project on GitHub. |
||||
|
|
||||
|
You are welcome to contribute. |
@ -0,0 +1 @@ |
|||||
|
from . import models |
@ -0,0 +1,32 @@ |
|||||
|
# Copyright (C) 2020 - 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). |
||||
|
{ |
||||
|
"name": "Point Of Sale - Meal Voucher", |
||||
|
"summary": "Handle meal vouchers in Point of Sale" |
||||
|
" with eligible amount and max amount", |
||||
|
"version": "12.0.1.0.1", |
||||
|
"category": "Point of Sale", |
||||
|
"author": "GRAP, Odoo Community Association (OCA)", |
||||
|
"website": "http://www.github.com/OCA/pos", |
||||
|
"license": "AGPL-3", |
||||
|
"depends": [ |
||||
|
"point_of_sale", |
||||
|
], |
||||
|
"data": [ |
||||
|
"data/barcode_rule.xml", |
||||
|
"views/view_account_journal.xml", |
||||
|
"views/view_pos_config.xml", |
||||
|
"views/view_product_category.xml", |
||||
|
"views/view_product_template.xml", |
||||
|
"views/templates.xml", |
||||
|
], |
||||
|
"qweb": [ |
||||
|
"static/src/xml/pos_meal_voucher.xml", |
||||
|
], |
||||
|
"demo": [ |
||||
|
"demo/product_category.xml", |
||||
|
"demo/product_product.xml", |
||||
|
], |
||||
|
"installable": True, |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- |
||||
|
Copyright (C) 2020 - 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). |
||||
|
--> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="rule_meal_voucher" model="barcode.rule"> |
||||
|
<field name="name">Meal Voucher Payment</field> |
||||
|
<field name="barcode_nomenclature_id" ref="barcodes.default_barcode_nomenclature"/> |
||||
|
<field name="type">meal_voucher_payment</field> |
||||
|
<field name="encoding">any</field> |
||||
|
<field name="sequence">1</field> |
||||
|
<field name="pattern">...........{NNNDD}........</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,15 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- |
||||
|
Copyright (C) 2020 - 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). |
||||
|
--> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="food_category" model="product.category"> |
||||
|
<field name="name">Food</field> |
||||
|
<field name="parent_id" ref="point_of_sale.product_category_pos"/> |
||||
|
<field name="meal_voucher_ok" eval="True"/> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,18 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- |
||||
|
Copyright (C) 2020 - 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). |
||||
|
--> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="bread" model="product.product"> |
||||
|
<field name="name">Organic Wholemeal Bread</field> |
||||
|
<field name="categ_id" ref="food_category"/> |
||||
|
<field name="meal_voucher_ok" eval="True"/> |
||||
|
<field name="available_in_pos" eval="True"/> |
||||
|
<field name="available_in_pos" eval="True"/> |
||||
|
<field name="list_price">5.30</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,294 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * pos_meal_voucher |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 12.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2020-09-01 17:04+0000\n" |
||||
|
"PO-Revision-Date: 2020-09-01 17:04+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_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:29 |
||||
|
#, python-format |
||||
|
msgid "(Dematerialized)" |
||||
|
msgstr "(Dématérialisé)" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/js/screens.js:148 |
||||
|
#, python-format |
||||
|
msgid ", when the maximum amount is " |
||||
|
msgstr ", alors que le montant maximum est de " |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/js/screens.js:150 |
||||
|
#, python-format |
||||
|
msgid ".\n" |
||||
|
"\n" |
||||
|
" Clicking 'Confirm' will validate the payment." |
||||
|
msgstr ".\n" |
||||
|
"\n" |
||||
|
" Cliquer sur 'confirmer' validera le paiement." |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_pos_config_form |
||||
|
msgid "<span class=\"o_form_label\">Meal Voucher Amount</span>" |
||||
|
msgstr "<span class=\"o_form_label\">Montant de titre restaurant</span>" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Alias" |
||||
|
msgstr "Alias" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_product_category |
||||
|
msgid "Apply to all Products" |
||||
|
msgstr "Appliquer à tous les produitss" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model,name:pos_meal_voucher.model_barcode_rule |
||||
|
msgid "Barcode Rule" |
||||
|
msgstr "Règle de code barre" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Cashier" |
||||
|
msgstr "Caissier" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model.fields,help:pos_meal_voucher.field_product_product__meal_voucher_ok |
||||
|
#: model:ir.model.fields,help:pos_meal_voucher.field_product_template__meal_voucher_ok |
||||
|
msgid "Check this box if the product can be paid with meal vouchers." |
||||
|
msgstr "Cocher cette case si le produit peut être payé avec des titres restaurants." |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Client" |
||||
|
msgstr "Client" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:account.journal,meal_voucher_type:0 |
||||
|
msgid "Credit Card / Dematerialized" |
||||
|
msgstr "Carte bleue / Dématérialisé" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:account.journal,meal_voucher_type:0 |
||||
|
msgid "Dematerialized" |
||||
|
msgstr "Dématérialisé" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Discounted Product" |
||||
|
msgstr "Article en promotion" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__meal_voucher_display_product_screen |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_pos_config_form |
||||
|
msgid "Display icon before products on screen" |
||||
|
msgstr "Afficher une icone devant les produits" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:product.category,name:pos_meal_voucher.food_category |
||||
|
msgid "Food" |
||||
|
msgstr "Alimentaire" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_pos_config_form |
||||
|
msgid "If checked, an icon will be displayed on the screen, before each product that can be paid with meal vouchers." |
||||
|
msgstr "Si la case est cochée, une icône sera affiché sur l'écran du point de vente, avant chaque produit éligible au paiement par titre restaurant." |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model.fields,help:pos_meal_voucher.field_product_category__meal_voucher_ok |
||||
|
msgid "If checked, the products that belong to the category will be marked as 'can be paid with meal vouchers', by default." |
||||
|
msgstr "Si la case est cochée, les produits qui appartiennent à cette catégorie seront marqués comme 'Peuvent être payé en titre restaurant', par défaut." |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model,name:pos_meal_voucher.model_account_journal |
||||
|
msgid "Journal" |
||||
|
msgstr "Journal" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Location" |
||||
|
msgstr "Lieu" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Lot" |
||||
|
msgstr "Lot" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:52 |
||||
|
#, python-format |
||||
|
msgid "Max Amount" |
||||
|
msgstr "Montant maximum" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_pos_config_form |
||||
|
msgid "Maximum amount of Meal Vouchers that can be received for a PoS Order.\n" |
||||
|
" Let 0, if you don't want to enable this check." |
||||
|
msgstr "Montant total de titres restaurant qui peuvent être encaissé pour une vente.\n" |
||||
|
" Laisser vide si vous ne souhaitez pas activer cette vérification." |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:39 |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_product_category__meal_voucher_ok |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_product_product__meal_voucher_ok |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_product_template__meal_voucher_ok |
||||
|
#, python-format |
||||
|
msgid "Meal Voucher" |
||||
|
msgstr "Titre restaurant" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__max_meal_voucher_amount |
||||
|
msgid "Meal Voucher Amount" |
||||
|
msgstr "Montant de titre restaurant" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Meal Voucher Payment" |
||||
|
msgstr "Paiement en titre restaurant" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_account_bank_statement_import_journal_creation__meal_voucher_type |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_account_journal__meal_voucher_type |
||||
|
msgid "Meal Voucher Type" |
||||
|
msgstr "Type de titre restaurant" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:16 |
||||
|
#, python-format |
||||
|
msgid "Meal Voucher:" |
||||
|
msgstr "Titre restaurant :" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_pos_config_form |
||||
|
msgid "Meal Vouchers" |
||||
|
msgstr "Titres Restaurant" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:product.product,name:pos_meal_voucher.bread |
||||
|
#: model:product.template,name:pos_meal_voucher.bread_product_template |
||||
|
msgid "Organic Wholemeal Bread" |
||||
|
msgstr "Pain complet biologique" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Package" |
||||
|
msgstr "Colis" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:account.journal,meal_voucher_type:0 |
||||
|
msgid "Paper" |
||||
|
msgstr "Papier" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/js/screens.js:145 |
||||
|
#, python-format |
||||
|
msgid "Please Confirm Meal Voucher Amount" |
||||
|
msgstr "Veuillez confirmer le montant en titre restaurant" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model,name:pos_meal_voucher.model_pos_config |
||||
|
msgid "Point of Sale Configuration" |
||||
|
msgstr "Paramétrage du point de vente" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model,name:pos_meal_voucher.model_pos_order |
||||
|
msgid "Point of Sale Orders" |
||||
|
msgstr "Commandes du point de vente" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Priced Product" |
||||
|
msgstr "Article à prix fixe" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model,name:pos_meal_voucher.model_product_category |
||||
|
msgid "Product Category" |
||||
|
msgstr "Catégorie d'article" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model,name:pos_meal_voucher.model_product_template |
||||
|
msgid "Product Template" |
||||
|
msgstr "Modèle d'article" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_account_bank_statement_import_journal_creation__meal_voucher_mixed_text |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_account_journal__meal_voucher_mixed_text |
||||
|
msgid "Text for Mixed Journal" |
||||
|
msgstr "Texte pour le journal mixte" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model.fields,help:pos_meal_voucher.field_account_bank_statement_import_journal_creation__meal_voucher_mixed_text |
||||
|
#: model:ir.model.fields,help:pos_meal_voucher.field_account_journal__meal_voucher_mixed_text |
||||
|
msgid "Text that will be displayed in the point of sale if the journal is a mixed journal (Credit Card / Dematerialized) for the dematerialized button." |
||||
|
msgstr "Ce texte sera affiché dans le point de vente, pour le journal de type 'mixte' (Carte bleue / Dématérialisé) pour le bouton correspondant au paiement dématérialisé" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:44 |
||||
|
#, python-format |
||||
|
msgid "Total Eligible" |
||||
|
msgstr "Total éligible" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:60 |
||||
|
#, python-format |
||||
|
msgid "Total Received" |
||||
|
msgstr "Total encaissé" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:ir.model.fields,field_description:pos_meal_voucher.field_barcode_rule__type |
||||
|
msgid "Type" |
||||
|
msgstr "Type" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Unit Product" |
||||
|
msgstr "Unité de produit" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:product.product,uom_name:pos_meal_voucher.bread |
||||
|
#: model:product.template,uom_name:pos_meal_voucher.bread_product_template |
||||
|
msgid "Unit(s)" |
||||
|
msgstr "Unité(s)" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: selection:barcode.rule,type:0 |
||||
|
msgid "Weighted Product" |
||||
|
msgstr "Article pesé" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_meal_voucher/static/src/js/screens.js:146 |
||||
|
#, python-format |
||||
|
msgid "You are about to validate a meal voucher payment of " |
||||
|
msgstr "Vous êtes sur le point de valider un paiement en titre restaurant d'un montant de " |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_product_category |
||||
|
msgid "by clicking on this button, all the products of this category will have the same settings than the current category, for the value 'Meal Voucher'" |
||||
|
msgstr "En cliquant sur ce bouton, tous les produits de cette catégories auront le même paramétrage que cette catégorie, pour la valeur 'Titre Restaurant'" |
||||
|
|
||||
|
#. module: pos_meal_voucher |
||||
|
#: model:product.product,weight_uom_name:pos_meal_voucher.bread |
||||
|
#: model:product.template,weight_uom_name:pos_meal_voucher.bread_product_template |
||||
|
msgid "kg" |
||||
|
msgstr "kg" |
||||
|
|
@ -0,0 +1,6 @@ |
|||||
|
from . import account_journal |
||||
|
from . import barcode_rule |
||||
|
from . import pos_config |
||||
|
from . import pos_order |
||||
|
from . import product_category |
||||
|
from . import product_template |
@ -0,0 +1,24 @@ |
|||||
|
# Copyright (C) 2020 - 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, models |
||||
|
|
||||
|
|
||||
|
class AccountJournal(models.Model): |
||||
|
_inherit = 'account.journal' |
||||
|
|
||||
|
meal_voucher_type = fields.Selection( |
||||
|
string="Meal Voucher Type", |
||||
|
selection=[ |
||||
|
("paper", "Paper"), |
||||
|
("dematerialized", "Dematerialized"), |
||||
|
("mixed", "Credit Card / Dematerialized"), |
||||
|
], |
||||
|
) |
||||
|
|
||||
|
meal_voucher_mixed_text = fields.Char( |
||||
|
string="Text for Mixed journal", |
||||
|
help="Text that will be displayed in the point of sale" |
||||
|
" if the journal is a mixed journal (Credit Card / " |
||||
|
" Dematerialized) for the dematerialized button.") |
@ -0,0 +1,13 @@ |
|||||
|
# Copyright (C) 2020 - 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, models |
||||
|
|
||||
|
|
||||
|
class BarcodeRule(models.Model): |
||||
|
_inherit = "barcode.rule" |
||||
|
|
||||
|
type = fields.Selection(selection_add=[ |
||||
|
("meal_voucher_payment", "Meal Voucher Payment") |
||||
|
]) |
@ -0,0 +1,18 @@ |
|||||
|
# Copyright (C) 2020 - 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, models |
||||
|
|
||||
|
|
||||
|
class PosConfig(models.Model): |
||||
|
_inherit = 'pos.config' |
||||
|
|
||||
|
max_meal_voucher_amount = fields.Monetary( |
||||
|
string="Meal Voucher Amount", |
||||
|
currency_field="currency_id", |
||||
|
) |
||||
|
|
||||
|
meal_voucher_display_product_screen = fields.Boolean( |
||||
|
string="Display icon before products on screen", |
||||
|
default=True) |
@ -0,0 +1,19 @@ |
|||||
|
# Copyright (C) 2020 - 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 models |
||||
|
|
||||
|
|
||||
|
class PosOrder(models.Model): |
||||
|
_inherit = 'pos.order' |
||||
|
|
||||
|
def _payment_fields(self, ui_paymentline): |
||||
|
res = super()._payment_fields(ui_paymentline) |
||||
|
res["statement_note"] = ui_paymentline.get("statement_note", False) |
||||
|
return res |
||||
|
|
||||
|
def _prepare_bank_statement_line_payment_values(self, data): |
||||
|
res = super()._prepare_bank_statement_line_payment_values(data) |
||||
|
res["note"] = data.get("statement_note", False) |
||||
|
return res |
@ -0,0 +1,22 @@ |
|||||
|
# Copyright (C) 2020 - 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, models |
||||
|
|
||||
|
|
||||
|
class ProductCategory(models.Model): |
||||
|
_inherit = 'product.category' |
||||
|
|
||||
|
meal_voucher_ok = fields.Boolean( |
||||
|
string="Meal Voucher", |
||||
|
help="If checked, the products that belong to the category" |
||||
|
" will be marked as 'can be paid with meal vouchers', by default." |
||||
|
) |
||||
|
|
||||
|
def button_apply_meal_voucher_settings(self): |
||||
|
ProductTemplate = self.env["product.template"] |
||||
|
for category in self: |
||||
|
templates = ProductTemplate.with_context( |
||||
|
active_test=False).search([('categ_id', '=', category.id)]) |
||||
|
templates.write({"meal_voucher_ok": category.meal_voucher_ok}) |
@ -0,0 +1,19 @@ |
|||||
|
# Copyright (C) 2020 - 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 api, fields, models |
||||
|
|
||||
|
|
||||
|
class ProductTemplate(models.Model): |
||||
|
_inherit = 'product.template' |
||||
|
|
||||
|
meal_voucher_ok = fields.Boolean( |
||||
|
string="Meal Voucher", |
||||
|
help="Check this box if the product can be paid with meal vouchers." |
||||
|
) |
||||
|
|
||||
|
@api.onchange("categ_id") |
||||
|
def onchange_categ_id(self): |
||||
|
for template in self: |
||||
|
template.meal_voucher_ok = template.categ_id.meal_voucher_ok |
@ -0,0 +1,24 @@ |
|||||
|
Products |
||||
|
~~~~~~~~ |
||||
|
|
||||
|
* go to your products, and click on the 'Meal Voucher' checkbox, if your product |
||||
|
can be paid with meal vouchers. |
||||
|
|
||||
|
.. figure:: ../static/description/product_product_form.png |
||||
|
|
||||
|
* You can configure your product categories to have a default value for the products |
||||
|
that belong to this category. |
||||
|
|
||||
|
.. figure:: ../static/description/product_category_form.png |
||||
|
|
||||
|
* configures your Account journals, mentioning the type of Meal Voucher: |
||||
|
|
||||
|
- Paper : the journal will be used when scanning meal voucher barcodes |
||||
|
- Dematerialized: the journal will be used for dematerialized meal vouchers |
||||
|
- Mixed: Specific configuration if your accountant want to use a single journal for Credit card AND dematerialized meal vouchers. In that case, the button of this journal will be duplicated, and an extra text can be set to display an alternative label. |
||||
|
|
||||
|
.. figure:: ../static/description/account_journal_form.png |
||||
|
|
||||
|
* go your point of sale configuration form, and set the maximum amount allowed by ticket. (optional) |
||||
|
|
||||
|
.. figure:: ../static/description/pos_config_form.png |
@ -0,0 +1 @@ |
|||||
|
* Sylvain LE GAL <https://twitter.com/legalsylvain> |
@ -0,0 +1,4 @@ |
|||||
|
The development of this module has been financially supported by: |
||||
|
|
||||
|
* Vracoop (https://portail.vracoop.fr/) |
||||
|
* Demain Supermarché (http://www.demainsupermarche.org/) |
@ -0,0 +1,5 @@ |
|||||
|
This module extend the Point of Sale Odoo module, regarding Meal Vouchers. |
||||
|
|
||||
|
Meal voucher is a payment method, available in some countries (France, Belgium, Romania, ...) |
||||
|
that allows customer to buy food products in grocery stores or pay in restaurants. |
||||
|
|
@ -0,0 +1,6 @@ |
|||||
|
* Introduce the Meal Voucher Issuer model |
||||
|
* When scaning Meal Voucher, deduce the Issuer |
||||
|
* Add a reporting to make easily the deposit of Meal Vouchers, per issuers. |
||||
|
* Add an option to add subtotal of products that can be paid with meal vouchers, |
||||
|
on the bill. |
||||
|
* Prevent to scan twice the same Meal Voucher barcode. |
@ -0,0 +1,33 @@ |
|||||
|
* Open your Point of Sale |
||||
|
|
||||
|
* Cashier can see the food products, eligible for meal voucher payment, and see the total for |
||||
|
Meal Voucher amount |
||||
|
|
||||
|
.. figure:: ../static/description/front_ui_pos_order_screen.png |
||||
|
|
||||
|
* go to the payment screen |
||||
|
|
||||
|
A Meal Voucher Summary is available: |
||||
|
|
||||
|
.. figure:: ../static/description/front_ui_pos_payment_screen.png |
||||
|
|
||||
|
If the amount received is too important, a warning icon is displayed |
||||
|
|
||||
|
.. figure:: ../static/description/front_ui_pos_payment_screen_summary.png |
||||
|
|
||||
|
If the cashier try to validate the order, a warning is also display, asking confirmation |
||||
|
|
||||
|
.. figure:: ../static/description/front_ui_pos_payment_screen_warning.png |
||||
|
|
||||
|
It is a non blocking warning, because we don't want to prevent an order to be done, |
||||
|
if products are not correctly set, or if a recent law changed the maximum amount that can |
||||
|
be used each day. (A recent case occured in France, during the Covid-19 pandemy) |
||||
|
|
||||
|
Note |
||||
|
~~~~ |
||||
|
|
||||
|
A new barcode rule is available for Paper Meal Voucher of 24 chars: |
||||
|
|
||||
|
``...........{NNNDD}........`` |
||||
|
|
||||
|
If you scan the following barcode ``052566641320080017000000``, a new payment line will be added, with an amount of 8,00€ (``00800``) |
After Width: 766 | Height: 330 | Size: 18 KiB |
After Width: 432 | Height: 332 | Size: 24 KiB |
After Width: 1006 | Height: 481 | Size: 53 KiB |
After Width: 352 | Height: 181 | Size: 11 KiB |
After Width: 494 | Height: 245 | Size: 17 KiB |
After Width: 1280 | Height: 720 | Size: 25 KiB |
After Width: 2048 | Height: 534 | Size: 66 KiB |
After Width: 396 | Height: 398 | Size: 15 KiB |
After Width: 288 | Height: 175 | Size: 5.1 KiB |
After Width: 482 | Height: 99 | Size: 6.7 KiB |
After Width: 763 | Height: 213 | Size: 12 KiB |
After Width: 734 | Height: 389 | Size: 24 KiB |
@ -0,0 +1,65 @@ |
|||||
|
.pos .order .summary .line .meal-voucher{ |
||||
|
font-size: 16px; |
||||
|
font-weight: normal; |
||||
|
text-align: center; |
||||
|
font-style:italic; |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
.pos .paymentline .is-meal-voucher{ |
||||
|
cursor: pointer; |
||||
|
text-align: center; |
||||
|
padding-top: 0px; |
||||
|
padding-bottom: 0px; |
||||
|
background-color: #f0eeee; |
||||
|
} |
||||
|
|
||||
|
.pos .paymentline .is-meal-voucher .fa-cutlery{ |
||||
|
border-radius: 20px; |
||||
|
border: 1px solid rgba(0,0,0,0.2); |
||||
|
font-size: 20px; |
||||
|
width: 40px; |
||||
|
height: 30px; |
||||
|
line-height: 30px; |
||||
|
vertical-align: 0%; |
||||
|
color:#AAA; |
||||
|
background-color: #FFF; |
||||
|
} |
||||
|
|
||||
|
.payment-screen .paymentmethods .fa-cutlery{ |
||||
|
width: 48px; |
||||
|
height: 48px; |
||||
|
line-height: 48px; |
||||
|
margin-top: -25px; |
||||
|
font-size: 20px; |
||||
|
border-radius: 26px; |
||||
|
border: 1px solid rgba(0,0,0,0.2); |
||||
|
background: rgba(255,255,255,0.4); |
||||
|
} |
||||
|
|
||||
|
.payment-screen div.meal-voucher-summary{ |
||||
|
border-top: dashed 1px gainsboro; |
||||
|
} |
||||
|
|
||||
|
.payment-screen div.meal-voucher-summary .fa-warning{ |
||||
|
color: red; |
||||
|
} |
||||
|
|
||||
|
.payment-screen div.meal-voucher-summary table{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.payment-screen div.meal-voucher-summary tbody{ |
||||
|
background: white; |
||||
|
} |
||||
|
|
||||
|
.payment-screen div.meal-voucher-summary th { |
||||
|
font-size: 16px; |
||||
|
padding: 8px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.payment-screen div.meal-voucher-summary td { |
||||
|
font-size: 22px; |
||||
|
padding: 8px 12px; |
||||
|
} |
||||
|
|
@ -0,0 +1,79 @@ |
|||||
|
// Copyright (C) 2020 - 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).
|
||||
|
|
||||
|
odoo.define("pos_meal_voucher.models", function (require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var models = require("point_of_sale.models"); |
||||
|
var utils = require("web.utils"); |
||||
|
|
||||
|
var round_pr = utils.round_precision; |
||||
|
|
||||
|
models.load_fields("product.product", ["meal_voucher_ok"]); |
||||
|
|
||||
|
models.load_fields("account.journal", ["meal_voucher_type", "meal_voucher_mixed_text"]); |
||||
|
|
||||
|
var OrderSuper = models.Order.prototype; |
||||
|
var Order = models.Order.extend({ |
||||
|
|
||||
|
get_total_meal_voucher_eligible: function() { |
||||
|
return round_pr(this.orderlines.reduce((function(sum, orderLine) { |
||||
|
if (orderLine.product.meal_voucher_ok){ |
||||
|
return sum + orderLine.get_price_with_tax(); |
||||
|
} else { |
||||
|
return sum; |
||||
|
} |
||||
|
}), 0), this.pos.currency.rounding); |
||||
|
}, |
||||
|
get_total_meal_voucher_received: function(){ |
||||
|
return round_pr(this.paymentlines.reduce((function(sum, paymentLine) { |
||||
|
if (paymentLine.is_meal_voucher()) { |
||||
|
return sum + paymentLine.get_amount(); |
||||
|
} else { |
||||
|
return sum; |
||||
|
} |
||||
|
}), 0), this.pos.currency.rounding); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
models.Order = Order; |
||||
|
|
||||
|
var PaymentlineSuper = models.Paymentline.prototype; |
||||
|
|
||||
|
var Paymentline = models.Paymentline.extend({ |
||||
|
|
||||
|
initialize: function(){ |
||||
|
PaymentlineSuper.initialize.apply(this, arguments); |
||||
|
// We use 'payment_note', because 'note' field is still used
|
||||
|
// to set in the payment_name value.
|
||||
|
// See odoo/addons/point_of_sale/models/pos_order.py:59
|
||||
|
// and then in the name of the statement line.
|
||||
|
// See odoo/addons/point_of_sale/models/pos_order.py:950
|
||||
|
this.statement_note = ''; |
||||
|
this.manual_meal_voucher = false; |
||||
|
}, |
||||
|
|
||||
|
init_from_JSON: function (json) { |
||||
|
PaymentlineSuper.init_from_JSON.apply(this, arguments); |
||||
|
this.statement_note = json.statement_note; |
||||
|
}, |
||||
|
export_as_JSON: function () { |
||||
|
var res = PaymentlineSuper.export_as_JSON.apply(this, arguments); |
||||
|
res.statement_note = this.statement_note; |
||||
|
return res; |
||||
|
}, |
||||
|
|
||||
|
is_meal_voucher: function() { |
||||
|
return ( |
||||
|
this.manual_meal_voucher === true || |
||||
|
["paper", "dematerialized"].indexOf( |
||||
|
this.cashregister.journal.meal_voucher_type) !== -1 |
||||
|
) |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
models.Paymentline = Paymentline; |
||||
|
|
||||
|
}); |
@ -0,0 +1,158 @@ |
|||||
|
// Copyright (C) 2020 - 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).
|
||||
|
|
||||
|
odoo.define("pos_meal_voucher.screens", function (require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var screens = require("point_of_sale.screens"); |
||||
|
|
||||
|
screens.ScreenWidget.include({ |
||||
|
barcode_meal_voucher_payment_action: function (code) { |
||||
|
|
||||
|
// Display the payment screen, if it is not the current one.
|
||||
|
if (this.pos.gui.current_screen.template !== "PaymentScreenWidget"){ |
||||
|
this.gui.show_screen("payment"); |
||||
|
} |
||||
|
var paymentScreen = this.pos.gui.current_screen; |
||||
|
var order = this.pos.get_order(); |
||||
|
var amount = code.value; |
||||
|
var cashregister = null; |
||||
|
// find a meal voucher cash register, if exist
|
||||
|
for ( var i = 0; i < this.pos.cashregisters.length; i++ ) { |
||||
|
if ( this.pos.cashregisters[i].journal.meal_voucher_type === "paper" ){ |
||||
|
cashregister = this.pos.cashregisters[i]; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (!cashregister){ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// Add new payment line with the amount found in the barcode
|
||||
|
this.pos.get_order().add_paymentline(cashregister); |
||||
|
paymentScreen.reset_input() |
||||
|
order.selected_paymentline.set_amount(amount); |
||||
|
order.selected_paymentline.statement_note = code.code; |
||||
|
paymentScreen.order_changes(); |
||||
|
paymentScreen.render_paymentlines(); |
||||
|
paymentScreen.$(".paymentline.selected .edit").text(paymentScreen.format_currency_no_symbol(amount)); |
||||
|
}, |
||||
|
|
||||
|
// Setup the callback action for the "meal_voucher_payment" barcodes.
|
||||
|
show: function () { |
||||
|
this._super(); |
||||
|
this.pos.barcode_reader.set_action_callback( |
||||
|
"meal_voucher_payment", |
||||
|
_.bind(this.barcode_meal_voucher_payment_action, this)); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
screens.OrderWidget.include({ |
||||
|
update_summary: function () { |
||||
|
this._super.apply(this, arguments); |
||||
|
var order = this.pos.get_order(); |
||||
|
if (!order.get_orderlines().length) { |
||||
|
return; |
||||
|
} |
||||
|
this.el.querySelector(".summary .meal-voucher .value").textContent = this.format_currency(order.get_total_meal_voucher_eligible()); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
screens.PaymentScreenWidget.include({ |
||||
|
|
||||
|
click_paymentmethods_meal_voucher_mixed: function(id) { |
||||
|
var cashregister = null; |
||||
|
for ( var i = 0; i < this.pos.cashregisters.length; i++ ) { |
||||
|
if ( this.pos.cashregisters[i].journal_id[0] === id ){ |
||||
|
cashregister = this.pos.cashregisters[i]; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
this.pos.get_order().add_paymentline( cashregister ); |
||||
|
// manually set meal voucher
|
||||
|
this.pos.get_order().selected_paymentline.manual_meal_voucher = true; |
||||
|
this.reset_input(); |
||||
|
this.render_paymentlines(); |
||||
|
}, |
||||
|
|
||||
|
render_paymentmethods: function() { |
||||
|
var self = this; |
||||
|
var methods = this._super.apply(this, arguments); |
||||
|
methods.on('click','.paymentmethod-meal-voucher-mixed',function(){ |
||||
|
self.click_paymentmethods_meal_voucher_mixed($(this).data('id')); |
||||
|
}); |
||||
|
return methods; |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
render_paymentlines: function() { |
||||
|
var self = this; |
||||
|
|
||||
|
this._super.apply(this, arguments); |
||||
|
var order = this.pos.get_order(); |
||||
|
if (!order) { |
||||
|
return; |
||||
|
} |
||||
|
// Update meal voucher summary
|
||||
|
var total_eligible = order.get_total_meal_voucher_eligible(); |
||||
|
this.el.querySelector("#meal-voucher-eligible-amount").textContent = this.format_currency(total_eligible); |
||||
|
|
||||
|
var max_amount = this.pos.config.max_meal_voucher_amount; |
||||
|
if (max_amount !== 0) { |
||||
|
this.el.querySelector("#meal-voucher-max-amount").textContent = this.format_currency(max_amount); |
||||
|
} |
||||
|
var total_received = order.get_total_meal_voucher_received(); |
||||
|
this.el.querySelector("#meal-voucher-received-amount").textContent = this.format_currency(total_received); |
||||
|
|
||||
|
// Display warnings
|
||||
|
if (total_received > total_eligible) { |
||||
|
this.$("#meal-voucher-eligible-warning").removeClass("oe_hidden"); |
||||
|
} else { |
||||
|
this.$("#meal-voucher-eligible-warning").addClass("oe_hidden"); |
||||
|
} |
||||
|
if (total_received > max_amount) { |
||||
|
this.$("#meal-voucher-max-warning").removeClass("oe_hidden"); |
||||
|
} else { |
||||
|
this.$("#meal-voucher-max-warning").addClass("oe_hidden"); |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
order_is_valid: function(force_validation) { |
||||
|
var self = this; |
||||
|
var order = this.pos.get_order(); |
||||
|
|
||||
|
var total_eligible = order.get_total_meal_voucher_eligible(); |
||||
|
var total_received = order.get_total_meal_voucher_received(); |
||||
|
var max_amount = this.pos.config.max_meal_voucher_amount; |
||||
|
|
||||
|
var current_max = total_eligible; |
||||
|
if (max_amount) { |
||||
|
current_max = Math.min(total_eligible, max_amount); |
||||
|
} |
||||
|
|
||||
|
// if the change is too large, it's probably an input error, make the user confirm.
|
||||
|
if (!force_validation && (total_received > current_max)) { |
||||
|
this.gui.show_popup("confirm", { |
||||
|
title: _t("Please Confirm Meal Voucher Amount"), |
||||
|
body: _t("You are about to validate a meal voucher payment of ") + |
||||
|
this.format_currency(total_received) + |
||||
|
_t(", when the maximum amount is ") + |
||||
|
this.format_currency(current_max) + |
||||
|
_t(".\n\n Clicking 'Confirm' will validate the payment."), |
||||
|
confirm: function() { |
||||
|
// Note: Due to the bad design of the original function
|
||||
|
// the check "Large Amount" will be skipped in that case.
|
||||
|
self.validate_order("confirm"); |
||||
|
}, |
||||
|
}); |
||||
|
return false; |
||||
|
} |
||||
|
return this._super.apply(this, arguments);; |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
}); |
@ -0,0 +1,82 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates id="template" xml:space="preserve"> |
||||
|
|
||||
|
<t t-extend="Orderline"> |
||||
|
<t t-jquery=".product-name" t-operation="prepend"> |
||||
|
<t t-if="line.get_product().meal_voucher_ok === true && |
||||
|
widget.pos.config.meal_voucher_display_product_screen"> |
||||
|
<i class="fa fa-lg fa-cutlery"/> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
<t t-extend="OrderWidget"> |
||||
|
<t t-jquery="div.line" t-operation="append"> |
||||
|
<div class="meal-voucher"> |
||||
|
(<span>Meal Voucher: </span> <span class="value">0.00 €</span>) |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
<t t-extend="PaymentScreen-Paymentmethods"> |
||||
|
<t t-jquery="div.paymentmethod" t-operation="after"> |
||||
|
<t t-if="['mixed'].indexOf(cashregister.journal.meal_voucher_type) !== -1"> |
||||
|
<div class="button paymentmethod-meal-voucher-mixed" t-att-data-id="cashregister.journal_id[0]"> |
||||
|
<t t-if="cashregister.journal.meal_voucher_mixed_text"> |
||||
|
<t t-esc="cashregister.journal.meal_voucher_mixed_text" /> |
||||
|
</t> |
||||
|
<t t-else=""> |
||||
|
<t t-esc="cashregister.journal_id[1]" /> (Dematerialized) |
||||
|
</t> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
<t t-jquery="div.paymentmethods" t-operation="after"> |
||||
|
<div class="meal-voucher-summary"> |
||||
|
<table class="meal-voucher-summary"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th colspan="2">Meal Voucher</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td>Total Eligible</td> |
||||
|
<td> |
||||
|
<span id="meal-voucher-eligible-amount">0.00 €</span> |
||||
|
<i id="meal-voucher-eligible-warning" class="fa fa-warning"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<t t-if="widget.pos.config.max_meal_voucher_amount !== 0"> |
||||
|
<tr> |
||||
|
<td>Max Amount</td> |
||||
|
<td> |
||||
|
<span id="meal-voucher-max-amount">0.00 €</span> |
||||
|
<i id="meal-voucher-max-warning" class="fa fa-warning"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
<tr> |
||||
|
<td>Total Received</td> |
||||
|
<td> |
||||
|
<span id="meal-voucher-received-amount">0.00 €</span> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
<t t-extend="PaymentScreen-Paymentlines"> |
||||
|
<t t-jquery="td.delete-button" t-operation="after"> |
||||
|
<t t-if="['paper', 'dematerialized'].indexOf(line.cashregister.journal.meal_voucher_type) !== -1 || |
||||
|
line.manual_meal_voucher === true"> |
||||
|
<td class="is-meal-voucher"> |
||||
|
<i class="fa fa-lg fa-cutlery" /> |
||||
|
</td> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
</templates> |
@ -0,0 +1,16 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- |
||||
|
Copyright (C) 2020 - 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). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
<template id="assets" inherit_id="point_of_sale.assets"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<link rel="stylesheet" href="/pos_meal_voucher/static/src/css/pos_meal_voucher.css"/> |
||||
|
<script type="text/javascript" src="/pos_meal_voucher/static/src/js/models.js"></script> |
||||
|
<script type="text/javascript" src="/pos_meal_voucher/static/src/js/screens.js"></script> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,23 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- |
||||
|
Copyright (C) 2020 - 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). |
||||
|
--> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_account_journal" model="ir.ui.view"> |
||||
|
<field name="model">account.journal</field> |
||||
|
<field name="inherit_id" ref="point_of_sale.view_account_journal_pos_user_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<group name="amount_authorized" position="after"> |
||||
|
<group> |
||||
|
<field name="meal_voucher_type"/> |
||||
|
<field name="meal_voucher_mixed_text" |
||||
|
attrs="{'invisible': [('meal_voucher_type', '!=', 'mixed')]}"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,44 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- |
||||
|
Copyright (C) 2020 - 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). |
||||
|
--> |
||||
|
<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='payment_methods']/.." position="after"> |
||||
|
<h2>Meal Vouchers</h2> |
||||
|
<div class="row mt16 o_settings_container"> |
||||
|
<div class="col-12 col-lg-6 o_setting_box"> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<span class="o_form_label">Meal Voucher Amount</span> |
||||
|
<div class="text-muted"> |
||||
|
Maximum amount of Meal Vouchers that can be received for a PoS Order. |
||||
|
Let 0, if you don't want to enable this check. |
||||
|
</div> |
||||
|
<div class="content-group mt16"> |
||||
|
<field name="max_meal_voucher_amount" colspan="4" nolabel="1"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-12 col-lg-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
<field name="meal_voucher_display_product_screen"/> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="meal_voucher_display_product_screen" string="Display icon before products on screen"/> |
||||
|
<div class="text-muted"> |
||||
|
If checked, an icon will be displayed on the screen, before each product that can be paid with meal vouchers. |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,24 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- |
||||
|
Copyright (C) 2020 - 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). |
||||
|
--> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_product_category" model="ir.ui.view"> |
||||
|
<field name="model">product.category</field> |
||||
|
<field name="inherit_id" ref="product.product_category_form_view"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="parent_id" position="after"> |
||||
|
<field name="meal_voucher_ok"/> |
||||
|
<button type="object" |
||||
|
name="button_apply_meal_voucher_settings" |
||||
|
string="Apply to all Products" |
||||
|
help="by clicking on this button, all the products of this category will have the same settings than the current category, for the value 'Meal Voucher'" |
||||
|
icon="fa-cogs" colspan="2"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,19 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!-- |
||||
|
Copyright (C) 2020 - 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). |
||||
|
--> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_product_template" model="ir.ui.view"> |
||||
|
<field name="model">product.template</field> |
||||
|
<field name="inherit_id" ref="point_of_sale.product_template_form_view"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="to_weight" position="after"> |
||||
|
<field name="meal_voucher_ok"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |