-
119pos_barcode_tare/README.rst
-
2pos_barcode_tare/__init__.py
-
24pos_barcode_tare/__openerp__.py
-
12pos_barcode_tare/data/barcode_rule.xml
-
9pos_barcode_tare/demo/pos_barcode_tare_demo.xml
-
191pos_barcode_tare/i18n/fr_CH.po
-
191pos_barcode_tare/i18n/pos_barcode_tare.pot
-
2pos_barcode_tare/models/__init__.py
-
14pos_barcode_tare/models/barcode_rule.py
-
11pos_barcode_tare/models/pos_config.py
-
8pos_barcode_tare/pos_barcode_tare.xml
-
4pos_barcode_tare/readme/CONTRIBUTORS.rst
-
30pos_barcode_tare/readme/DESCRIPTION.rst
-
1pos_barcode_tare/readme/ROADMAP.rst
-
5pos_barcode_tare/readme/USAGE.rst
-
BINpos_barcode_tare/static/description/POS_with_button.png
-
BINpos_barcode_tare/static/description/icon.png
-
457pos_barcode_tare/static/description/index.html
-
BINpos_barcode_tare/static/description/label.png
-
BINpos_barcode_tare/static/description/null_weight.png
-
BINpos_barcode_tare/static/description/ready_to_print.png
-
BINpos_barcode_tare/static/description/zoom_action_widget.png
-
111pos_barcode_tare/static/src/css/pos_barcode_tare.css
-
359pos_barcode_tare/static/src/js/pos_barcode_tare.js
-
86pos_barcode_tare/static/src/xml/pos_barcode_tare.xml
-
16pos_barcode_tare/views/pos_config_view.xml
@ -0,0 +1,119 @@ |
|||
==================================================== |
|||
Point of Sale - Tare barecode labels for loose goods |
|||
==================================================== |
|||
|
|||
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
|||
!! This file is generated by oca-gen-addon-readme !! |
|||
!! changes will be overwritten. !! |
|||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
|||
|
|||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png |
|||
:target: https://odoo-community.org/page/development-status |
|||
:alt: Beta |
|||
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png |
|||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github |
|||
:target: https://github.com/OCA/pos/tree/9.0/pos_barcode_tare |
|||
:alt: OCA/pos |
|||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png |
|||
:target: https://translation.odoo-community.org/projects/pos-9-0/pos-9-0-pos_barcode_tare |
|||
:alt: Translate me on Weblate |
|||
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png |
|||
:target: https://runbot.odoo-community.org/runbot/184/9.0 |
|||
:alt: Try me on Runbot |
|||
|
|||
|badge1| |badge2| |badge3| |badge4| |badge5| |
|||
|
|||
This add-on enables POS to read and print tare barcodes. We print a barcode tare label to sell loose goods in a Bring Your Own pot (BYOC) scheme. |
|||
|
|||
The BYOC scheme has five steps: |
|||
1. The cashier weighs the pot and sticks the tare barcode onto the customer's pot. |
|||
2. The customer go and put loose goods into the labeled pot. |
|||
3. The cashier weighs the pot with loose goods inside. POS computes the price including the pot. |
|||
4. The cashier scans the tare barcode. POS get the pot weight from the barcode. POS subtracts the pot weight from the weight of the latest product. POS sets the billable price for the loose goods. |
|||
5. The customer pays. |
|||
|
|||
This add-on adds a news screen to POS to print (web) the tare barcode labels. This add-on enables POS to read a tare barcode. Reading a barcode makes POS adjust the weight of the latest article in the order list. The new weight is equal to the total weight minus the tare weight. The price is updated accordingly to the weight change. |
|||
|
|||
POS home screen is now: |
|||
|
|||
.. image:: https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/POS_with_button.png |
|||
|
|||
The label screen is: |
|||
|
|||
.. image:: https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/null_weight.png |
|||
|
|||
When we read a weight the impression button is enabled |
|||
|
|||
.. image:: https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/ready_to_print.png |
|||
|
|||
A barcode label looks like: |
|||
|
|||
.. image:: https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/label.png |
|||
|
|||
Zoom on the action widget: |
|||
|
|||
.. image:: https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/zoom_action_widget.png |
|||
|
|||
**Table of contents** |
|||
|
|||
.. contents:: |
|||
:local: |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
Install this add-on and configure the point of sale where you want to be able to use the tare barecode. The label printing is done using web print. To streamline the label printing it is advised to use the silent printing mode (firefox) or the kiosk printing (chrome). |
|||
|
|||
The command line to start a chrome base browser in kiosk mode with silent printing looks like: |
|||
|
|||
``chromium-browser --use-system-default-printer --kiosk --kiosk-printing http://localhost:8069/`` |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
- Merge with Sylvain LE GAL tare module that allows user to set tare on the scale screen. |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/pos/issues>`_. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed |
|||
`feedback <https://github.com/OCA/pos/issues/new?body=module:%20pos_barcode_tare%0Aversion:%209.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 |
|||
~~~~~~~ |
|||
|
|||
* Le Nid |
|||
|
|||
Contributors |
|||
~~~~~~~~~~~~ |
|||
|
|||
- Le Nid |
|||
- Sylvain LE GAL |
|||
- CoopITEasy |
|||
|
|||
|
|||
Maintainers |
|||
~~~~~~~~~~~ |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
OCA, or the Odoo Community Association, is a nonprofit organization whose |
|||
mission is to support the collaborative development of Odoo features and |
|||
promote its widespread use. |
|||
|
|||
This module is part of the `OCA/pos <https://github.com/OCA/pos/tree/9.0/pos_barcode_tare>`_ project on GitHub. |
|||
|
|||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -0,0 +1,24 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# @author: François Kawala |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
{ |
|||
'name': "Point of Sale - Tare barecode labels for loose goods", |
|||
'version': '9.0.0.0.1', |
|||
'category': 'Point of Sale', |
|||
'summary': """Point of Sale - Print and scan tare \ |
|||
barecodes labels to sell loose goods.""", |
|||
'author': "Le Nid, Odoo Community Association (OCA)", |
|||
'website': "https://github.com/OCA/pos", |
|||
'license': 'AGPL-3', |
|||
'depends': ['point_of_sale'], |
|||
'demo': ['demo/pos_barcode_tare_demo.xml'], |
|||
'data': [ |
|||
'pos_barcode_tare.xml', |
|||
'views/pos_config_view.xml', |
|||
'data/barcode_rule.xml', |
|||
], |
|||
'qweb': [ |
|||
'static/src/xml/pos_barcode_tare.xml', |
|||
], |
|||
'installable': True, |
|||
} |
@ -0,0 +1,12 @@ |
|||
<?xml version="1.0"?> |
|||
|
|||
<odoo noupdate="1"> |
|||
<record id="barcode_rule_tare" model="barcode.rule"> |
|||
<field name="name">Tare</field> |
|||
<field name="barcode_nomenclature_id" ref="barcodes.default_barcode_nomenclature"/> |
|||
<field name="sequence">81</field> |
|||
<field name="type">tare</field> |
|||
<field name="encoding">ean13</field> |
|||
<field name="pattern">0700000{NNDDD}</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<record id="product_uom_kgm_dbg" model="product.uom"> |
|||
<field name="category_id" ref="product.product_uom_categ_kgm"/> |
|||
<field name="name">Kg</field> |
|||
<field name="factor" eval="1"/> |
|||
<field name="rounding" eval="0.001"/> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,191 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * pos_barcode_tare |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 9.0c\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2020-02-14 06:44+0000\n" |
|||
"PO-Revision-Date: 2020-02-14 06:44+0000\n" |
|||
"Last-Translator: <>\n" |
|||
"Language-Team: \n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: \n" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:8 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:8 |
|||
#, python-format |
|||
msgid "Back" |
|||
msgstr "Retour" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:130 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:130 |
|||
#, python-format |
|||
msgid "Failed to read weight from scale." |
|||
msgstr "Echec lors de la lecture du poids depuis la balance" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:product.uom,name:pos_barcode_tare.product_uom_kgm_dbg |
|||
msgid "Kg" |
|||
msgstr "Kg" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.ui.view,arch_db:pos_barcode_tare.view_pos_config_form |
|||
msgid "Loose good options" |
|||
msgstr "Options pour la vente en vrac" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:196 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:196 |
|||
#, python-format |
|||
msgid "Maximum tare weight is 99.999kg" |
|||
msgstr "Le poids mesuré est supérieur au poids maximum pour la tare: 99.999kg" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:18 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:18 |
|||
#, python-format |
|||
msgid "Print" |
|||
msgstr "Imprimer l'étiquette" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:11 |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:41 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:11 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:41 |
|||
#, python-format |
|||
msgid "Print a tare label" |
|||
msgstr "Imprimer une étiquette de tare" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.model.fields,help:pos_barcode_tare.field_pos_config_iface_tare_label |
|||
msgid "Print tare labels with this POS" |
|||
msgstr "Utiliser ce POS pour imprimer les étiquettes de tare" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:15 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:15 |
|||
#, python-format |
|||
msgid "Set the pot on the scale and check the weight above" |
|||
msgstr "Placez le récipient à tarer sur la balance puis vérifiez le poids ci-dessus" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.model.fields,field_description:pos_barcode_tare.field_pos_config_iface_tare_label |
|||
msgid "Show tare label button" |
|||
msgstr "Utiliser ce POS pour imprimer les étiquettes de tare" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: code:addons/addons/pos_barcode_tare/models/barcode_rule.py:13 |
|||
#: code:addons/pos_barcode_tare/models/barcode_rule.py:13 |
|||
#, python-format |
|||
msgid "Tare" |
|||
msgstr "Tare" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:164 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:164 |
|||
#, python-format |
|||
msgid "The scale sent a measure in %s unit. This unit of measure (UOM) in not found in the point of sale. You may need to create a new UOM named %s. The UOM name is case sensitive." |
|||
msgstr "La balance à envoyé une mesure en %s. Cette unité de mesure (UOM) n'existe pas. Vous devez probablement créer une UOM nommée %s. Le nom de l'UOM est sensible à la casse." |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:288 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:288 |
|||
#, python-format |
|||
msgid "The tare (%s) is already set for the product \"%s\". We can not re-apply a tare to this product." |
|||
msgstr "La tare (%s) est déjà mesurée pour le produit \"%s\". Nous ne pouvons plus appliquer de tare à ce produit." |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:319 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:319 |
|||
#, python-format |
|||
msgid "The tare weight is %s %s, it's greater or equal to the product weight %s. We can not apply this tare." |
|||
msgstr "Le poids de la tare est de %s %s, c'est plus que le poids du produit %s. Nous ne pouvons pas appliquer cette tare." |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:74 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:74 |
|||
#, python-format |
|||
msgid "We can not apply this tare barcode." |
|||
msgstr "Impossible d'appliquer cette étiquette de tare." |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:33 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:33 |
|||
#, python-format |
|||
msgid "We can not cast a weight in %s into %s." |
|||
msgstr "Nous ne pouvons pas convertir un poids en %s en %s." |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:product.uom.categ,name:pos_barcode_tare.product_uom_categ_kgm |
|||
msgid "Weight" |
|||
msgstr "Poids" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:69 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:69 |
|||
#, python-format |
|||
msgid "With a" |
|||
msgstr "Avec un(e)" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:61 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:61 |
|||
#, python-format |
|||
msgid "at" |
|||
msgstr "à" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.model,name:pos_barcode_tare.model_barcode_rule |
|||
msgid "barcode.rule" |
|||
msgstr "barcode.rule" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:71 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:71 |
|||
#, python-format |
|||
msgid "discount" |
|||
msgstr "remise" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:32 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:32 |
|||
#, python-format |
|||
msgid "kg" |
|||
msgstr "kg" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.model,name:pos_barcode_tare.model_pos_config |
|||
msgid "pos.config" |
|||
msgstr "pos.config" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:32 |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:78 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:32 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:78 |
|||
#, python-format |
|||
msgid "tare =" |
|||
msgstr "tare =" |
|||
|
@ -0,0 +1,191 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * pos_barcode_tare |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 9.0c\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2020-02-14 06:05+0000\n" |
|||
"PO-Revision-Date: 2020-02-14 06:05+0000\n" |
|||
"Last-Translator: <>\n" |
|||
"Language-Team: \n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: \n" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:8 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:8 |
|||
#, python-format |
|||
msgid "Back" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:130 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:130 |
|||
#, python-format |
|||
msgid "Failed to read weight from scale." |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:product.uom,name:pos_barcode_tare.product_uom_kgm_dbg |
|||
msgid "Kg" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.ui.view,arch_db:pos_barcode_tare.view_pos_config_form |
|||
msgid "Loose good options" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:196 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:196 |
|||
#, python-format |
|||
msgid "Maximum tare weight is 99.999kg" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:18 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:18 |
|||
#, python-format |
|||
msgid "Print" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:11 |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:41 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:11 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:41 |
|||
#, python-format |
|||
msgid "Print a tare label" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.model.fields,help:pos_barcode_tare.field_pos_config_iface_tare_label |
|||
msgid "Print tare labels with this POS" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:15 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:15 |
|||
#, python-format |
|||
msgid "Set the pot on the scale and check the weight above" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.model.fields,field_description:pos_barcode_tare.field_pos_config_iface_tare_label |
|||
msgid "Show tare label button" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: code:addons/addons/pos_barcode_tare/models/barcode_rule.py:13 |
|||
#: code:addons/pos_barcode_tare/models/barcode_rule.py:13 |
|||
#, python-format |
|||
msgid "Tare" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:164 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:164 |
|||
#, python-format |
|||
msgid "The scale sent a measure in %s unit. This unit of measure (UOM) in not found in the point of sale. You may need to create a new UOM named %s. The UOM name is case sensitive." |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:288 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:288 |
|||
#, python-format |
|||
msgid "The tare (%s) is already set for the product \"%s\". We can not re-apply a tare to this product." |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:319 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:319 |
|||
#, python-format |
|||
msgid "The tare weight is %s %s this is greater or equal to the product weight %s. We can not apply this tare." |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:74 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:74 |
|||
#, python-format |
|||
msgid "We can not apply this tare barcode." |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:33 |
|||
#: code:addons/pos_barcode_tare/static/src/js/pos_barcode_tare.js:33 |
|||
#, python-format |
|||
msgid "We can not cast a weight in %s into %s." |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:product.uom.categ,name:pos_barcode_tare.product_uom_categ_kgm |
|||
msgid "Weight" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:69 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:69 |
|||
#, python-format |
|||
msgid "With a" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:61 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:61 |
|||
#, python-format |
|||
msgid "at" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.model,name:pos_barcode_tare.model_barcode_rule |
|||
msgid "barcode.rule" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:71 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:71 |
|||
#, python-format |
|||
msgid "discount" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:32 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:32 |
|||
#, python-format |
|||
msgid "kg" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#: model:ir.model,name:pos_barcode_tare.model_pos_config |
|||
msgid "pos.config" |
|||
msgstr "" |
|||
|
|||
#. module: pos_barcode_tare |
|||
#. openerp-web |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:32 |
|||
#: code:addons/addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:78 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:32 |
|||
#: code:addons/pos_barcode_tare/static/src/xml/pos_barcode_tare.xml:78 |
|||
#, python-format |
|||
msgid "tare =" |
|||
msgstr "" |
|||
|
@ -0,0 +1,2 @@ |
|||
from . import pos_config |
|||
from . import barcode_rule |
@ -0,0 +1,14 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from openerp import _, models, api |
|||
|
|||
|
|||
class BarcodeRule(models.Model): |
|||
_inherit = 'barcode.rule' |
|||
|
|||
@api.model |
|||
def _get_type_selection(self): |
|||
res = super(BarcodeRule, self)._get_type_selection() |
|||
res.append( |
|||
('tare', _('Tare'))) |
|||
return res |
@ -0,0 +1,11 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from openerp import models, fields |
|||
|
|||
|
|||
class PosConfig(models.Model): |
|||
_inherit = 'pos.config' |
|||
iface_tare_label = fields.Boolean( |
|||
'Show tare label button', |
|||
help="Print tare labels with this POS" |
|||
) |
@ -0,0 +1,8 @@ |
|||
<odoo> |
|||
<template id="assets_backend" name="pos_barcode_tare" inherit_id="point_of_sale.assets"> |
|||
<xpath expr="." position="inside"> |
|||
<link rel="stylesheet" href="/pos_barcode_tare/static/src/css/pos_barcode_tare.css"/> |
|||
<script type="text/javascript" src="/pos_barcode_tare/static/src/js/pos_barcode_tare.js"></script> |
|||
</xpath> |
|||
</template> |
|||
</odoo> |
@ -0,0 +1,4 @@ |
|||
- Le Nid |
|||
- Sylvain LE GAL |
|||
- CoopITEasy |
|||
|
@ -0,0 +1,30 @@ |
|||
This add-on enables POS to read and print tare barcodes. We print a barcode tare label to sell loose goods in a Bring Your Own pot (BYOC) scheme. |
|||
|
|||
The BYOC scheme has five steps: |
|||
1. The cashier weighs the pot and sticks the tare barcode onto the customer's pot. |
|||
2. The customer go and put loose goods into the labeled pot. |
|||
3. The cashier weighs the pot with loose goods inside. POS computes the price including the pot. |
|||
4. The cashier scans the tare barcode. POS get the pot weight from the barcode. POS subtracts the pot weight from the weight of the latest product. POS sets the billable price for the loose goods. |
|||
5. The customer pays. |
|||
|
|||
This add-on adds a news screen to POS to print (web) the tare barcode labels. This add-on enables POS to read a tare barcode. Reading a barcode makes POS adjust the weight of the latest article in the order list. The new weight is equal to the total weight minus the tare weight. The price is updated accordingly to the weight change. |
|||
|
|||
POS home screen is now: |
|||
|
|||
.. image:: ../static/description/POS_with_button.png |
|||
|
|||
The label screen is: |
|||
|
|||
.. image:: ../static/description/null_weight.png |
|||
|
|||
When we read a weight the impression button is enabled |
|||
|
|||
.. image:: ../static/description/ready_to_print.png |
|||
|
|||
A barcode label looks like: |
|||
|
|||
.. image:: ../static/description/label.png |
|||
|
|||
Zoom on the action widget: |
|||
|
|||
.. image:: ../static/description/zoom_action_widget.png |
@ -0,0 +1 @@ |
|||
- Merge with Sylvain LE GAL tare module that allows user to set tare on the scale screen. |
@ -0,0 +1,5 @@ |
|||
Install this add-on and configure the point of sale where you want to be able to use the tare barecode. The label printing is done using web print. To streamline the label printing it is advised to use the silent printing mode (firefox) or the kiosk printing (chrome). |
|||
|
|||
The command line to start a chrome base browser in kiosk mode with silent printing looks like: |
|||
|
|||
``chromium-browser --use-system-default-printer --kiosk --kiosk-printing http://localhost:8069/`` |
After Width: 960 | Height: 540 | Size: 198 KiB |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,457 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
|||
<head> |
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|||
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" /> |
|||
<title>Point of Sale - Tare barecode labels for loose goods</title> |
|||
<style type="text/css"> |
|||
|
|||
/* |
|||
:Author: David Goodger (goodger@python.org) |
|||
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ |
|||
:Copyright: This stylesheet has been placed in the public domain. |
|||
|
|||
Default cascading style sheet for the HTML output of Docutils. |
|||
|
|||
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to |
|||
customize this style sheet. |
|||
*/ |
|||
|
|||
/* used to remove borders from tables and images */ |
|||
.borderless, table.borderless td, table.borderless th { |
|||
border: 0 } |
|||
|
|||
table.borderless td, table.borderless th { |
|||
/* Override padding for "table.docutils td" with "! important". |
|||
The right padding separates the table cells. */ |
|||
padding: 0 0.5em 0 0 ! important } |
|||
|
|||
.first { |
|||
/* Override more specific margin styles with "! important". */ |
|||
margin-top: 0 ! important } |
|||
|
|||
.last, .with-subtitle { |
|||
margin-bottom: 0 ! important } |
|||
|
|||
.hidden { |
|||
display: none } |
|||
|
|||
.subscript { |
|||
vertical-align: sub; |
|||
font-size: smaller } |
|||
|
|||
.superscript { |
|||
vertical-align: super; |
|||
font-size: smaller } |
|||
|
|||
a.toc-backref { |
|||
text-decoration: none ; |
|||
color: black } |
|||
|
|||
blockquote.epigraph { |
|||
margin: 2em 5em ; } |
|||
|
|||
dl.docutils dd { |
|||
margin-bottom: 0.5em } |
|||
|
|||
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { |
|||
overflow: hidden; |
|||
} |
|||
|
|||
/* Uncomment (and remove this text!) to get bold-faced definition list terms |
|||
dl.docutils dt { |
|||
font-weight: bold } |
|||
*/ |
|||
|
|||
div.abstract { |
|||
margin: 2em 5em } |
|||
|
|||
div.abstract p.topic-title { |
|||
font-weight: bold ; |
|||
text-align: center } |
|||
|
|||
div.admonition, div.attention, div.caution, div.danger, div.error, |
|||
div.hint, div.important, div.note, div.tip, div.warning { |
|||
margin: 2em ; |
|||
border: medium outset ; |
|||
padding: 1em } |
|||
|
|||
div.admonition p.admonition-title, div.hint p.admonition-title, |
|||
div.important p.admonition-title, div.note p.admonition-title, |
|||
div.tip p.admonition-title { |
|||
font-weight: bold ; |
|||
font-family: sans-serif } |
|||
|
|||
div.attention p.admonition-title, div.caution p.admonition-title, |
|||
div.danger p.admonition-title, div.error p.admonition-title, |
|||
div.warning p.admonition-title, .code .error { |
|||
color: red ; |
|||
font-weight: bold ; |
|||
font-family: sans-serif } |
|||
|
|||
/* Uncomment (and remove this text!) to get reduced vertical space in |
|||
compound paragraphs. |
|||
div.compound .compound-first, div.compound .compound-middle { |
|||
margin-bottom: 0.5em } |
|||
|
|||
div.compound .compound-last, div.compound .compound-middle { |
|||
margin-top: 0.5em } |
|||
*/ |
|||
|
|||
div.dedication { |
|||
margin: 2em 5em ; |
|||
text-align: center ; |
|||
font-style: italic } |
|||
|
|||
div.dedication p.topic-title { |
|||
font-weight: bold ; |
|||
font-style: normal } |
|||
|
|||
div.figure { |
|||
margin-left: 2em ; |
|||
margin-right: 2em } |
|||
|
|||
div.footer, div.header { |
|||
clear: both; |
|||
font-size: smaller } |
|||
|
|||
div.line-block { |
|||
display: block ; |
|||
margin-top: 1em ; |
|||
margin-bottom: 1em } |
|||
|
|||
div.line-block div.line-block { |
|||
margin-top: 0 ; |
|||
margin-bottom: 0 ; |
|||
margin-left: 1.5em } |
|||
|
|||
div.sidebar { |
|||
margin: 0 0 0.5em 1em ; |
|||
border: medium outset ; |
|||
padding: 1em ; |
|||
background-color: #ffffee ; |
|||
width: 40% ; |
|||
float: right ; |
|||
clear: right } |
|||
|
|||
div.sidebar p.rubric { |
|||
font-family: sans-serif ; |
|||
font-size: medium } |
|||
|
|||
div.system-messages { |
|||
margin: 5em } |
|||
|
|||
div.system-messages h1 { |
|||
color: red } |
|||
|
|||
div.system-message { |
|||
border: medium outset ; |
|||
padding: 1em } |
|||
|
|||
div.system-message p.system-message-title { |
|||
color: red ; |
|||
font-weight: bold } |
|||
|
|||
div.topic { |
|||
margin: 2em } |
|||
|
|||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, |
|||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { |
|||
margin-top: 0.4em } |
|||
|
|||
h1.title { |
|||
text-align: center } |
|||
|
|||
h2.subtitle { |
|||
text-align: center } |
|||
|
|||
hr.docutils { |
|||
width: 75% } |
|||
|
|||
img.align-left, .figure.align-left, object.align-left, table.align-left { |
|||
clear: left ; |
|||
float: left ; |
|||
margin-right: 1em } |
|||
|
|||
img.align-right, .figure.align-right, object.align-right, table.align-right { |
|||
clear: right ; |
|||
float: right ; |
|||
margin-left: 1em } |
|||
|
|||
img.align-center, .figure.align-center, object.align-center { |
|||
display: block; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
|
|||
table.align-center { |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
|
|||
.align-left { |
|||
text-align: left } |
|||
|
|||
.align-center { |
|||
clear: both ; |
|||
text-align: center } |
|||
|
|||
.align-right { |
|||
text-align: right } |
|||
|
|||
/* reset inner alignment in figures */ |
|||
div.align-right { |
|||
text-align: inherit } |
|||
|
|||
/* div.align-center * { */ |
|||
/* text-align: left } */ |
|||
|
|||
.align-top { |
|||
vertical-align: top } |
|||
|
|||
.align-middle { |
|||
vertical-align: middle } |
|||
|
|||
.align-bottom { |
|||
vertical-align: bottom } |
|||
|
|||
ol.simple, ul.simple { |
|||
margin-bottom: 1em } |
|||
|
|||
ol.arabic { |
|||
list-style: decimal } |
|||
|
|||
ol.loweralpha { |
|||
list-style: lower-alpha } |
|||
|
|||
ol.upperalpha { |
|||
list-style: upper-alpha } |
|||
|
|||
ol.lowerroman { |
|||
list-style: lower-roman } |
|||
|
|||
ol.upperroman { |
|||
list-style: upper-roman } |
|||
|
|||
p.attribution { |
|||
text-align: right ; |
|||
margin-left: 50% } |
|||
|
|||
p.caption { |
|||
font-style: italic } |
|||
|
|||
p.credits { |
|||
font-style: italic ; |
|||
font-size: smaller } |
|||
|
|||
p.label { |
|||
white-space: nowrap } |
|||
|
|||
p.rubric { |
|||
font-weight: bold ; |
|||
font-size: larger ; |
|||
color: maroon ; |
|||
text-align: center } |
|||
|
|||
p.sidebar-title { |
|||
font-family: sans-serif ; |
|||
font-weight: bold ; |
|||
font-size: larger } |
|||
|
|||
p.sidebar-subtitle { |
|||
font-family: sans-serif ; |
|||
font-weight: bold } |
|||
|
|||
p.topic-title { |
|||
font-weight: bold } |
|||
|
|||
pre.address { |
|||
margin-bottom: 0 ; |
|||
margin-top: 0 ; |
|||
font: inherit } |
|||
|
|||
pre.literal-block, pre.doctest-block, pre.math, pre.code { |
|||
margin-left: 2em ; |
|||
margin-right: 2em } |
|||
|
|||
pre.code .ln { color: grey; } /* line numbers */ |
|||
pre.code, code { background-color: #eeeeee } |
|||
pre.code .comment, code .comment { color: #5C6576 } |
|||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } |
|||
pre.code .literal.string, code .literal.string { color: #0C5404 } |
|||
pre.code .name.builtin, code .name.builtin { color: #352B84 } |
|||
pre.code .deleted, code .deleted { background-color: #DEB0A1} |
|||
pre.code .inserted, code .inserted { background-color: #A3D289} |
|||
|
|||
span.classifier { |
|||
font-family: sans-serif ; |
|||
font-style: oblique } |
|||
|
|||
span.classifier-delimiter { |
|||
font-family: sans-serif ; |
|||
font-weight: bold } |
|||
|
|||
span.interpreted { |
|||
font-family: sans-serif } |
|||
|
|||
span.option { |
|||
white-space: nowrap } |
|||
|
|||
span.pre { |
|||
white-space: pre } |
|||
|
|||
span.problematic { |
|||
color: red } |
|||
|
|||
span.section-subtitle { |
|||
/* font-size relative to parent (h1..h6 element) */ |
|||
font-size: 80% } |
|||
|
|||
table.citation { |
|||
border-left: solid 1px gray; |
|||
margin-left: 1px } |
|||
|
|||
table.docinfo { |
|||
margin: 2em 4em } |
|||
|
|||
table.docutils { |
|||
margin-top: 0.5em ; |
|||
margin-bottom: 0.5em } |
|||
|
|||
table.footnote { |
|||
border-left: solid 1px black; |
|||
margin-left: 1px } |
|||
|
|||
table.docutils td, table.docutils th, |
|||
table.docinfo td, table.docinfo th { |
|||
padding-left: 0.5em ; |
|||
padding-right: 0.5em ; |
|||
vertical-align: top } |
|||
|
|||
table.docutils th.field-name, table.docinfo th.docinfo-name { |
|||
font-weight: bold ; |
|||
text-align: left ; |
|||
white-space: nowrap ; |
|||
padding-left: 0 } |
|||
|
|||
/* "booktabs" style (no vertical lines) */ |
|||
table.docutils.booktabs { |
|||
border: 0px; |
|||
border-top: 2px solid; |
|||
border-bottom: 2px solid; |
|||
border-collapse: collapse; |
|||
} |
|||
table.docutils.booktabs * { |
|||
border: 0px; |
|||
} |
|||
table.docutils.booktabs th { |
|||
border-bottom: thin solid; |
|||
text-align: left; |
|||
} |
|||
|
|||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, |
|||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { |
|||
font-size: 100% } |
|||
|
|||
ul.auto-toc { |
|||
list-style-type: none } |
|||
|
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div class="document" id="point-of-sale-tare-barecode-labels-for-loose-goods"> |
|||
<h1 class="title">Point of Sale - Tare barecode labels for loose goods</h1> |
|||
|
|||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
|||
!! This file is generated by oca-gen-addon-readme !! |
|||
!! changes will be overwritten. !! |
|||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> |
|||
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/pos/tree/9.0/pos_barcode_tare"><img alt="OCA/pos" src="https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/pos-9-0/pos-9-0-pos_barcode_tare"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/184/9.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> |
|||
<p>This add-on enables POS to read and print tare barcodes. We print a barcode tare label to sell loose goods in a Bring Your Own pot (BYOC) scheme.</p> |
|||
<dl class="docutils"> |
|||
<dt>The BYOC scheme has five steps:</dt> |
|||
<dd><ol class="first last arabic simple"> |
|||
<li>The cashier weighs the pot and sticks the tare barcode onto the customer’s pot.</li> |
|||
<li>The customer go and put loose goods into the labeled pot.</li> |
|||
<li>The cashier weighs the pot with loose goods inside. POS computes the price including the pot.</li> |
|||
<li>The cashier scans the tare barcode. POS get the pot weight from the barcode. POS subtracts the pot weight from the weight of the latest product. POS sets the billable price for the loose goods.</li> |
|||
<li>The customer pays.</li> |
|||
</ol> |
|||
</dd> |
|||
</dl> |
|||
<p>This add-on adds a news screen to POS to print (web) the tare barcode labels. This add-on enables POS to read a tare barcode. Reading a barcode makes POS adjust the weight of the latest article in the order list. The new weight is equal to the total weight minus the tare weight. The price is updated accordingly to the weight change.</p> |
|||
<p>POS home screen is now:</p> |
|||
<img alt="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/POS_with_button.png" src="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/POS_with_button.png" /> |
|||
<p>The label screen is:</p> |
|||
<img alt="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/null_weight.png" src="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/null_weight.png" /> |
|||
<p>When we read a weight the impression button is enabled</p> |
|||
<img alt="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/ready_to_print.png" src="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/ready_to_print.png" /> |
|||
<p>A barcode label looks like:</p> |
|||
<img alt="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/label.png" src="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/label.png" /> |
|||
<p>Zoom on the action widget:</p> |
|||
<img alt="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/zoom_action_widget.png" src="https://raw.githubusercontent.com/OCA/pos/9.0/pos_barcode_tare/static/description/zoom_action_widget.png" /> |
|||
<p><strong>Table of contents</strong></p> |
|||
<div class="contents local topic" id="contents"> |
|||
<ul class="simple"> |
|||
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li> |
|||
<li><a class="reference internal" href="#known-issues-roadmap" id="id2">Known issues / Roadmap</a></li> |
|||
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li> |
|||
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul> |
|||
<li><a class="reference internal" href="#authors" id="id5">Authors</a></li> |
|||
<li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li> |
|||
<li><a class="reference internal" href="#maintainers" id="id7">Maintainers</a></li> |
|||
</ul> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<div class="section" id="usage"> |
|||
<h1><a class="toc-backref" href="#id1">Usage</a></h1> |
|||
<p>Install this add-on and configure the point of sale where you want to be able to use the tare barecode. The label printing is done using web print. To streamline the label printing it is advised to use the silent printing mode (firefox) or the kiosk printing (chrome).</p> |
|||
<p>The command line to start a chrome base browser in kiosk mode with silent printing looks like:</p> |
|||
<p><tt class="docutils literal"><span class="pre">chromium-browser</span> <span class="pre">--use-system-default-printer</span> <span class="pre">--kiosk</span> <span class="pre">--kiosk-printing</span> <span class="pre">http://localhost:8069/</span></tt></p> |
|||
</div> |
|||
<div class="section" id="known-issues-roadmap"> |
|||
<h1><a class="toc-backref" href="#id2">Known issues / Roadmap</a></h1> |
|||
<ul class="simple"> |
|||
<li>Merge with Sylvain LE GAL tare module that allows user to set tare on the scale screen.</li> |
|||
</ul> |
|||
</div> |
|||
<div class="section" id="bug-tracker"> |
|||
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1> |
|||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/pos/issues">GitHub Issues</a>. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed |
|||
<a class="reference external" href="https://github.com/OCA/pos/issues/new?body=module:%20pos_barcode_tare%0Aversion:%209.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="#id4">Credits</a></h1> |
|||
<div class="section" id="authors"> |
|||
<h2><a class="toc-backref" href="#id5">Authors</a></h2> |
|||
<ul class="simple"> |
|||
<li>Le Nid</li> |
|||
</ul> |
|||
</div> |
|||
<div class="section" id="contributors"> |
|||
<h2><a class="toc-backref" href="#id6">Contributors</a></h2> |
|||
<ul class="simple"> |
|||
<li>Le Nid</li> |
|||
<li>Sylvain LE GAL</li> |
|||
<li>CoopITEasy</li> |
|||
</ul> |
|||
</div> |
|||
<div class="section" id="maintainers"> |
|||
<h2><a class="toc-backref" href="#id7">Maintainers</a></h2> |
|||
<p>This module is maintained by the OCA.</p> |
|||
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> |
|||
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose |
|||
mission is to support the collaborative development of Odoo features and |
|||
promote its widespread use.</p> |
|||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/pos/tree/9.0/pos_barcode_tare">OCA/pos</a> project on GitHub.</p> |
|||
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
After Width: 576 | Height: 393 | Size: 7.4 KiB |
After Width: 960 | Height: 540 | Size: 20 KiB |
After Width: 960 | Height: 540 | Size: 21 KiB |
After Width: 437 | Height: 292 | Size: 15 KiB |
@ -0,0 +1,111 @@ |
|||
.pos .print-label.disabled { |
|||
background: #e2e2e2; |
|||
border: solid 1px #BEBEBE; |
|||
opacity: 0.5; |
|||
cursor: default; |
|||
color: inherit; |
|||
} |
|||
|
|||
.pos .pos-tare-label { |
|||
width: 300px; |
|||
background-color: white; |
|||
margin: 20px; |
|||
padding: 15px; |
|||
font-size: 21px; |
|||
padding-bottom:30px; |
|||
display: inline-block; |
|||
font-family: "Inconsolata"; |
|||
border: solid 1px rgb(220,220,220); |
|||
border-radius: 3px; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.pos .pos-tare-label .caption { |
|||
display: block; |
|||
} |
|||
|
|||
.pos .tare-screen .pos-directions-for-user { |
|||
font-size: 25px; |
|||
margin: 8px; |
|||
text-align: center; |
|||
line-height: 2; |
|||
} |
|||
|
|||
.pos .tare-screen .pos-directions-for-user span { |
|||
width:100px; |
|||
height: 50px; |
|||
background-color: rgb(49,174,218); |
|||
color: white !important; |
|||
font-weight: bold; |
|||
border: solid 1px black; |
|||
border-radius: 90% 30%; |
|||
display: flex; |
|||
align-items: center; |
|||
overflow: hidden; |
|||
vertical-align:middle; |
|||
justify-content: center; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
|
|||
.pos .pos-tare-label img { |
|||
width: 50mm; |
|||
height: 45mm; |
|||
} |
|||
|
|||
.pos .tare-screen .print-label { |
|||
text-align: center; |
|||
font-size: 32px; |
|||
background: rgb(110,200,155); |
|||
color: white; |
|||
border-radius: 3px; |
|||
padding: 16px; |
|||
margin: 16px; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
@media print { |
|||
.pos .tare-screen header, |
|||
.pos .tare-screen .top-content, |
|||
.pos .tare-screen .centered-content .print-label, |
|||
.pos .tare-screen .pos-directions-for-user { |
|||
display: none !important; |
|||
} |
|||
|
|||
.pos .tare-screen .centered-content { |
|||
position: static; |
|||
border: none; |
|||
} |
|||
|
|||
.pos .pos-tare-label .caption { |
|||
display: block; |
|||
} |
|||
|
|||
.pos .pos-tare-paper { |
|||
margin: 0; |
|||
margin-left: 0 !important; |
|||
margin-right: 0 !important; |
|||
width: 99% !important; |
|||
height: 99% !important; |
|||
display: block; |
|||
position: fixed; |
|||
display: flex !important; |
|||
justify-content: center !important; |
|||
align-items: center !important; |
|||
} |
|||
|
|||
.pos-tare-label img { |
|||
width: 27mm !important; |
|||
height: 21mm !important; |
|||
display: run-in; |
|||
} |
|||
|
|||
.pos .pos-tare-label { |
|||
margin: 0; |
|||
margin-left: 0 !important; |
|||
margin-right: 0 !important; |
|||
position: fixed !important; |
|||
border: none !important; |
|||
font-size: 10px !important; |
|||
} |
|||
} |
@ -0,0 +1,359 @@ |
|||
odoo.define('pos_barcode_tare.screens', function (require) { |
|||
|
|||
"use strict"; |
|||
var chrome = require('point_of_sale.chrome'); |
|||
var core = require('web.core'); |
|||
var devices = require('point_of_sale.devices'); |
|||
var gui = require('point_of_sale.gui'); |
|||
var models = require('point_of_sale.models'); |
|||
var screens = require('point_of_sale.screens'); |
|||
var utils = require('web.utils'); |
|||
var formats = require('web.formats'); |
|||
|
|||
var QWeb = core.qweb; |
|||
var _t = core._t; |
|||
var round_pr = utils.round_precision; |
|||
var round_di = utils.round_decimals; |
|||
var tare_barcode_type = "tare"; |
|||
|
|||
// Define functions used to do unit operation.
|
|||
// Get unit search for unit based on unit name.
|
|||
var get_unit = function (pos, unit_name) { |
|||
return pos.units.filter( |
|||
function (u) { |
|||
return u.name === unit_name; |
|||
})[0]; |
|||
}; |
|||
|
|||
// Convert mass using the reference UOM as pivot unit.
|
|||
var convert_mass = function (mass, from_unit, to_unit) { |
|||
// There is no conversion from one category to another.
|
|||
if (from_unit.category_id[0] !== to_unit.category_id[0]) { |
|||
throw new Error(_.str.sprintf( |
|||
_t("We can not cast a weight in %s into %s."), |
|||
from_unit.name, to_unit.name)); |
|||
} |
|||
// No need to convert as weights are measured in same unit.
|
|||
if (from_unit.id === to_unit.id) { |
|||
return mass; |
|||
} |
|||
// Converts "from_unit" to reference unit of measure.
|
|||
var result = mass; |
|||
if (from_unit.uom_type === "bigger") { |
|||
result /= from_unit.factor; |
|||
} else { |
|||
result *= from_unit.factor_inv; |
|||
} |
|||
// Converts reference unit of measure to "to_unit".
|
|||
if (to_unit.uom_type === "bigger") { |
|||
result *= to_unit.factor; |
|||
} else { |
|||
result /= to_unit.factor_inv; |
|||
} |
|||
|
|||
if (to_unit.rounding) { |
|||
// Return the rounded result if needed.
|
|||
return round_pr(result || 0, to_unit.rounding); |
|||
} |
|||
|
|||
return result || 0; |
|||
}; |
|||
|
|||
// This configures read action for tare barcode. A tare barcode contains a
|
|||
// fake product ID and the weight to be subtracted from the product in the
|
|||
// latest order line.
|
|||
screens.ScreenWidget.include( |
|||
{ |
|||
barcode_tare_action: function (code) { |
|||
try { |
|||
var order = this.pos.get_order(); |
|||
var last_order_line = order.get_last_orderline(); |
|||
var tare_weight = code.value; |
|||
last_order_line.set_tare(tare_weight); |
|||
} catch (error) { |
|||
var title = _t("We can not apply this tare barcode."); |
|||
var popup = {title: title, body: error.message}; |
|||
this.gui.show_popup('error', popup); |
|||
} |
|||
}, |
|||
// Setup the callback action for the "weight" barcodes.
|
|||
show: function () { |
|||
this._super(); |
|||
this.pos.barcode_reader.set_action_callback( |
|||
'tare', |
|||
_.bind(this.barcode_tare_action, this)); |
|||
}, |
|||
}); |
|||
|
|||
// This create a new button on top of action widget. This button links to
|
|||
// the barcode label printing screen defined below.
|
|||
var TareScreenButton = screens.ActionButtonWidget.extend({ |
|||
template: 'TareScreenButton', |
|||
|
|||
button_click: function () { |
|||
this.gui.show_screen('tare'); |
|||
}, |
|||
}); |
|||
|
|||
screens.define_action_button({ |
|||
'name': 'tareScreenButton', |
|||
'widget': TareScreenButton, |
|||
}); |
|||
|
|||
// This is a new screen that reads weight from the electronic scale and
|
|||
// create a barcode label encoding the weight. The screen shows a preview
|
|||
// of the label. The user is expected to check if the preview matches what's
|
|||
// measured on the scale. The barcode image is generated by the report
|
|||
// module.
|
|||
var TareScreenWidget = screens.ScreenWidget.extend({ |
|||
template: 'TareScreenWidget', |
|||
next_screen: 'products', |
|||
previous_screen: 'products', |
|||
default_tare_value: 0.0, |
|||
weight_barcode_prefix: null, |
|||
|
|||
show: function () { |
|||
this._super(); |
|||
// Fetch the unit of measure used to save the tare
|
|||
this.kg_unit = get_unit(this.pos, "kg"); |
|||
// Fetch the barcode prefix from POS barcode parser rules.
|
|||
this.weight_barcode_prefix = this.get_barcode_prefix(); |
|||
// Setup the proxy
|
|||
var queue = this.pos.proxy_queue; |
|||
// The pooling of the scale starts here.
|
|||
var self = this; |
|||
queue.schedule(function () { |
|||
return self.pos.proxy.scale_read().then(function (weight) { |
|||
try { |
|||
self.set_weight(weight); |
|||
} catch (error) { |
|||
var title = _t("Failed to read weight from scale."); |
|||
var popup = {title: title, body: error.message}; |
|||
self.gui.show_popup('error', popup); |
|||
} |
|||
}); |
|||
}, {duration:150, repeat: true}); |
|||
// Shows a barcode whose weight might be zero, but this is preferred
|
|||
// for UI/UX reasons.
|
|||
this.render_receipt(); |
|||
this.lock_screen(true); |
|||
}, |
|||
get_barcode_prefix: function () { |
|||
var barcode_pattern = this.get_barcode_pattern(); |
|||
return barcode_pattern.substr(0, 2); |
|||
}, |
|||
get_barcode_pattern: function () { |
|||
var rules = this.get_barcode_rules(); |
|||
var rule = rules.filter( |
|||
function (r) { |
|||
// We select the first (smallest sequence ID) barcode rule
|
|||
// with the expected type.
|
|||
return r.type === tare_barcode_type; |
|||
})[0]; |
|||
return rule.pattern; |
|||
}, |
|||
get_barcode_rules: function () { |
|||
return this.pos.barcode_reader.barcode_parser.nomenclature.rules; |
|||
}, |
|||
set_weight: function (scale_measure) { |
|||
var weight = scale_measure.weight; |
|||
var unit = get_unit(this.pos, scale_measure.unit); |
|||
|
|||
if (typeof unit === 'undefined') { |
|||
throw new Error(_.str.sprintf( |
|||
_t("The scale sent a measure in %s unit. This unit of "+ |
|||
"measure (UOM) in not found in the point of sale. You " + |
|||
"may need to create a new UOM named %s. The UOM name is "+ |
|||
"case sensitive."), scale_measure.unit, |
|||
scale_measure.unit)); |
|||
} |
|||
|
|||
if (weight > 0) { |
|||
this.weight_in_kg = convert_mass(weight, unit, this.kg_unit); |
|||
this.render_receipt(); |
|||
this.lock_screen(false); |
|||
} |
|||
}, |
|||
get_weight: function () { |
|||
if (typeof this.weight_in_kg === 'undefined') { |
|||
return this.default_tare_value; |
|||
} |
|||
return this.weight_in_kg; |
|||
}, |
|||
barcode_data: function (weight) { |
|||
// We use EAN13 barcode, it looks like 07 00000 12345 x. First there
|
|||
// is the prefix, here 07, that is used to decide which type of
|
|||
// barcode we're dealing with. A weight barcode has then two groups
|
|||
// of five digits. The first group encodes the product id. Here the
|
|||
// product id is 00000. The second group encodes the weight in
|
|||
// grams. Here the weight is 12.345kg. The last digit of the barcode
|
|||
// is a checksum, here symbolized by x.
|
|||
var padding_size = 5; |
|||
var void_product_id = '0'.repeat(padding_size); |
|||
var weight_in_gram = weight * 1e3; |
|||
|
|||
if (weight_in_gram >= Math.pow(10, padding_size)) { |
|||
throw new RangeError(_t("Maximum tare weight is 99.999kg")); |
|||
} |
|||
|
|||
// Weight has to be padded with zeros.
|
|||
var weight_with_padding = '0'.repeat(padding_size) + weight_in_gram; |
|||
var padded_weight = weight_with_padding.substr( |
|||
weight_with_padding.length - padding_size); |
|||
// Builds the barcode using a placeholder checksum.
|
|||
var barcode = this.weight_barcode_prefix |
|||
.concat(void_product_id, padded_weight) |
|||
.concat(0); |
|||
// Compute checksum
|
|||
var barcode_parser = this.pos.barcode_reader.barcode_parser; |
|||
var checksum = barcode_parser.ean_checksum(barcode); |
|||
// Replace checksum placeholder by the actual checksum.
|
|||
return barcode.substr(0, 12).concat(checksum); |
|||
}, |
|||
get_barcode_data: function () { |
|||
return this.barcode_data(this.get_weight()); |
|||
}, |
|||
lock_screen: function (locked) { |
|||
this._locked = locked; |
|||
if (locked) { |
|||
this.$('.print-label').addClass('disabled'); |
|||
} else { |
|||
this.$('.print-label').removeClass('disabled'); |
|||
} |
|||
}, |
|||
print_web: function () { |
|||
window.print(); |
|||
this.pos.get_order()._printed = true; |
|||
}, |
|||
print: function () { |
|||
// See comment in print function of ReceiptScreenWidget
|
|||
this.lock_screen(true); |
|||
var self = this; |
|||
setTimeout(function () { |
|||
self.lock_screen(false); |
|||
}, 1000); |
|||
|
|||
this.print_web(); |
|||
this.click_back(); |
|||
}, |
|||
click_back: function () { |
|||
this.close(); |
|||
this.gui.show_screen(this.previous_screen); |
|||
}, |
|||
renderElement: function () { |
|||
this._super(); |
|||
var self = this; |
|||
this.$('.back').click(function () { |
|||
self.click_back(); |
|||
}); |
|||
this.$('.print-label').click(function () { |
|||
if (!self._locked) { |
|||
self.print(); |
|||
} |
|||
}); |
|||
}, |
|||
render_receipt: function () { |
|||
this.$('.pos-tare-label-container').html( |
|||
QWeb.render('PosTareLabel', {widget:this})); |
|||
}, |
|||
close: function () { |
|||
this._super(); |
|||
delete this.weight; |
|||
this.pos.proxy_queue.clear(); |
|||
}, |
|||
}); |
|||
|
|||
gui.define_screen({name:'tare', widget: TareScreenWidget}); |
|||
|
|||
// Update Orderline model
|
|||
var _super_ = models.Orderline.prototype; |
|||
|
|||
models.Orderline = models.Orderline.extend({ |
|||
initialize: function (session, attributes) { |
|||
this.tareQuantity = 0; |
|||
this.tareQuantityStr = '0'; |
|||
return _super_.initialize.call(this, session, attributes); |
|||
}, |
|||
init_from_JSON: function (json) { |
|||
_super_.init_from_JSON.call(this, json); |
|||
this.tareQuantity = json.tareQuantity ||0; |
|||
this.tareQuantityStr = json.tareQuantityStr ||'0'; |
|||
}, |
|||
set_tare: function (quantity) { |
|||
this.order.assert_editable(); |
|||
|
|||
// Prevent to apply multiple times a tare to the same product.
|
|||
if (this.get_tare() > 0) { |
|||
throw new RangeError(_.str.sprintf( |
|||
_t("The tare (%s) is already set for the " + |
|||
"product \"%s\". We can not re-apply a tare to this " + |
|||
"product."), |
|||
this.get_tare_str_with_unit(), this.product.display_name)); |
|||
} |
|||
|
|||
var self = this; |
|||
// This function is used to format the quantity into string
|
|||
// according to the rounding specifications.
|
|||
var stringify = function (qty) { |
|||
var unit = self.get_unit(); |
|||
if (unit.rounding) { |
|||
var q = round_pr(qty, unit.rounding); |
|||
var decimals = self.pos.dp['Product Unit of Measure']; |
|||
return formats.format_value( |
|||
round_di(q, decimals), |
|||
{type: 'float', digits: [69, decimals]}); |
|||
} |
|||
return qty.toFixed(0); |
|||
}; |
|||
// We convert the tare that is always measured in kilogrammes into
|
|||
// the unit of measure for this order line.
|
|||
var kg = get_unit(this.pos, "kg"); |
|||
var tare = parseFloat(quantity) || 0; |
|||
var unit = this.get_unit(); |
|||
var tare_in_product_uom = convert_mass(tare, kg, unit); |
|||
var tare_in_product_uom_string = stringify(tare_in_product_uom); |
|||
var net_quantity = this.get_quantity() - tare_in_product_uom; |
|||
// This method fails when the net weight is negative.
|
|||
if (net_quantity <= 0) { |
|||
throw new RangeError(_.str.sprintf( |
|||
_t("The tare weight is %s %s, it's greater or equal to " + |
|||
"the product weight %s. We can not apply this tare."), |
|||
tare_in_product_uom_string, unit.name, |
|||
this.get_quantity_str_with_unit())); |
|||
} |
|||
// Update tare value.
|
|||
this.tareQuantity = tare_in_product_uom; |
|||
this.tareQuantityStr = tare_in_product_uom_string; |
|||
// Update the quantity with the new weight net of tare quantity.
|
|||
this.set_quantity(net_quantity); |
|||
this.trigger('change', this); |
|||
}, |
|||
get_tare: function () { |
|||
return this.tareQuantity; |
|||
}, |
|||
get_tare_str: function () { |
|||
return this.tareQuantityStr; |
|||
}, |
|||
get_tare_str_with_unit: function () { |
|||
var unit = this.get_unit(); |
|||
return this.tareQuantityStr + ' ' + unit.name; |
|||
}, |
|||
export_as_JSON: function () { |
|||
var json = _super_.export_as_JSON.call(this); |
|||
json.tareQuantity = this.get_tare(); |
|||
json.tareQuantityStr = this.get_tare_str(); |
|||
return json; |
|||
}, |
|||
clone: function () { |
|||
var orderline = _super_.clone.call(this); |
|||
orderline.tareQuantity = this.tareQuantity; |
|||
orderline.tareQuantityStr = this.tareQuantityStr; |
|||
return orderline; |
|||
}, |
|||
export_for_printing: function () { |
|||
var result = _super_.export_for_printing.call(this); |
|||
result.tare_quantity = this.get_tare(); |
|||
return result; |
|||
}, |
|||
}); |
|||
}); |
@ -0,0 +1,86 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<templates id="template" xml:space="preserve"> |
|||
<t t-name="TareScreenWidget"> |
|||
<div class='tare-screen screen'> |
|||
<div class='screen-content'> |
|||
<div class='top-content'> |
|||
<span class='button back'> |
|||
<i class='fa fa-angle-double-left'></i> |
|||
Back |
|||
</span> |
|||
<h1>Print a tare label</h1> |
|||
</div> |
|||
<div class="centered-content"> |
|||
<div class="pos-tare-label-container"></div> |
|||
<div class="pos-directions-for-user"> |
|||
Set the pot on the scale and check the weight above |
|||
</div> |
|||
<div class='print-label'> |
|||
Print |
|||
<i class='fa fa-angle-double-right'></i> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
|
|||
<t t-name="PosTareLabel"> |
|||
<div class="pos-center-align"> |
|||
<div class="pos-tare-paper"> |
|||
<div class="pos-tare-label"> |
|||
<img t-att-src="'/report/barcode/EAN13/' + widget.get_barcode_data()" /> |
|||
<span class="caption">tare = <t t-esc="widget.get_weight()" />kg</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
|
|||
<t t-name="TareScreenButton"> |
|||
<t t-if="widget.pos.config.iface_tare_label"> |
|||
<span class="control-button"> |
|||
<i class="fa fa-print"></i> |
|||
Print a tare label |
|||
</span> |
|||
</t> |
|||
</t> |
|||
|
|||
<t t-name="Orderline"> |
|||
<li t-attf-class="orderline #{ line.selected ? 'selected' : '' }"> |
|||
<span class="product-name"> |
|||
<t t-esc="line.get_product().display_name"/> |
|||
</span> |
|||
<span class="price"> |
|||
<t t-esc="widget.format_currency(line.get_display_price())"/> |
|||
</span> |
|||
<ul class="info-list"> |
|||
<t t-if="line.get_quantity_str() !== '1' || line.selected "> |
|||
<li class="info"> |
|||
<em> |
|||
<t t-esc="line.get_quantity_str()" /> |
|||
</em> |
|||
<t t-esc="line.get_unit().name" /> |
|||
at |
|||
<t t-esc="widget.format_currency(line.get_unit_display_price(),'Product Price')" /> |
|||
/ |
|||
<t t-esc="line.get_unit().name" /> |
|||
</li> |
|||
</t> |
|||
<t t-if="line.get_discount_str() !== '0'"> |
|||
<li class="info"> |
|||
With a |
|||
<em> |
|||
<t t-esc="line.get_discount_str()" />% |
|||
</em> |
|||
discount |
|||
</li> |
|||
</t> |
|||
<t t-if="line.get_tare_str() !== '0'"> |
|||
<li class="info"> |
|||
tare = <t t-esc="line.get_tare_str_with_unit()" /> |
|||
</li> |
|||
</t> |
|||
</ul> |
|||
</li> |
|||
</t> |
|||
|
|||
</templates> |
@ -0,0 +1,16 @@ |
|||
<?xml version="1.0"?> |
|||
|
|||
<odoo> |
|||
<record model="ir.ui.view" id="view_pos_config_form"> |
|||
<field name="model">pos.config</field> |
|||
<field name="inherit_id" ref="point_of_sale.view_pos_config_form" /> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="/form/sheet/group[@name='features']" position="inside"> |
|||
<separator string="Loose good options" colspan="4"/> |
|||
<group> |
|||
<field name="iface_tare_label" /> |
|||
</group> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |