Move all OCA POS modules from oca-technical to dedicated oca-pos submodule

Reorganized 74 POS-related modules for better structure:
- Moved all odoo-bringout-oca-pos-* packages from packages/oca-technical/
- Now organized in dedicated packages/oca-pos/ submodule
- Includes payment, receipt, loyalty, order, product, and partner modules
- Maintains all module functionality while improving project organization

This creates a cleaner separation between general technical modules
and Point of Sale specific functionality.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ernad Husremovic 2025-08-30 17:15:35 +02:00
parent 3791451dc1
commit 377f346a99
2675 changed files with 93308 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# Point Of Sale - Meal Voucher
Odoo addon: pos_meal_voucher
## Installation
```bash
pip install odoo-bringout-oca-pos-pos_meal_voucher
```
## Dependencies
This addon depends on:
- point_of_sale
## Manifest Information
- **Name**: Point Of Sale - Meal Voucher
- **Version**: 16.0.1.0.0
- **Category**: Point of Sale
- **License**: AGPL-3
- **Installable**: False
## Source
Based on [OCA/pos](https://github.com/OCA/pos) branch 16.0, addon `pos_meal_voucher`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Reports: doc/REPORTS.md
- Security: doc/SECURITY.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Pos_meal_voucher Module - pos_meal_voucher
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for pos_meal_voucher. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,5 @@
# Dependencies
This addon depends on:
- [point_of_sale](https://github.com/bringout/oca-ocb-sale/tree/681dc8d5fff638cb0862a34e48091a2098d091f8/odoo-bringout-oca-ocb-point_of_sale)

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon pos_meal_voucher or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-pos-pos_meal_voucher"
# or
uv pip install odoo-bringout-oca-pos-pos_meal_voucher"
```

View file

@ -0,0 +1,20 @@
# Models
Detected core models and extensions in pos_meal_voucher.
```mermaid
classDiagram
class barcode_rule
class pos_config
class pos_order
class pos_payment_method
class pos_session
class product_category
class product_product
class product_template
class res_config_settings
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: pos_meal_voucher. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon pos_meal_voucher
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,8 @@
# Security
This module does not define custom security rules or access controls beyond Odoo defaults.
Default Odoo security applies:
- Base user access through standard groups
- Model access inherited from dependencies
- No custom row-level security rules

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon pos_meal_voucher
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,180 @@
============================
Point Of Sale - Meal Voucher
============================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:6017c21d19f693f1b5e3ca796085eb3b752979671be3000968613478f38f7e20
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github
:target: https://github.com/OCA/pos/tree/16.0/pos_meal_voucher
:alt: OCA/pos
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/pos-16-0/pos-16-0-pos_meal_voucher
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/pos&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows to handle meal vouchers in the point of sale.
Meal vouchers are a payment method, available in some countries (France, Belgium, Romania,…) that allows customers to buy food products in grocery stores or pay in restaurants.
**Table of contents**
.. contents::
:local:
Configuration
=============
Products
~~~~~~~~
On a product form, in the "Sales" tab, the "Can be Paid for by Meal Vouchers" checkbox controls whether the product can be paid for by meal vouchers.
.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/product_product_form.png
Product categories can be configured to have a default value for the "Can be Paid for by Meal Vouchers" field for its products.
The "Apply to All Products" button allows to set the value on all products of the category.
.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/product_category_form.png
Point of Sale Payment Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Point of sale payment methods (Point of Sale > Configuration > Payment Methods) have a "Meal Voucher Type" field that defines what type of meal voucher payment method they are:
* (empty): The payment method is not a meal voucher payment method.
* **Paper**: The payment method will be used when scanning meal voucher barcodes.
* **Electronic**: The payment method will be used for electronic meal vouchers.
.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_method_form.png
Settings
~~~~~~~~
This module adds a "Meal Vouchers" section in the point of sale settings (Point of Sale > Configuration > Settings, or Settings > Point of Sale) with several options:
* **Maximum Amount**: Optional maximum amount per order that can be paid by meal vouchers. Set to 0 to disable.
* **Icon on Order Lines**: Whether to display an icon on point of sale order lines (on the product screen) for products that can be paid for by meal vouchers.
* **Information on Receipt**: Whether to display an asterisk (*) on receipts before each product that can be paid for by meal vouchers as well as the total eligible amount.
.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_settings.png
Usage
=====
Product Screen
~~~~~~~~~~~~~~
On the product screen, the products that can be paid for by meal vouchers are (optionally) identified with an icon and the total amount of those products is displayed.
.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_order_screen.png
Payment Screen
~~~~~~~~~~~~~~
On the payment screen, a meal voucher summary is displayed:
.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_screen_meal_vouchers.png
If the received amount is too high, a warning icon is displayed:
.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_screen_warning.png
Receipt
~~~~~~~
The receipts can optionally contain information about the products that can be paid for by meal vouchers and the total amount of those products:
.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/receipt_information.png
Barcodes
~~~~~~~~
A new barcode rule is defined for paper meal vouchers (with 24 characters):
``...........{NNNDD}........``
If you scan the following barcode: ``052566641320080017000000``, a new payment line with an amount of ¤8.00 (``00800``) will be added.
Known issues / Roadmap
======================
Possible Features
~~~~~~~~~~~~~~~~~
* Introduce the Meal Voucher Issuer model.
* Deduce the issuer when scanning a meal voucher barcode.
* Add a report to easily compute the total deposit of meal vouchers (per issuer).
* Prevent to scan the same meal voucher barcode twice.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/pos/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/pos/issues/new?body=module:%20pos_meal_voucher%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* GRAP
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/)
* Le Drive tout nu (https://ledrivetoutnu.com/)
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px
:target: https://github.com/legalsylvain
:alt: legalsylvain
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-legalsylvain|
This module is part of the `OCA/pos <https://github.com/OCA/pos/tree/16.0/pos_meal_voucher>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

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

View file

@ -0,0 +1,35 @@
# 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": "16.0.1.0.0",
"category": "Point of Sale",
"author": "GRAP, Odoo Community Association (OCA)",
"maintainers": ["legalsylvain"],
"website": "https://github.com/OCA/pos",
"license": "AGPL-3",
"depends": [
"point_of_sale",
],
"data": [
"data/barcode_rule.xml",
"views/pos_payment_method_view.xml",
"views/res_config_settings_view.xml",
"views/view_product_category.xml",
"views/view_product_template.xml",
],
"assets": {
"point_of_sale.assets": [
"pos_meal_voucher/static/src/scss/*.scss",
"pos_meal_voucher/static/src/js/**/*.js",
"pos_meal_voucher/static/src/xml/**/*.xml",
],
},
"demo": [
"demo/product_category.xml",
"demo/product_product.xml",
],
}

View file

@ -0,0 +1,21 @@
<?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>

View file

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

View file

@ -0,0 +1,17 @@
<?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="list_price">5.30</field>
</record>
</odoo>

View file

@ -0,0 +1,252 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_meal_voucher
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid "<span class=\"o_form_label\">Maximum Amount</span>"
msgstr "<span class=\"o_form_label\">Maximum Amount</span>"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_product_category
msgid "Apply to All Products"
msgstr "Apply to All Products"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_barcode_rule
msgid "Barcode Rule"
msgstr "Barkod pravilo"
#. module: pos_meal_voucher
#: 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
msgid "Can be Paid for by Meal Vouchers"
msgstr "Can be Paid for by Meal Vouchers"
#. 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 for by meal vouchers."
msgstr "Check this box if the product can be paid for by meal vouchers."
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_res_config_settings
msgid "Config Settings"
msgstr "Postavke"
#. module: pos_meal_voucher
#: model:ir.model.fields.selection,name:pos_meal_voucher.selection__pos_payment_method__meal_voucher_type__electronic
msgid "Electronic"
msgstr "Electronic"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml:0
#, python-format
msgid "Eligible Total:"
msgstr "Eligible Total:"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__has_meal_voucher_payment_method
msgid "Has Meal Voucher Payment Method"
msgstr "Has Meal Voucher Payment Method"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid "Icon on Order Lines"
msgstr "Icon on Order Lines"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid ""
"If checked, an asterisk (*) will be displayed on receipts before each "
"product that can be paid for by meal vouchers as well as the total eligible "
"amount."
msgstr ""
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid ""
"If checked, an icon will be displayed on point of sale order lines (on the "
"product screen) for products that can be paid for by meal vouchers."
msgstr ""
#. module: pos_meal_voucher
#: model:ir.model.fields,help:pos_meal_voucher.field_product_category__meal_voucher_ok
msgid ""
"If checked, the products of this category will be marked as \"Can be Paid "
"for by Meal Vouchers\" by default."
msgstr ""
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid "Information on Receipt"
msgstr "Information on Receipt"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/js/models.esm.js:0
#, python-format
msgid "Invalid Meal Voucher"
msgstr "Invalid Meal Voucher"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml:0
#, python-format
msgid "Max Amount"
msgstr "Max Amount"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__enable_meal_voucher_order_lines_icon
#: model:ir.model.fields,field_description:pos_meal_voucher.field_res_config_settings__pos_enable_meal_voucher_order_lines_icon
msgid "Meal Voucher Icon on Order Lines"
msgstr "Meal Voucher Icon on Order Lines"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__enable_meal_voucher_receipt_info
#: model:ir.model.fields,field_description:pos_meal_voucher.field_res_config_settings__pos_enable_meal_voucher_receipt_info
msgid "Meal Voucher Information on Receipt"
msgstr "Meal Voucher Information on Receipt"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__max_meal_voucher_amount
#: model:ir.model.fields,field_description:pos_meal_voucher.field_res_config_settings__pos_max_meal_voucher_amount
msgid "Meal Voucher Maximum Amount"
msgstr "Meal Voucher Maximum Amount"
#. module: pos_meal_voucher
#: model:ir.model.fields.selection,name:pos_meal_voucher.selection__barcode_rule__type__meal_voucher_payment
msgid "Meal Voucher Payment"
msgstr "Meal Voucher Payment"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_payment_method__meal_voucher_type
msgid "Meal Voucher Type"
msgstr "Meal Voucher Type"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/ProductScreen/OrderSummary.xml:0
#, python-format
msgid "Meal Voucher:"
msgstr "Meal Voucher:"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml:0
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
#, python-format
msgid "Meal Vouchers"
msgstr "Meal Vouchers"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml:0
#, python-format
msgid "Non-Eligible Total:"
msgstr "Non-Eligible Total:"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid ""
"Optional maximum amount per order that can be paid by meal vouchers.\n"
" Set to 0 to disable."
msgstr ""
#. module: pos_meal_voucher
#: model:product.template,name:pos_meal_voucher.bread_product_template
msgid "Organic Wholemeal Bread"
msgstr "Organic Wholemeal Bread"
#. module: pos_meal_voucher
#: model:ir.model.fields.selection,name:pos_meal_voucher.selection__pos_payment_method__meal_voucher_type__paper
msgid "Paper"
msgstr "Paper"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_pos_config
msgid "Point of Sale Configuration"
msgstr "Postavke prodajnog mjesta"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_pos_order
msgid "Point of Sale Orders"
msgstr "Narudžbe POS-a"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_pos_payment_method
msgid "Point of Sale Payment Methods"
msgstr "Načini plaćanja na prodajnom mjestu"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_pos_session
msgid "Point of Sale Session"
msgstr "Sesija POS-a"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_template
msgid "Product"
msgstr "Artikal"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_category
msgid "Product Category"
msgstr "Kategorija proizvoda"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_product
msgid "Product Variant"
msgstr "Varijanta proizvoda"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml:0
#, python-format
msgid "Products marked with an asterisk (*) can be paid for by meal vouchers."
msgstr "Products marked with an asterisk (*) can be paid for by meal vouchers."
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_product_category
msgid ""
"Set the above \"Can be Paid for by Meal Vouchers\" value on all of the "
"products of this category"
msgstr ""
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/js/models.esm.js:0
#, python-format
msgid "The paper meal voucher with code \"%s\" has already been scanned."
msgstr "The paper meal voucher with code \"%s\" has already been scanned."
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml:0
#, python-format
msgid "Total Eligible"
msgstr "Total Eligible"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml:0
#, python-format
msgid "Total Received"
msgstr "Total Received"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_barcode_rule__type
msgid "Type"
msgstr "Tip"

View file

@ -0,0 +1,270 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_meal_voucher
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-21 17:11+0000\n"
"PO-Revision-Date: 2025-02-21 17:11+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\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
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid "<span class=\"o_form_label\">Maximum Amount</span>"
msgstr "<span class=\"o_form_label\">Montant maximum</span>"
#. 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 produits"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_barcode_rule
msgid "Barcode Rule"
msgstr "Règle de code-barres"
#. module: pos_meal_voucher
#: 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
msgid "Can be Paid for by Meal Vouchers"
msgstr "Peut être payé avec des titres-restaurant"
#. 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 for by meal vouchers."
msgstr ""
"Cocher cette case si le produit peut être payé avec des titres-restaurant."
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_res_config_settings
msgid "Config Settings"
msgstr "Paramètres de configuration"
#. module: pos_meal_voucher
#: model:ir.model.fields.selection,name:pos_meal_voucher.selection__pos_payment_method__meal_voucher_type__electronic
msgid "Electronic"
msgstr "Électronique"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml:0
#, python-format
msgid "Eligible Total:"
msgstr "Total éligible :"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__has_meal_voucher_payment_method
msgid "Has Meal Voucher Payment Method"
msgstr "A une méthode de paiement titre-restaurant"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid "Icon on Order Lines"
msgstr "Icône sur les lignes de commande"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid ""
"If checked, an asterisk (*) will be displayed on receipts before each "
"product that can be paid for by meal vouchers as well as the total eligible "
"amount."
msgstr ""
"Si la case est cochée, une astérisque (*) sera affichée sur les tickets "
"devant chaque produit qui peut être payé avec des titres-restaurant, ainsi "
"que le montant total éligible."
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid ""
"If checked, an icon will be displayed on point of sale order lines (on the "
"product screen) for products that can be paid for by meal vouchers."
msgstr ""
"Si la case est cochée, une icône sera affichée sur les lignes de commande "
"(sur l'écran des produits) pour les produits qui peuvent être payés avec des "
"titres-restaurant."
#. module: pos_meal_voucher
#: model:ir.model.fields,help:pos_meal_voucher.field_product_category__meal_voucher_ok
msgid ""
"If checked, the products of this category will be marked as \"Can be Paid "
"for by Meal Vouchers\" by default."
msgstr ""
"Si la case est cochée, les produits de cette catégorie seront marqués comme "
"\"Peut être payé avec des titres-restaurant\" par défaut."
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid "Information on Receipt"
msgstr "Informations sur le ticket"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/js/models.esm.js:0
#, python-format
msgid "Invalid Meal Voucher"
msgstr "Titre-restaurant invalide"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml:0
#, python-format
msgid "Max Amount"
msgstr "Montant maximum"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__enable_meal_voucher_order_lines_icon
#: model:ir.model.fields,field_description:pos_meal_voucher.field_res_config_settings__pos_enable_meal_voucher_order_lines_icon
msgid "Meal Voucher Icon on Order Lines"
msgstr "Icône de titre-restaurant sur lignes de commande"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__enable_meal_voucher_receipt_info
#: model:ir.model.fields,field_description:pos_meal_voucher.field_res_config_settings__pos_enable_meal_voucher_receipt_info
msgid "Meal Voucher Information on Receipt"
msgstr "Informations de titres-restaurant sur le ticket"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__max_meal_voucher_amount
#: model:ir.model.fields,field_description:pos_meal_voucher.field_res_config_settings__pos_max_meal_voucher_amount
msgid "Meal Voucher Maximum Amount"
msgstr "Montant maximum en titres-restaurant"
#. module: pos_meal_voucher
#: model:ir.model.fields.selection,name:pos_meal_voucher.selection__barcode_rule__type__meal_voucher_payment
msgid "Meal Voucher Payment"
msgstr "Paiement en titres-restaurant"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_payment_method__meal_voucher_type
msgid "Meal Voucher Type"
msgstr "Type de titre-restaurant"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/ProductScreen/OrderSummary.xml:0
#, python-format
msgid "Meal Voucher:"
msgstr "Titre-restaurant :"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml:0
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
#, python-format
msgid "Meal Vouchers"
msgstr "Titres-restaurant"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml:0
#, python-format
msgid "Non-Eligible Total:"
msgstr "Total non-éligible :"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.res_config_settings_view_form
msgid ""
"Optional maximum amount per order that can be paid by meal vouchers.\n"
" Set to 0 to disable."
msgstr ""
"Montant maximum en titres-restaurant par vente.\n"
" Mettre à 0 pour désactiver."
#. module: pos_meal_voucher
#: model:product.template,name:pos_meal_voucher.bread_product_template
msgid "Organic Wholemeal Bread"
msgstr "Pain complet biologique"
#. module: pos_meal_voucher
#: model:ir.model.fields.selection,name:pos_meal_voucher.selection__pos_payment_method__meal_voucher_type__paper
msgid "Paper"
msgstr "Papier"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_pos_config
msgid "Point of Sale Configuration"
msgstr "Configuration 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
#: model:ir.model,name:pos_meal_voucher.model_pos_payment_method
msgid "Point of Sale Payment Methods"
msgstr "Modes de paiement du point de vente"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_pos_session
msgid "Point of Sale Session"
msgstr "Session du point de vente"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_template
msgid "Product"
msgstr "Produit"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_category
msgid "Product Category"
msgstr "Catégorie de produit"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_product
msgid "Product Variant"
msgstr "Variante de produit"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml:0
#, python-format
msgid "Products marked with an asterisk (*) can be paid for by meal vouchers."
msgstr ""
"Les produits marqués d'une astérisque (*) peuvent être payés avec des titres-"
"restaurant."
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_product_category
msgid ""
"Set the above \"Can be Paid for by Meal Vouchers\" value on all of the "
"products of this category"
msgstr ""
"Applique la valeur de \"Peut être payé avec des titres-restaurant\" ci-"
"dessus à tous les produits de cette catégorie"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/js/models.esm.js:0
#, python-format
msgid "The paper meal voucher with code \"%s\" has already been scanned."
msgstr "Le titre-restaurant papier avec le code \"%s\" a déjà été scanné."
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml:0
#, python-format
msgid "Total Eligible"
msgstr "Total éligible"
#. module: pos_meal_voucher
#. odoo-javascript
#: code:addons/pos_meal_voucher/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml:0
#, 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"

View file

@ -0,0 +1,337 @@
# 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"
"PO-Revision-Date: 2023-11-21 13:36+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: pos_meal_voucher
#. openerp-web
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:35
#, python-format
msgid "(Dematerialized)"
msgstr "(Dematerializzato)"
#. 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\">Importo buoni pasto</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 "Applicare a tutti i prodotti"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_barcode_rule
msgid "Barcode Rule"
msgstr "Regola codice a barre"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Cashier"
msgstr "Cassiere"
#. 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 ""
"Selezionare questo campo se il prodotto può essere pagato con buoni pasto."
#. 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 "Carta di credito / dematerializzato"
#. module: pos_meal_voucher
#: selection:account.journal,meal_voucher_type:0
msgid "Dematerialized"
msgstr "Dematerializzato"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Discounted Product"
msgstr "Prodotto scontato"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__meal_voucher_display_info_ticket
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_pos_config_form
msgid "Display Information on Ticket"
msgstr "Visualizza informazioni sul biglietto"
#. 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 "Mostrare l'icona prima dei prodotti a schermo"
#. module: pos_meal_voucher
#. openerp-web
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:100
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:118
#, python-format
msgid "Eligible Total:"
msgstr "Totale ammissibile:"
#. module: pos_meal_voucher
#: model:product.category,name:pos_meal_voucher.food_category
msgid "Food"
msgstr "Cibo"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_pos_config__has_meal_voucher_journal
msgid "Has Meal Voucher Journal"
msgstr "Ha registro buoni pasto"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_pos_config_form
msgid ""
"If checked, a star (*) will be displayed on the ticket, before each product "
"that can be paid with meal vouchers, and the total of the eligible product "
"will be printed."
msgstr ""
"Se selezionata, un asterisco (*) verrà visualizzato sul biglietto, prima di "
"ogni prodotto che può essere pagato con i buoni pasto, e verrà stampato il "
"totale del prodotto consentito."
#. 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 ""
"Se selezionato, un'icona verrà mostrata a schermo, prima di ogni prodotto "
"che può essere pagato con buoni pasto."
#. 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 ""
"Se selezionato, i prodotti che appartengono alla categoria verranno "
"impostati come 'può essere pagato con buoni pasto', di default."
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_account_journal
msgid "Journal"
msgstr "Registro"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Location"
msgstr "Ubicazione"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Lot"
msgstr "Lotto"
#. module: pos_meal_voucher
#. openerp-web
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:59
#, python-format
msgid "Max Amount"
msgstr "Importo massimo"
#. 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 ""
"Massimo importo di buoni pasto che può essere ricevuto per un ordine POS.\n"
" Lasciare 0, se non si vuole abilitare questo "
"controllo."
#. module: pos_meal_voucher
#. openerp-web
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:46
#: 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 "Buoni pasto"
#. 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 "Importo buoni pasto"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Meal Voucher Payment"
msgstr "Pagamento buoni pasto"
#. 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 "Tipo buoni pasto"
#. module: pos_meal_voucher
#. openerp-web
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:19
#, python-format
msgid "Meal Voucher:"
msgstr "Buoni pasto:"
#. module: pos_meal_voucher
#: model_terms:ir.ui.view,arch_db:pos_meal_voucher.view_pos_config_form
msgid "Meal Vouchers"
msgstr "Buoni pasto"
#. 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 "Pane integrale biologico"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Package"
msgstr "Collo"
#. module: pos_meal_voucher
#: selection:account.journal,meal_voucher_type:0
msgid "Paper"
msgstr "Carta"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_pos_config
msgid "Point of Sale Configuration"
msgstr "Configurazione punto vendita"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_pos_order
msgid "Point of Sale Orders"
msgstr "Ordini punto vendita"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Priced Product"
msgstr "Prodotto prezzato"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Priced Product (Computed Weight)"
msgstr "Prodotto prezzato (peso calcolato)"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_product
msgid "Product"
msgstr "Prodotto"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_category
msgid "Product Category"
msgstr "Categoria prodotto"
#. module: pos_meal_voucher
#: model:ir.model,name:pos_meal_voucher.model_product_template
msgid "Product Template"
msgstr "Modello prodotto"
#. module: pos_meal_voucher
#. openerp-web
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:96
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:114
#, python-format
msgid "Products marked with a star (*) are eligible for Meal vouchers."
msgstr ""
"I prodotti segnalati da un asterisco (*) sono pagabili con i buoni pasto."
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Tare"
msgstr "Tara"
#. 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 "Testo per il registro misto"
#. 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 ""
"Testo che verrà mostrato nel punto vendita se il registro è misto (carta di "
"credito / dematerializzato) per il pulsante dematerializzato."
#. module: pos_meal_voucher
#. openerp-web
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:51
#, python-format
msgid "Total Eligible"
msgstr "Totale idoneo"
#. module: pos_meal_voucher
#. openerp-web
#: code:addons/pos_meal_voucher/static/src/xml/pos_meal_voucher.xml:67
#, python-format
msgid "Total Received"
msgstr "Totale ricevuto"
#. module: pos_meal_voucher
#: model:ir.model.fields,field_description:pos_meal_voucher.field_barcode_rule__type
msgid "Type"
msgstr "Tipo"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Unit Product"
msgstr "Prodotto unitario"
#. 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à"
#. module: pos_meal_voucher
#: selection:barcode.rule,type:0
msgid "Weighted Product"
msgstr "Prodotto pesato"
#. 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 ""
"cliccando questo pulsante, tutti i prodotti di questa categoria avranno le "
"stesse impostazioni della categoria corrente, per il valore 'buoni pasto'"
#. 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"

View file

@ -0,0 +1,9 @@
from . import barcode_rule
from . import pos_config
from . import pos_order
from . import pos_payment_method
from . import pos_session
from . import product_category
from . import product_product
from . import product_template
from . import res_config_settings

View file

@ -0,0 +1,14 @@
# 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")],
ondelete={"meal_voucher_payment": "set default"},
)

View file

@ -0,0 +1,31 @@
# 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 Maximum Amount",
currency_field="currency_id",
)
enable_meal_voucher_order_lines_icon = fields.Boolean(
string="Meal Voucher Icon on Order Lines", default=True
)
enable_meal_voucher_receipt_info = fields.Boolean(
string="Meal Voucher Information on Receipt",
)
has_meal_voucher_payment_method = fields.Boolean(
compute="_compute_has_meal_voucher_payment_method"
)
def _compute_has_meal_voucher_payment_method(self):
for config in self:
config.has_meal_voucher_payment_method = bool(
config.payment_method_ids.filtered(
lambda x: x.meal_voucher_type is not False
)
)

View file

@ -0,0 +1,17 @@
# 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, order, ui_paymentline):
res = super()._payment_fields(order, ui_paymentline)
# the pos.payment.name field is named "Label" and is not used for
# normal payments, so it is used here to store the payment note (the
# barcode of paper meal vouchers).
res["name"] = ui_paymentline.get("payment_note", False)
return res

View file

@ -0,0 +1,16 @@
# 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 PosPaymentMethod(models.Model):
_inherit = "pos.payment.method"
meal_voucher_type = fields.Selection(
selection=[
("paper", "Paper"),
("electronic", "Electronic"),
],
)

View file

@ -0,0 +1,19 @@
# SPDX-FileCopyrightText: 2025 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later
from odoo import models
class PosSession(models.Model):
_inherit = "pos.session"
def _loader_params_pos_payment_method(self):
res = super()._loader_params_pos_payment_method()
res["search_params"]["fields"].append("meal_voucher_type")
return res
def _loader_params_product_product(self):
res = super()._loader_params_product_product()
res["search_params"]["fields"].append("meal_voucher_ok")
return res

View file

@ -0,0 +1,25 @@
# 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="Can be Paid for by Meal Vouchers",
help="If checked, the products of this category will be marked as "
'"Can be Paid for by Meal Vouchers" by default.',
)
def button_apply_meal_voucher_settings(self):
ProductTemplate = self.env["product.template"]
for category in self:
templates = (
ProductTemplate.sudo()
.with_context(active_test=False)
.search([("categ_id", "=", category.id)])
)
templates.write({"meal_voucher_ok": category.meal_voucher_ok})

View file

@ -0,0 +1,14 @@
# Copyright (C) 2021 - 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, models
class ProductProduct(models.Model):
_inherit = "product.product"
@api.onchange("categ_id")
def onchange_categ_id_pos_meal_voucher(self):
for product in self:
product.meal_voucher_ok = product.categ_id.meal_voucher_ok

View file

@ -0,0 +1,29 @@
# 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="Can be Paid for by Meal Vouchers",
help="Check this box if the product can be paid for by meal vouchers.",
)
@api.onchange("categ_id")
def onchange_categ_id_pos_meal_voucher(self):
for template in self:
template.meal_voucher_ok = template.categ_id.meal_voucher_ok
@api.model_create_multi
def create(self, vals_list):
product_category_model = self.env["product.category"]
for vals in vals_list:
if "meal_voucher_ok" not in vals and "categ_id" in vals:
# Guess meal_voucher_ok if not present, based on the category
categ = product_category_model.browse(vals.get("categ_id"))
vals["meal_voucher_ok"] = categ.meal_voucher_ok
return super().create(vals_list)

View file

@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2025 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
pos_max_meal_voucher_amount = fields.Monetary(
related="pos_config_id.max_meal_voucher_amount",
readonly=False,
)
pos_enable_meal_voucher_order_lines_icon = fields.Boolean(
related="pos_config_id.enable_meal_voucher_order_lines_icon",
readonly=False,
)
pos_enable_meal_voucher_receipt_info = fields.Boolean(
related="pos_config_id.enable_meal_voucher_receipt_info",
readonly=False,
)

View file

@ -0,0 +1,33 @@
Products
~~~~~~~~
On a product form, in the "Sales" tab, the "Can be Paid for by Meal Vouchers" checkbox controls whether the product can be paid for by meal vouchers.
.. figure:: ../static/description/product_product_form.png
Product categories can be configured to have a default value for the "Can be Paid for by Meal Vouchers" field for its products.
The "Apply to All Products" button allows to set the value on all products of the category.
.. figure:: ../static/description/product_category_form.png
Point of Sale Payment Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Point of sale payment methods (Point of Sale > Configuration > Payment Methods) have a "Meal Voucher Type" field that defines what type of meal voucher payment method they are:
* (empty): The payment method is not a meal voucher payment method.
* **Paper**: The payment method will be used when scanning meal voucher barcodes.
* **Electronic**: The payment method will be used for electronic meal vouchers.
.. figure:: ../static/description/pos_payment_method_form.png
Settings
~~~~~~~~
This module adds a "Meal Vouchers" section in the point of sale settings (Point of Sale > Configuration > Settings, or Settings > Point of Sale) with several options:
* **Maximum Amount**: Optional maximum amount per order that can be paid by meal vouchers. Set to 0 to disable.
* **Icon on Order Lines**: Whether to display an icon on point of sale order lines (on the product screen) for products that can be paid for by meal vouchers.
* **Information on Receipt**: Whether to display an asterisk (*) on receipts before each product that can be paid for by meal vouchers as well as the total eligible amount.
.. figure:: ../static/description/pos_settings.png

View file

@ -0,0 +1 @@
* Sylvain LE GAL <https://twitter.com/legalsylvain>

View file

@ -0,0 +1,5 @@
The development of this module has been financially supported by:
* Vracoop (https://portail.vracoop.fr/)
* Demain Supermarché (http://www.demainsupermarche.org/)
* Le Drive tout nu (https://ledrivetoutnu.com/)

View file

@ -0,0 +1,3 @@
This module allows to handle meal vouchers in the point of sale.
Meal vouchers are a payment method, available in some countries (France, Belgium, Romania,…) that allows customers to buy food products in grocery stores or pay in restaurants.

View file

@ -0,0 +1,7 @@
Possible Features
~~~~~~~~~~~~~~~~~
* Introduce the Meal Voucher Issuer model.
* Deduce the issuer when scanning a meal voucher barcode.
* Add a report to easily compute the total deposit of meal vouchers (per issuer).
* Prevent to scan the same meal voucher barcode twice.

View file

@ -0,0 +1,33 @@
Product Screen
~~~~~~~~~~~~~~
On the product screen, the products that can be paid for by meal vouchers are (optionally) identified with an icon and the total amount of those products is displayed.
.. figure:: ../static/description/pos_order_screen.png
Payment Screen
~~~~~~~~~~~~~~
On the payment screen, a meal voucher summary is displayed:
.. figure:: ../static/description/pos_payment_screen_meal_vouchers.png
If the received amount is too high, a warning icon is displayed:
.. figure:: ../static/description/pos_payment_screen_warning.png
Receipt
~~~~~~~
The receipts can optionally contain information about the products that can be paid for by meal vouchers and the total amount of those products:
.. figure:: ../static/description/receipt_information.png
Barcodes
~~~~~~~~
A new barcode rule is defined for paper meal vouchers (with 24 characters):
``...........{NNNDD}........``
If you scan the following barcode: ``052566641320080017000000``, a new payment line with an amount of ¤8.00 (``00800``) will be added.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -0,0 +1,538 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Point Of Sale - Meal Voucher</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="point-of-sale-meal-voucher">
<h1 class="title">Point Of Sale - Meal Voucher</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:6017c21d19f693f1b5e3ca796085eb3b752979671be3000968613478f38f7e20
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/pos/tree/16.0/pos_meal_voucher"><img alt="OCA/pos" src="https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/pos-16-0/pos-16-0-pos_meal_voucher"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/pos&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows to handle meal vouchers in the point of sale.</p>
<p>Meal vouchers are a payment method, available in some countries (France, Belgium, Romania,…) that allows customers to buy food products in grocery stores or pay in restaurants.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a><ul>
<li><a class="reference internal" href="#products" id="toc-entry-2">Products</a></li>
<li><a class="reference internal" href="#point-of-sale-payment-methods" id="toc-entry-3">Point of Sale Payment Methods</a></li>
<li><a class="reference internal" href="#settings" id="toc-entry-4">Settings</a></li>
</ul>
</li>
<li><a class="reference internal" href="#usage" id="toc-entry-5">Usage</a><ul>
<li><a class="reference internal" href="#product-screen" id="toc-entry-6">Product Screen</a></li>
<li><a class="reference internal" href="#payment-screen" id="toc-entry-7">Payment Screen</a></li>
<li><a class="reference internal" href="#receipt" id="toc-entry-8">Receipt</a></li>
<li><a class="reference internal" href="#barcodes" id="toc-entry-9">Barcodes</a></li>
</ul>
</li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-10">Known issues / Roadmap</a><ul>
<li><a class="reference internal" href="#possible-features" id="toc-entry-11">Possible Features</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-12">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-13">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-14">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-15">Contributors</a></li>
<li><a class="reference internal" href="#other-credits" id="toc-entry-16">Other credits</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-17">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<div class="section" id="products">
<h2><a class="toc-backref" href="#toc-entry-2">Products</a></h2>
<p>On a product form, in the “Sales” tab, the “Can be Paid for by Meal Vouchers” checkbox controls whether the product can be paid for by meal vouchers.</p>
<div class="figure">
<img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/product_product_form.png" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/product_product_form.png" />
</div>
<p>Product categories can be configured to have a default value for the “Can be Paid for by Meal Vouchers” field for its products.
The “Apply to All Products” button allows to set the value on all products of the category.</p>
<div class="figure">
<img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/product_category_form.png" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/product_category_form.png" />
</div>
</div>
<div class="section" id="point-of-sale-payment-methods">
<h2><a class="toc-backref" href="#toc-entry-3">Point of Sale Payment Methods</a></h2>
<p>Point of sale payment methods (Point of Sale &gt; Configuration &gt; Payment Methods) have a “Meal Voucher Type” field that defines what type of meal voucher payment method they are:</p>
<ul class="simple">
<li>(empty): The payment method is not a meal voucher payment method.</li>
<li><strong>Paper</strong>: The payment method will be used when scanning meal voucher barcodes.</li>
<li><strong>Electronic</strong>: The payment method will be used for electronic meal vouchers.</li>
</ul>
<div class="figure">
<img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_method_form.png" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_method_form.png" />
</div>
</div>
<div class="section" id="settings">
<h2><a class="toc-backref" href="#toc-entry-4">Settings</a></h2>
<p>This module adds a “Meal Vouchers” section in the point of sale settings (Point of Sale &gt; Configuration &gt; Settings, or Settings &gt; Point of Sale) with several options:</p>
<ul class="simple">
<li><strong>Maximum Amount</strong>: Optional maximum amount per order that can be paid by meal vouchers. Set to 0 to disable.</li>
<li><strong>Icon on Order Lines</strong>: Whether to display an icon on point of sale order lines (on the product screen) for products that can be paid for by meal vouchers.</li>
<li><strong>Information on Receipt</strong>: Whether to display an asterisk (*) on receipts before each product that can be paid for by meal vouchers as well as the total eligible amount.</li>
</ul>
<div class="figure">
<img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_settings.png" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_settings.png" />
</div>
</div>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-5">Usage</a></h1>
<div class="section" id="product-screen">
<h2><a class="toc-backref" href="#toc-entry-6">Product Screen</a></h2>
<p>On the product screen, the products that can be paid for by meal vouchers are (optionally) identified with an icon and the total amount of those products is displayed.</p>
<div class="figure">
<img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_order_screen.png" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_order_screen.png" />
</div>
</div>
<div class="section" id="payment-screen">
<h2><a class="toc-backref" href="#toc-entry-7">Payment Screen</a></h2>
<p>On the payment screen, a meal voucher summary is displayed:</p>
<div class="figure">
<img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_screen_meal_vouchers.png" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_screen_meal_vouchers.png" />
</div>
<p>If the received amount is too high, a warning icon is displayed:</p>
<div class="figure">
<img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_screen_warning.png" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/pos_payment_screen_warning.png" />
</div>
</div>
<div class="section" id="receipt">
<h2><a class="toc-backref" href="#toc-entry-8">Receipt</a></h2>
<p>The receipts can optionally contain information about the products that can be paid for by meal vouchers and the total amount of those products:</p>
<div class="figure">
<img alt="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/receipt_information.png" src="https://raw.githubusercontent.com/OCA/pos/16.0/pos_meal_voucher/static/description/receipt_information.png" />
</div>
</div>
<div class="section" id="barcodes">
<h2><a class="toc-backref" href="#toc-entry-9">Barcodes</a></h2>
<p>A new barcode rule is defined for paper meal vouchers (with 24 characters):</p>
<p><tt class="docutils literal"><span class="pre">...........{NNNDD}........</span></tt></p>
<p>If you scan the following barcode: <tt class="docutils literal">052566641320080017000000</tt>, a new payment line with an amount of ¤8.00 (<tt class="docutils literal">00800</tt>) will be added.</p>
</div>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-10">Known issues / Roadmap</a></h1>
<div class="section" id="possible-features">
<h2><a class="toc-backref" href="#toc-entry-11">Possible Features</a></h2>
<ul class="simple">
<li>Introduce the Meal Voucher Issuer model.</li>
<li>Deduce the issuer when scanning a meal voucher barcode.</li>
<li>Add a report to easily compute the total deposit of meal vouchers (per issuer).</li>
<li>Prevent to scan the same meal voucher barcode twice.</li>
</ul>
</div>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-12">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/pos/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/pos/issues/new?body=module:%20pos_meal_voucher%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-13">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-14">Authors</a></h2>
<ul class="simple">
<li>GRAP</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-15">Contributors</a></h2>
<ul class="simple">
<li>Sylvain LE GAL &lt;<a class="reference external" href="https://twitter.com/legalsylvain">https://twitter.com/legalsylvain</a>&gt;</li>
</ul>
</div>
<div class="section" id="other-credits">
<h2><a class="toc-backref" href="#toc-entry-16">Other credits</a></h2>
<p>The development of this module has been financially supported by:</p>
<ul class="simple">
<li>Vracoop (<a class="reference external" href="https://portail.vracoop.fr/">https://portail.vracoop.fr/</a>)</li>
<li>Demain Supermarché (<a class="reference external" href="http://www.demainsupermarche.org/">http://www.demainsupermarche.org/</a>)</li>
<li>Le Drive tout nu (<a class="reference external" href="https://ledrivetoutnu.com/">https://ledrivetoutnu.com/</a>)</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-17">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/legalsylvain"><img alt="legalsylvain" src="https://github.com/legalsylvain.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/pos/tree/16.0/pos_meal_voucher">OCA/pos</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View file

@ -0,0 +1,42 @@
/** @odoo-module **/
// SPDX-FileCopyrightText: 2025 Coop IT Easy SC
//
// SPDX-License-Identifier: AGPL-3.0-or-later
import {Component} from "point_of_sale.Registries";
import PaymentScreen from "point_of_sale.PaymentScreen";
import {useBarcodeReader} from "point_of_sale.custom_hooks";
const MealVoucherPaymentScreen = (OriginalPaymentScreen) =>
class extends OriginalPaymentScreen {
setup() {
super.setup();
if (this.env.pos.paper_meal_voucher_payment_method !== null) {
useBarcodeReader({
meal_voucher_payment: this._barcodeMealVoucherAction,
});
}
}
async _barcodeMealVoucherAction(code) {
return this.currentOrder.handle_meal_voucher_barcode(code);
}
get hasMealVoucherPaymentMethod() {
return this.env.pos.config.has_meal_voucher_payment_method;
}
get mealVoucherEligibleAmount() {
return this.currentOrder.get_total_meal_voucher_eligible();
}
get mealVoucherReceivedAmount() {
return this.currentOrder.get_total_meal_voucher_received();
}
get maxMealVoucherAmount() {
return this.env.pos.config.max_meal_voucher_amount;
}
};
Component.extend(PaymentScreen, MealVoucherPaymentScreen);

View file

@ -0,0 +1,16 @@
/** @odoo-module **/
// SPDX-FileCopyrightText: 2025 Coop IT Easy SC
//
// SPDX-License-Identifier: AGPL-3.0-or-later
import {Component} from "point_of_sale.Registries";
import PaymentScreenPaymentLines from "point_of_sale.PaymentScreenPaymentLines";
const MealVoucherPaymentScreenPaymentLines = (OriginalPaymentScreenPaymentLines) =>
class extends OriginalPaymentScreenPaymentLines {
isMealVoucher(line) {
return line.payment_method.meal_voucher_type !== false;
}
};
Component.extend(PaymentScreenPaymentLines, MealVoucherPaymentScreenPaymentLines);

View file

@ -0,0 +1,19 @@
/** @odoo-module **/
// SPDX-FileCopyrightText: 2025 Coop IT Easy SC
//
// SPDX-License-Identifier: AGPL-3.0-or-later
import {Component} from "point_of_sale.Registries";
import Orderline from "point_of_sale.Orderline";
const MealVoucherOrderline = (OriginalOrderline) =>
class extends OriginalOrderline {
get displayMealVoucherIcon() {
return (
this.env.pos.config.enable_meal_voucher_order_lines_icon &&
this.props.line.get_product().meal_voucher_ok
);
}
};
Component.extend(Orderline, MealVoucherOrderline);

View file

@ -0,0 +1,28 @@
/** @odoo-module **/
// SPDX-FileCopyrightText: 2025 Coop IT Easy SC
//
// SPDX-License-Identifier: AGPL-3.0-or-later
import {Component} from "point_of_sale.Registries";
import ProductScreen from "point_of_sale.ProductScreen";
import {useBarcodeReader} from "point_of_sale.custom_hooks";
const MealVoucherProductScreen = (OriginalProductScreen) =>
class extends OriginalProductScreen {
setup() {
super.setup();
if (this.env.pos.paper_meal_voucher_payment_method !== null) {
useBarcodeReader({
meal_voucher_payment: this._barcodeMealVoucherAction,
});
}
}
async _barcodeMealVoucherAction(code) {
// Display the payment screen, if it is not the current one.
this.showScreen("PaymentScreen");
return this.currentOrder.handle_meal_voucher_barcode(code);
}
};
Component.extend(ProductScreen, MealVoucherProductScreen);

View file

@ -0,0 +1,168 @@
/** @odoo-module **/
// 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).
import {Order, Orderline, Payment, PosGlobalState} from "point_of_sale.models";
import {Gui} from "point_of_sale.Gui";
import {Model} from "point_of_sale.Registries";
import {_t} from "web.core";
import {round_precision as round_pr} from "web.utils";
const MealVoucherOrder = (OriginalOrder) =>
class extends OriginalOrder {
get_total_meal_voucher_eligible() {
return round_pr(
this.orderlines.reduce(function (sum, orderLine) {
if (orderLine.product.meal_voucher_ok) {
return sum + orderLine.get_price_with_tax();
}
return sum;
}, 0),
this.pos.currency.rounding
);
}
get_total_meal_voucher_non_eligible() {
return round_pr(
this.orderlines.reduce(function (sum, orderLine) {
if (!orderLine.product.meal_voucher_ok) {
return sum + orderLine.get_price_with_tax();
}
return sum;
}, 0),
this.pos.currency.rounding
);
}
get_total_meal_voucher_received() {
return round_pr(
this.paymentlines.reduce(function (sum, paymentLine) {
if (paymentLine.is_meal_voucher()) {
return sum + paymentLine.get_amount();
}
return sum;
}, 0),
this.pos.currency.rounding
);
}
async _meal_voucher_is_valid(code) {
for (const payment_line of this.paymentlines) {
if (payment_line.payment_note === code) {
await Gui.showPopup("ErrorPopup", {
title: _t("Invalid Meal Voucher"),
body: _.str.sprintf(
_t(
'The paper meal voucher with code "%s" has already been scanned.'
),
code
),
});
return false;
}
}
return true;
}
async handle_meal_voucher_barcode(code) {
if (!(await this._meal_voucher_is_valid(code.code))) {
return;
}
// Add new payment line with the amount found in the barcode.
const payment_line = this.add_paymentline(
this.pos.paper_meal_voucher_payment_method
);
payment_line.set_amount(code.value);
payment_line.payment_note = code.code;
}
};
Model.extend(Order, MealVoucherOrder);
const RECEIPT_ORDER_LINE_PREFIX = "(*) ";
const MealVoucherOrderline = (OriginalOrderline) =>
class extends OriginalOrderline {
generate_wrapped_product_name() {
if (
!this.get_product().meal_voucher_ok ||
!this.pos.config.enable_meal_voucher_receipt_info
) {
return super.generate_wrapped_product_name(...arguments);
}
// Temporarily change the product name to add a prefix on the
// receipt.
//
// .generate_wrapped_product_name() calls
// .get_full_product_name(), and it has a different behavior
// depending on whether this.full_product_name is set or not. both
// behaviors must be handled, because one is used when generating
// a receipt during an order, while the order is used when
// retrieving a receipt from a previous order.
// .get_full_product_name() cannot be overridden because its
// result is also used for display in the product screen and
// its result is stored, which would result in the prefix being
// added each time the pos interface is reloaded.
const originalFullProductName = this.full_product_name;
const originalDisplayName = this.product.display_name;
if (originalFullProductName) {
this.full_product_name =
RECEIPT_ORDER_LINE_PREFIX + originalFullProductName;
} else {
this.product.display_name =
RECEIPT_ORDER_LINE_PREFIX + originalDisplayName;
}
const res = super.generate_wrapped_product_name(...arguments);
if (originalFullProductName) {
this.full_product_name = originalFullProductName;
} else {
this.product.display_name = originalDisplayName;
}
return res;
}
};
Model.extend(Orderline, MealVoucherOrderline);
const MealVoucherPayment = (OriginalPayment) =>
class extends OriginalPayment {
initialize() {
super.initialize(...arguments);
this.payment_note = null;
}
init_from_JSON(json) {
super.init_from_JSON(...arguments);
this.payment_note = json.payment_note;
}
export_as_JSON() {
const res = super.export_as_JSON(...arguments);
res.payment_note = this.payment_note;
return res;
}
is_meal_voucher() {
return this.payment_method.meal_voucher_type !== false;
}
};
Model.extend(Payment, MealVoucherPayment);
const MealVoucherPosGlobalState = (OriginalPosGlobalState) =>
class extends OriginalPosGlobalState {
async load_server_data() {
await super.load_server_data(...arguments);
this.paper_meal_voucher_payment_method = null;
for (const payment_method_id of this.config.payment_method_ids) {
const payment_method = this.payment_methods_by_id[payment_method_id];
if (payment_method.meal_voucher_type === "paper") {
this.paper_meal_voucher_payment_method = payment_method;
break;
}
}
}
};
Model.extend(PosGlobalState, MealVoucherPosGlobalState);

View file

@ -0,0 +1,56 @@
.pos .paymentline .is-meal-voucher {
text-align: center;
padding: map-get($spacers, 3);
}
.pos .paymentline .is-meal-voucher .fa-cutlery {
border-radius: 8px;
border: 1px solid rgba($gray-700, 0.5);
width: 24px;
line-height: 24px;
}
.payment-screen div.meal-voucher-summary .fa-warning {
color: red;
}
.pos .meal-voucher-summary {
// same as .pos .paymentlines
display: flex;
flex-direction: column-reverse;
border-spacing: 0px 10px;
border-collapse: inherit;
}
.pos .meal-voucher-summary-container {
padding: map-get($spacers, 2) 0;
}
.pos .meal-voucher-summary-line {
// same as .pos .paymentline, with some changes
display: flex;
flex-grow: 1;
flex-basis: 100%;
background: #fff;
font-size: 16px;
border-top-width: 0px;
padding: map-get($spacers, 2) 0;
}
.meal-voucher-summary-line .meal-voucher-summary-line-name {
flex-grow: 1;
padding: 0 map-get($spacers, 3);
}
.meal-voucher-summary-line .meal-voucher-summary-line-amount {
padding: 0 map-get($spacers, 3);
}
.meal-voucher-summary-line .meal-voucher-summary-line-warning {
font-size: 20px;
margin-bottom: -(map-get($spacers, 2));
}
.pos-receipt-meal-voucher-totals {
font-size: 75%;
}

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t
t-name="MealVoucherPaymentScreen"
t-inherit="point_of_sale.PaymentScreen"
t-inherit-mode="extension"
owl="1"
>
<xpath expr="//div[hasclass('paymentmethods')]" position="after">
<div t-if="hasMealVoucherPaymentMethod" class="meal-voucher-summary">
<p class="title-category">Meal Vouchers</p>
<div class="meal-voucher-summary-container">
<div class="meal-voucher-summary-line">
<div class="meal-voucher-summary-line-name">Total Eligible</div>
<div
t-if="mealVoucherReceivedAmount > mealVoucherEligibleAmount"
class="meal-voucher-summary-line-warning"
>
<i
id="meal-voucher-eligible-warning"
class="fa fa-warning"
/>
</div>
<div class="meal-voucher-summary-line-amount">
<span
id="meal-voucher-eligible-amount"
t-out="env.pos.format_currency(mealVoucherEligibleAmount)"
/>
</div>
</div>
<div
t-if="maxMealVoucherAmount !== 0"
class="meal-voucher-summary-line"
>
<div class="meal-voucher-summary-line-name">Max Amount</div>
<div
t-if="mealVoucherReceivedAmount > maxMealVoucherAmount"
class="meal-voucher-summary-line-warning"
>
<i id="meal-voucher-max-warning" class="fa fa-warning" />
</div>
<div class="meal-voucher-summary-line-amount">
<span
id="meal-voucher-max-amount"
t-out="env.pos.format_currency(maxMealVoucherAmount)"
/>
</div>
</div>
<div class="meal-voucher-summary-line">
<div class="meal-voucher-summary-line-name">Total Received</div>
<div class="meal-voucher-summary-line-amount">
<span
id="meal-voucher-received-amount"
t-out="env.pos.format_currency(mealVoucherReceivedAmount)"
/>
</div>
</div>
</div>
</div>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t
t-name="MealVoucherPaymentScreenPaymentLines"
t-inherit="point_of_sale.PaymentScreenPaymentLines"
t-inherit-mode="extension"
owl="1"
>
<xpath
expr="//t[@t-if='line.selected']/div/div[hasclass('payment-amount')]"
position="before"
>
<div t-if="isMealVoucher(line)" class="is-meal-voucher">
<i class="fa fa-cutlery" />
</div>
</xpath>
<xpath
expr="//t[@t-foreach='props.paymentLines']/t[@t-else='']/div/div[hasclass('payment-amount')]"
position="before"
>
<div t-if="isMealVoucher(line)" class="is-meal-voucher">
<i class="fa fa-cutlery" />
</div>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t
t-name="MealVoucherOrderSummary"
t-inherit="point_of_sale.OrderSummary"
t-inherit-mode="extension"
owl="1"
>
<xpath expr="//div[hasclass('summary')][1]" position="after">
<t t-if="env.pos.config.has_meal_voucher_payment_method">
<div class="summary clearfix">
<div class="line">
<div class="subentry meal-voucher">
Meal Voucher: <span
class="value"
t-out="env.pos.format_currency(props.order.get_total_meal_voucher_eligible())"
/>
</div>
</div>
</div>
</t>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t
t-name="MealVoucherOrderline"
t-inherit="point_of_sale.Orderline"
t-inherit-mode="extension"
owl="1"
>
<!--
the space after the <i> element is needed to separate the icon
from the product name.
-->
<xpath expr="//span[hasclass('product-name')]/t[1]" position="before">
<t t-if="displayMealVoucherIcon"><i class="fa fa-cutlery" /> </t>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t
t-name="MealVoucherOrderReceipt"
t-inherit="point_of_sale.OrderReceipt"
t-inherit-mode="extension"
owl="1"
>
<xpath expr="//t/div[hasclass('pos-receipt-amount')]/.." position="after">
<t t-if="env.pos.config.enable_meal_voucher_receipt_info">
<br />
<div class="pos-receipt-meal-voucher-totals">
Products marked with an asterisk (*) can be paid for by meal vouchers.
<br />
Eligible Total:
<span
t-out="env.pos.format_currency(props.order.get_total_meal_voucher_eligible())"
class="pos-receipt-right-align"
/>
<br />
Non-Eligible Total:
<span
t-out="env.pos.format_currency(props.order.get_total_meal_voucher_non_eligible())"
class="pos-receipt-right-align"
/>
</div>
</t>
</xpath>
</t>
</templates>

View file

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

View file

@ -0,0 +1,52 @@
# Copyright 2021 - Today Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase
class TestModule(TransactionCase):
def setUp(self):
super().setUp()
self.ProductProduct = self.env["product.product"]
self.ProductTemplate = self.env["product.template"]
self.food_category = self.env.ref("pos_meal_voucher.food_category")
self.main_category = self.env.ref("product.product_category_all")
self.uom_unit = self.env.ref("uom.product_uom_unit")
def test_product_product(self):
product = self.ProductProduct.create(
{
"name": "Product",
"uom_id": self.uom_unit.id,
"uom_po_id": self.uom_unit.id,
"categ_id": self.food_category.id,
}
)
self.assertEqual(product.meal_voucher_ok, True)
# Affect product to a non-food category and run onchange
product.categ_id = self.main_category.id
product.onchange_categ_id_pos_meal_voucher()
self.assertEqual(product.meal_voucher_ok, False)
def test_product_template(self):
template = self.ProductTemplate.create(
{
"name": "Product",
"uom_id": self.uom_unit.id,
"uom_po_id": self.uom_unit.id,
"categ_id": self.food_category.id,
}
)
self.assertEqual(template.meal_voucher_ok, True)
# Affect template to a non-food category and run onchange
template.categ_id = self.main_category.id
template.onchange_categ_id_pos_meal_voucher()
self.assertEqual(template.meal_voucher_ok, False)
# Set non-food category as a food category and propagate settings
# to all the child product
self.main_category.meal_voucher_ok = True
self.main_category.button_apply_meal_voucher_settings()
self.assertEqual(template.meal_voucher_ok, True)

View file

@ -0,0 +1,21 @@
<?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="pos_payment_method_view_form" model="ir.ui.view">
<field name="model">pos.payment.method</field>
<field name="inherit_id" ref="point_of_sale.pos_payment_method_view_form" />
<field name="arch" type="xml">
<group name="Payment methods" position="inside">
<group>
<field name="meal_voucher_type" />
</group>
</group>
</field>
</record>
</odoo>

View file

@ -0,0 +1,65 @@
<?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="res_config_settings_view_form" model="ir.ui.view">
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="point_of_sale.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[@id='pos_payment_section']" 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">Maximum Amount</span>
<div class="text-muted">
Optional maximum amount per order that can be paid by meal vouchers.
Set to 0 to disable.
</div>
<div class="content-group mt16">
<field
name="pos_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="pos_enable_meal_voucher_order_lines_icon" />
</div>
<div class="o_setting_right_pane">
<label
for="pos_enable_meal_voucher_order_lines_icon"
string="Icon on Order Lines"
/>
<div class="text-muted">
If checked, an icon will be displayed on point of sale order lines (on the product screen) for products that can be paid for by meal vouchers.
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="pos_enable_meal_voucher_receipt_info" />
</div>
<div class="o_setting_right_pane">
<label
for="pos_enable_meal_voucher_receipt_info"
string="Information on Receipt"
/>
<div class="text-muted">
If checked, an asterisk (*) will be displayed on receipts before each product that can be paid for by meal vouchers as well as the total eligible amount.
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

View file

@ -0,0 +1,27 @@
<?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="Set the above &quot;Can be Paid for by Meal Vouchers&quot; value on all of the products of this category"
icon="fa-cogs"
colspan="2"
/>
</field>
</field>
</record>
</odoo>

View file

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

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-oca-pos-pos_meal_voucher"
version = "16.0.0"
description = "Point Of Sale - Meal Voucher - Handle meal vouchers in Point of Sale with eligible amount and max amount"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-ocb-point_of_sale>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["pos_meal_voucher"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]