diff --git a/pos_tare/README.rst b/pos_tare/README.rst new file mode 100644 index 00000000..a2abecdf --- /dev/null +++ b/pos_tare/README.rst @@ -0,0 +1,109 @@ +==================== +Point Of Sale - Tare +==================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github + :target: https://github.com/OCA/pos/tree/12.0/pos_tare + :alt: OCA/pos +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_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/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Give the possibility to the user to enter a Tare weight, when weighting +products in the Point of Sale. +This will compute automatically net weight and set it to the current +selected order + +.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_tare/static/description/pos_tare.png + +The net weight is displayed in the order with the tare value below. + +.. figure:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_tare/static/description/order.png + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Install this add-on and configure your point of sale. To enable this addon, go to your point of sale configuration page. There, enable the electronic scale and barcode reader in the "IoT Box" section. In the same page, look up for the "Tare input method" field, and choose a tare method. There are three tare methods: +- "manual", you'll set the tare value when you weight the product; +- "barcode", you'll scan the tare value from a barcode; +- "both", you can both of the above. + +To generate a tare barcode you need to use the default barcode nomenclature. The default barcode pattern is `0700000{NNDDD}`. Using that pattern, the barcode for a tare of 0.1kg is `0700000001006`. The `pos_tare_barcode_generator` allows you to create tare labels right from the POS. + +Known issues / Roadmap +====================== + +- Print tare value on customer receipt. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* GRAP +* Le Nid + +Contributors +~~~~~~~~~~~~ + +- Sylvain LE GAL (https://www.twitter.com/legalsylvain) +- Le Nid +- 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. + +.. |maintainer-fkawala| image:: https://github.com/fkawala.png?size=40px + :target: https://github.com/fkawala + :alt: fkawala + +Current `maintainer `__: + +|maintainer-fkawala| + +This module is part of the `OCA/pos `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_tare/__init__.py b/pos_tare/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/pos_tare/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/pos_tare/__manifest__.py b/pos_tare/__manifest__.py new file mode 100644 index 00000000..e5dffebb --- /dev/null +++ b/pos_tare/__manifest__.py @@ -0,0 +1,25 @@ +# @author: François Kawala +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Point Of Sale - Tare", + "summary": "Manage Tare in Point Of Sale module", + "version": "12.0.1.0.0", + "category": "Point of Sale", + "author": "GRAP, Le Nid, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/pos", + "license": "AGPL-3", + "maintainers": ["fkawala", "legalsylvain"], + "depends": [ + "point_of_sale", + ], + "data": [ + "views/templates.xml", + "views/view_pos_config.xml", + "views/view_pos_order.xml", + "data/barcode_rule.xml", + ], + "qweb": [ + "static/src/xml/pos_tare.xml", + ], + "installable": True, +} diff --git a/pos_tare/data/barcode_rule.xml b/pos_tare/data/barcode_rule.xml new file mode 100644 index 00000000..a8ecb861 --- /dev/null +++ b/pos_tare/data/barcode_rule.xml @@ -0,0 +1,12 @@ + + + + + Tare + + 81 + tare + ean13 + 0700000{NNDDD} + + diff --git a/pos_tare/models/__init__.py b/pos_tare/models/__init__.py new file mode 100644 index 00000000..c6acc897 --- /dev/null +++ b/pos_tare/models/__init__.py @@ -0,0 +1,3 @@ +from . import pos_config +from . import pos_order_line +from . import barcode_rule diff --git a/pos_tare/models/barcode_rule.py b/pos_tare/models/barcode_rule.py new file mode 100644 index 00000000..f48c1147 --- /dev/null +++ b/pos_tare/models/barcode_rule.py @@ -0,0 +1,9 @@ +from odoo import models, fields + + +class BarcodeRule(models.Model): + _inherit = 'barcode.rule' + + type = fields.Selection(selection_add=[ + ('tare', 'Tare') + ]) diff --git a/pos_tare/models/pos_config.py b/pos_tare/models/pos_config.py new file mode 100644 index 00000000..8a53ef75 --- /dev/null +++ b/pos_tare/models/pos_config.py @@ -0,0 +1,41 @@ +from odoo import api, models, fields + + +class PosConfig(models.Model): + _inherit = "pos.config" + + iface_tare_method = fields.Selection( + [ + ("manual", "Input the tare manually"), + ("barcode", "Scan a barcode to set the tare"), + ("both", "Manual input and barcode"), + ], + string="Tare Input Method", + default="both", + required=True, + help="Select tare method:\n" + "* 'manual' : the scale screen has an extra tare input field;\n" + "* 'barecode' : (scan a barcode to tare the selected order line;\n" + "* 'both' : manual input and barcode methods are enabled;", + ) + + iface_gross_weight_method = fields.Selection( + [ + ("manual", "Input the Gross Weight manually"), + ("scale", "Input Gross Weight via Scale") + ], + string="Gross Weight Input Method", + default="scale", + required=True, + ) + + iface_tare_uom_id = fields.Many2one( + string="Unit of Measure of the tare", + comodel_name="uom.uom", + default=lambda s: s._default_iface_tare_uom_id(), + required=True, + ) + + @api.model + def _default_iface_tare_uom_id(self): + return self.env.ref("uom.product_uom_kgm") diff --git a/pos_tare/models/pos_order_line.py b/pos_tare/models/pos_order_line.py new file mode 100644 index 00000000..c86e6260 --- /dev/null +++ b/pos_tare/models/pos_order_line.py @@ -0,0 +1,15 @@ +# Copyright (C) 2020-Today: GRAP () +# @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, fields +from odoo.addons import decimal_precision as dp + + +class PosOrderLine(models.Model): + _inherit = "pos.order.line" + + tare = fields.Float( + string="Tare", + digits=dp.get_precision("Product Unit of Measure") + ) diff --git a/pos_tare/readme/CONTRIBUTORS.rst b/pos_tare/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..1434c95d --- /dev/null +++ b/pos_tare/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +- Sylvain LE GAL (https://www.twitter.com/legalsylvain) +- Le Nid +- CoopITEasy diff --git a/pos_tare/readme/DESCRIPTION.rst b/pos_tare/readme/DESCRIPTION.rst new file mode 100644 index 00000000..a21b3b7a --- /dev/null +++ b/pos_tare/readme/DESCRIPTION.rst @@ -0,0 +1,10 @@ +Give the possibility to the user to enter a Tare weight, when weighting +products in the Point of Sale. +This will compute automatically net weight and set it to the current +selected order + +.. figure:: ../static/description/pos_tare.png + +The net weight is displayed in the order with the tare value below. + +.. figure:: ../static/description/order.png diff --git a/pos_tare/readme/USAGE.rst b/pos_tare/readme/USAGE.rst new file mode 100644 index 00000000..b4393402 --- /dev/null +++ b/pos_tare/readme/USAGE.rst @@ -0,0 +1,6 @@ +Install this add-on and configure your point of sale. To enable this addon, go to your point of sale configuration page. There, enable the electronic scale and barcode reader in the "IoT Box" section. In the same page, look up for the "Tare input method" field, and choose a tare method. There are three tare methods: +- "manual", you'll set the tare value when you weight the product; +- "barcode", you'll scan the tare value from a barcode; +- "both", you can both of the above. + +To generate a tare barcode you need to use the default barcode nomenclature. The default barcode pattern is `0700000{NNDDD}`. Using that pattern, the barcode for a tare of 0.1kg is `0700000001006`. The `pos_tare_barcode_generator` allows you to create tare labels right from the POS. diff --git a/pos_tare/static/description/icon.png b/pos_tare/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/pos_tare/static/description/icon.png differ diff --git a/pos_tare/static/description/index.html b/pos_tare/static/description/index.html new file mode 100644 index 00000000..8e61f33a --- /dev/null +++ b/pos_tare/static/description/index.html @@ -0,0 +1,450 @@ + + + + + + +Point Of Sale - Tare + + + +
+

Point Of Sale - Tare

+ + +

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

+

Give the possibility to the user to enter a Tare weight, when weighting +products in the Point of Sale. +This will compute automatically net weight and set it to the current +selected order

+
+https://raw.githubusercontent.com/OCA/pos/12.0/pos_tare/static/description/pos_tare.png +
+

The net weight is displayed in the order with the tare value below.

+
+https://raw.githubusercontent.com/OCA/pos/12.0/pos_tare/static/description/order.png +
+

Table of contents

+ +
+

Usage

+

Install this add-on and configure your point of sale. To enable this addon, go to your point of sale configuration page. There, enable the electronic scale and barcode reader in the “IoT Box” section. In the same page, look up for the “Tare input method” field, and choose a tare method. There are three tare methods: +- “manual”, you’ll set the tare value when you weight the product; +- “barcode”, you’ll scan the tare value from a barcode; +- “both”, you can both of the above.

+

To generate a tare barcode you need to use the default barcode nomenclature. The default barcode pattern is 0700000{NNDDD}. Using that pattern, the barcode for a tare of 0.1kg is 0700000001006. The pos_tare_barcode_generator allows you to create tare labels right from the POS.

+
+
+

Known issues / Roadmap

+
    +
  • Print tare value on customer receipt.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • GRAP
  • +
  • Le Nid
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

Current maintainer:

+

fkawala

+

This module is part of the OCA/pos project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/pos_tare/static/description/order.png b/pos_tare/static/description/order.png new file mode 100644 index 00000000..9a7c035e Binary files /dev/null and b/pos_tare/static/description/order.png differ diff --git a/pos_tare/static/description/pos_tare.png b/pos_tare/static/description/pos_tare.png new file mode 100644 index 00000000..2738e6f0 Binary files /dev/null and b/pos_tare/static/description/pos_tare.png differ diff --git a/pos_tare/static/description/pos_ticket.png b/pos_tare/static/description/pos_ticket.png new file mode 100644 index 00000000..bf753d40 Binary files /dev/null and b/pos_tare/static/description/pos_ticket.png differ diff --git a/pos_tare/static/src/css/pos_tare.css b/pos_tare/static/src/css/pos_tare.css new file mode 100644 index 00000000..6d746d98 --- /dev/null +++ b/pos_tare/static/src/css/pos_tare.css @@ -0,0 +1,71 @@ +/*************************************************************** +Overloading existing PoS objects +****************************************************************/ + +/*Change the design of the numpad in the product-screen*/ +.pos .product-screen .actionpad .button.pay { + height: 216px; +} + +.pos .product-screen .numpad button.input-button.numpad-backspace { + width: 216px; +} + +/*Fix the receipt in the non proxy mode as the order lines can now +content multiple lines*/ +.pos .pos-right-align{ + vertical-align: top; +} + +/*************************************************************** +New style for new scale objects +****************************************************************/ + +.pos .scale-screen .weight-label { + font-size: 25px; + margin: 16px; + text-align: center; + display: inline-block; + width: 40%; + margin-bottom: 0px; +} + +.pos .scale-screen .weight-value { + font-size: 25px; + display: inline-block; + margin: 16px; + margin-top: 0px; + padding: 16px; + width: 40%; + font-family: Inconsolata; + font-weight: bold; + text-shadow: 0px 2px 0px rgb(210,210,210); + margin-bottom: 0px; +} + +.pos .scale-screen .weight-value-fixed { + border-radius: 3px; + box-shadow: 0px 2px 0px rgb(225,225,225) inset; + text-align: right; + background: white; +} + +.pos .scale-screen .weight-value-alterable { + text-align: left; + padding-bottom: 0px; + padding-left: 0px; +} +.pos .scale-screen .input-weight { + border: 1px solid #cecbcb; + border-radius: 20px; + padding: 15px 20px; + width: 50%; + font-family: Inconsolata; + font-weight: bold; + font-size: 25px; +} + +.pos .scale-screen .input-weight:focus { + outline: none; + box-shadow: 0px 0px 0px 3px #6EC89B; +} diff --git a/pos_tare/static/src/js/models.js b/pos_tare/static/src/js/models.js new file mode 100644 index 00000000..923ec878 --- /dev/null +++ b/pos_tare/static/src/js/models.js @@ -0,0 +1,116 @@ +odoo.define('pos_tare.models', function (require) { + + "use strict"; + var core = require('web.core'); + var models = require('point_of_sale.models'); + var pos_tare_tools = require('pos_tare.tools'); + var _t = core._t; + + var _super_ = models.Orderline.prototype; + var OrderLineWithTare = models.Orderline.extend({ + + // ///////////////////////////// + // Overload Section + // ///////////////////////////// + initialize: function (session, attributes) { + this.tare = 0; + return _super_.initialize.call(this, session, attributes); + }, + + init_from_JSON: function (json) { + _super_.init_from_JSON.call(this, json); + this.tare = json.tare ||0; + }, + + clone: function () { + var orderline = _super_.clone.call(this); + orderline.tare = this.tare; + return orderline; + }, + + export_as_JSON: function () { + var json = _super_.export_as_JSON.call(this); + json.tare = this.get_tare(); + return json; + }, + + export_for_printing: function () { + var result = _super_.export_for_printing.call(this); + result.tare_quantity = this.get_tare(); + result.gross_quantity = this.get_gross_weight(); + return result; + }, + + // ///////////////////////////// + // Custom Section + // ///////////////////////////// + + set_tare: function (quantity, update_net_weight) { + this.order.assert_editable(); + + // Prevent to apply multiple times a tare to the same product. + + if (this.get_tare() > 0) { + // This is valid because the tare is stored using product UOM. + this.set_quantity(this.get_quantity() + this.get_tare()); + this.reset_tare(); + } + + // We convert the tare that is always measured in the same UoM into + // the unit of measure for this order line. + var tare_uom = this.pos.config.iface_tare_uom_id[0]; + var tare_unit = this.pos.units_by_id[tare_uom]; + var tare = parseFloat(quantity) || 0; + var line_unit = this.get_unit(); + var tare_in_product_uom = pos_tare_tools.convert_mass( + tare, tare_unit, line_unit); + var tare_in_product_uom_string = pos_tare_tools.format_tare( + this.pos, tare_in_product_uom, line_unit); + if (update_net_weight) { + var net_quantity = this.get_quantity() - tare_in_product_uom; + // Update the quantity with the new weight net of tare quantity. + this.set_quantity(net_quantity); + } + // Update tare value. + this.tare = tare_in_product_uom; + this.trigger('change', this); + + }, + + reset_tare: function () { + this.tare = 0; + }, + + get_tare: function () { + return this.tare; + }, + + get_gross_weight: function () { + return this.get_tare() + this.get_quantity(); + }, + + get_tare_str_with_unit: function () { + var unit = this.get_unit(); + var tare_str = pos_tare_tools.format_tare( + this.pos, + this.tare, + this.get_unit() + ); + return tare_str + ' ' + unit.name; + }, + + get_gross_weight_str_with_unit: function () { + var unit = this.get_unit(); + var gross_weight_str = pos_tare_tools.format_tare( + this.pos, + this.get_gross_weight(), + this.get_unit() + ); + return gross_weight_str + ' ' + unit.name; + }, + + }); + + models.Orderline = OrderLineWithTare; + +}); diff --git a/pos_tare/static/src/js/screens.js b/pos_tare/static/src/js/screens.js new file mode 100644 index 00000000..ff7a4ed6 --- /dev/null +++ b/pos_tare/static/src/js/screens.js @@ -0,0 +1,201 @@ +odoo.define('pos_tare.screens', function (require) { + + "use strict"; + var core = require('web.core'); + var screens = require('point_of_sale.screens'); + var utils = require('web.utils'); + + var _t = core._t; + var round_pr = utils.round_precision; + var leq_zero_qty = (ol) => ol.get_quantity() <= 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 selected_order_line = order.get_selected_orderline(); + var tare_weight = code.value; + selected_order_line.set_tare(tare_weight, true); + } 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(); + if (this.pos.config.iface_tare_method !== 'manual') { + this.pos.barcode_reader.set_action_callback( + 'tare', + _.bind(this.barcode_tare_action, this)); + } + }, + }); + + screens.ScaleScreenWidget.include({ + + // ///////////////////////////// + // Overload Section + // ///////////////////////////// + + show: function () { + this.tare = 0.0; + this.gross_weight = 0.0; + this._super(); + var self = this; + this.$('#input_weight_tare').keyup(function (event) { + self.onchange_tare(event); + }); + this.$('#input_gross_weight').keyup(function (event) { + self.onchange_gross_weight(event); + }); + if (this.pos.config.iface_gross_weight_method === 'scale') { + this.$('#input_weight_tare').focus(); + } else { + this.pos.proxy_queue.clear(); + this.$('#input_gross_weight').focus(); + } + }, + + // Overload set_weight function + // We assume that the argument is now the gross weight + // we compute the net weight, depending on the tare and the gross weight + // then we call super, with the net weight + set_weight: function (gross_weight) { + this.gross_weight = gross_weight; + var net_weight = gross_weight - (this.tare || 0); + this.$('#container_weight_gross').text( + this.get_product_gross_weight_string()); + this._super(net_weight); + }, + + order_product: function () { + if (this.tare === undefined) { + this.gui.show_popup('error', { + 'title': _t('Incorrect Tare Value'), + 'body': _t('Please set a numeric value' + + ' in the tare field, or let empty.'), + }); + } else { + this._super(); + if (this.tare > 0.0) { + var order = this.pos.get_order(); + var orderline = order.get_last_orderline(); + orderline.set_tare(this.tare, false); + } + } + }, + + // ///////////////////////////// + // Custom Section + // ///////////////////////////// + get_product_gross_weight_string: function () { + var product = this.get_product(); + var defaultstr = (this.gross_weight || 0).toFixed(3) + ' Kg'; + if (!product || !this.pos) { + return defaultstr; + } + var unit_id = product.uom_id; + if (!unit_id) { + return defaultstr; + } + var unit = this.pos.units_by_id[unit_id[0]]; + var weight = round_pr(this.gross_weight || 0, unit.rounding); + var weightstr = weight.toFixed( + Math.ceil(Math.log(1.0/unit.rounding) / Math.log(10) )); + weightstr += ' ' + unit.name; + return weightstr; + }, + + onchange_tare: function () { + this.tare = this.check_sanitize_value('#input_weight_tare'); + this.set_weight(this.gross_weight); + }, + + onchange_gross_weight: function () { + var gross_weight = this.check_sanitize_value('#input_gross_weight'); + this.set_weight(gross_weight); + }, + + check_sanitize_value: function (input_name) { + var res = this.$(input_name)[0].value.replace(',', '.').trim(); + if (isNaN(res)) { + this.$(input_name).css("background-color", "#F66"); + return undefined; + } + this.$(input_name).css("background-color", "#FFF"); + return parseFloat(res, 10); + }, + + }); + + screens.PaymentScreenWidget.include({ + validate_order: function(options) { + var order = this.pos.get_order(); + var orderlines = Array.from(order.get_orderlines()); + + if (orderlines.some(leq_zero_qty)) { + var _super_validate_order = this._super.bind(this); + var wrong_orderline = orderlines.find(leq_zero_qty); + var wrong_product = wrong_orderline.get_product().display_name; + this.gui.show_popup('confirm', { + title: _t('Quantity lower or equal to zero'), + body: _.str.sprintf( + _t("The quantity for \"%s\" is lower or equal to" + + " zero. Call for help unless you're perfectly" + + " sure you are doing right."), wrong_product), + confirm: function() { + _super_validate_order(); + }, + }); + return; + } + return this._super(options); + }, + }); + + screens.OrderWidget.include({ + set_value: function (val) { + var order = this.pos.get_order(); + if (order.get_selected_orderline()) { + var mode = this.numpad_state.get('mode'); + if (mode === 'quantity') { + var orderline = order.get_selected_orderline(); + var tare = orderline.get_tare(); + orderline.reset_tare(); + orderline.set_quantity(val); + if (tare > 0) { + orderline.set_tare(tare, true); + } + } else if (mode === 'discount') { + order.get_selected_orderline().set_discount(val); + } else if (mode === 'price') { + var selected_orderline = order.get_selected_orderline(); + selected_orderline.price_manually_set = true; + selected_orderline.set_unit_price(val); + } else if (mode === 'tare') { + if (this.pos.config.iface_tare_method === 'barcode') { + this.gui.show_popup('error', + {'title': _t('Incorrect Tare Value'), + 'body': _t('You can not set the tare.' + + ' To be able to set the tare manually' + + ' you have to change the tare input method' + + ' in the POS configuration.')}); + } else { + try { + order.get_selected_orderline().set_tare(val, true); + } catch (error) { + var title = _t("We can not apply this tare."); + var popup = {title: title, body: error.message}; + this.gui.show_popup('error', popup); + } + } + } + } + }, + }); +}); diff --git a/pos_tare/static/src/js/tools.js b/pos_tare/static/src/js/tools.js new file mode 100644 index 00000000..e1c349d9 --- /dev/null +++ b/pos_tare/static/src/js/tools.js @@ -0,0 +1,62 @@ +odoo.define('pos_tare.tools', function (require) { + + "use strict"; + var core = require('web.core'); + var utils = require('web.utils'); + var field_utils = require('web.field_utils'); + + var _t = core._t; + var round_pr = utils.round_precision; + var round_di = utils.round_decimals; + + // 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; + }; + + // Format the tare value. + var format_tare = function (pos, qty, unit) { + if (unit.rounding) { + var q = round_pr(qty, unit.rounding); + var decimals = pos.dp['Product Unit of Measure']; + return field_utils.format.float( + round_di(q, decimals), + {type: 'float', digits: [69, decimals]}); + } + return qty.toFixed(0); + }; + + return { + convert_mass: convert_mass, + format_tare: format_tare, + }; +}); diff --git a/pos_tare/static/src/xml/pos_tare.xml b/pos_tare/static/src/xml/pos_tare.xml new file mode 100644 index 00000000..d3115123 --- /dev/null +++ b/pos_tare/static/src/xml/pos_tare.xml @@ -0,0 +1,107 @@ + + + + + + +
+ Gross Weight +
+ +
+ + +
+ + +
+
+
+ Tare +
+
+ + +
+ + + + + + + +
  • + + (Gross Weight: + + - Tare: + ) + +
  • +
    +
    +
    + + + + +
    + Gross Weight : +
    + Tare : +
    +
    +
    +
    +
    + + + + + + + ( + + + - + + + + ) + + + + + + + +
    + + + + + +
    + + + + + +
    + + + + + +
    + + + + + + +
    +
    + diff --git a/pos_tare/views/templates.xml b/pos_tare/views/templates.xml new file mode 100644 index 00000000..a8e0bc73 --- /dev/null +++ b/pos_tare/views/templates.xml @@ -0,0 +1,10 @@ + + + diff --git a/pos_tare/views/view_pos_config.xml b/pos_tare/views/view_pos_config.xml new file mode 100644 index 00000000..11ca9424 --- /dev/null +++ b/pos_tare/views/view_pos_config.xml @@ -0,0 +1,54 @@ + + + + + + + pos.config + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    diff --git a/pos_tare/views/view_pos_order.xml b/pos_tare/views/view_pos_order.xml new file mode 100644 index 00000000..7df2e933 --- /dev/null +++ b/pos_tare/views/view_pos_order.xml @@ -0,0 +1,16 @@ + + + + + + + pos.order + + + + + + + + +