From 325ae220d88ca368db5d51cd46e838d63e801bca Mon Sep 17 00:00:00 2001 From: Benoit Aimont Date: Fri, 7 Apr 2023 14:25:48 +0200 Subject: [PATCH] [MIG] pos_tare: Migration to 14.0 --- pos_tare/__manifest__.py | 7 +- pos_tare/models/barcode_rule.py | 4 +- pos_tare/models/pos_order_line.py | 5 +- pos_tare/models/product_template.py | 4 +- .../js/Screens/ProductScreen/ProductScreen.js | 167 ++++++++++++++ .../src/js/Screens/ScaleScreen/ScaleScreen.js | 52 +++++ pos_tare/static/src/js/db.js | 13 -- pos_tare/static/src/js/models.js | 23 +- pos_tare/static/src/js/screens.js | 211 ------------------ .../Screens/ProductScreen/NumpadWidget.xml | 23 ++ .../xml/Screens/ProductScreen/Orderline.xml | 24 ++ .../Screens/ReceiptScreen/OrderReceipt.xml | 22 ++ .../xml/Screens/ScaleScreen/ScaleScreen.xml | 54 +++++ pos_tare/static/src/xml/pos_tare.xml | 132 ----------- pos_tare/views/templates.xml | 10 +- 15 files changed, 376 insertions(+), 375 deletions(-) create mode 100644 pos_tare/static/src/js/Screens/ProductScreen/ProductScreen.js create mode 100644 pos_tare/static/src/js/Screens/ScaleScreen/ScaleScreen.js delete mode 100644 pos_tare/static/src/js/db.js delete mode 100644 pos_tare/static/src/js/screens.js create mode 100644 pos_tare/static/src/xml/Screens/ProductScreen/NumpadWidget.xml create mode 100644 pos_tare/static/src/xml/Screens/ProductScreen/Orderline.xml create mode 100644 pos_tare/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml create mode 100644 pos_tare/static/src/xml/Screens/ScaleScreen/ScaleScreen.xml delete mode 100644 pos_tare/static/src/xml/pos_tare.xml diff --git a/pos_tare/__manifest__.py b/pos_tare/__manifest__.py index 890d7fff21..05465795b9 100644 --- a/pos_tare/__manifest__.py +++ b/pos_tare/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Point Of Sale - Tare", "summary": "Manage Tare in Point Of Sale module", - "version": "12.0.1.0.3", + "version": "14.0.1.0.0", "category": "Point of Sale", "author": "GRAP, Le Nid, Odoo Community Association (OCA)", "website": "https://github.com/OCA/pos", @@ -20,7 +20,10 @@ "data/barcode_rule.xml", ], "qweb": [ - "static/src/xml/pos_tare.xml", + "static/src/xml/Screens/ProductScreen/Orderline.xml", + "static/src/xml/Screens/ProductScreen/NumpadWidget.xml", + "static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml", + "static/src/xml/Screens/ScaleScreen/ScaleScreen.xml", ], "demo": [ "demo/product_product.xml", diff --git a/pos_tare/models/barcode_rule.py b/pos_tare/models/barcode_rule.py index 92b661e3af..c3d332fcf2 100644 --- a/pos_tare/models/barcode_rule.py +++ b/pos_tare/models/barcode_rule.py @@ -4,4 +4,6 @@ class BarcodeRule(models.Model): _inherit = "barcode.rule" - type = fields.Selection(selection_add=[("tare", "Tare")]) + type = fields.Selection( + selection_add=[("tare", "Tare")], ondelete={"tare": "set default"} + ) diff --git a/pos_tare/models/pos_order_line.py b/pos_tare/models/pos_order_line.py index 0e423d8234..8289081bb9 100644 --- a/pos_tare/models/pos_order_line.py +++ b/pos_tare/models/pos_order_line.py @@ -4,12 +4,11 @@ from odoo import fields, models -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") + string="Tare", + digits="Product Unit of Measure", ) diff --git a/pos_tare/models/product_template.py b/pos_tare/models/product_template.py index c1d8a39c77..1086bb4da6 100644 --- a/pos_tare/models/product_template.py +++ b/pos_tare/models/product_template.py @@ -4,14 +4,12 @@ from odoo import fields, models -import odoo.addons.decimal_precision as dp - class ProductTemplate(models.Model): _inherit = "product.template" tare_weight = fields.Float( - digits=dp.get_precision("Product Unit of Measure"), + digits="Product Unit of Measure", string="Tare Weight", help="Set here Constant tare weight" " for the given product. This tare will be substracted when" diff --git a/pos_tare/static/src/js/Screens/ProductScreen/ProductScreen.js b/pos_tare/static/src/js/Screens/ProductScreen/ProductScreen.js new file mode 100644 index 0000000000..e0503bae34 --- /dev/null +++ b/pos_tare/static/src/js/Screens/ProductScreen/ProductScreen.js @@ -0,0 +1,167 @@ +odoo.define("pos_tare.screens", function (require) { + "use strict"; + const ProductScreen = require("point_of_sale.ProductScreen"); + const Registries = require("point_of_sale.Registries"); + const {useBarcodeReader} = require("point_of_sale.custom_hooks"); + + const TareProductScreen = (ProductScreen) => + class extends ProductScreen { + constructor() { + super(...arguments); + useBarcodeReader({ + // We add the tare action + tare: this._barcodeTareAction, + }); + } + + async _barcodeTareAction(code) { + var last_orderline = this.currentOrder.get_last_orderline(); + if (last_orderline) { + last_orderline.set_tare(code.value, true); + } + } + + async _getAddProductOptions(product) { + let price_extra = 0.0; + let draftPackLotLines, weight, description, packLotLinesToEdit, tare; // eslint-disable-line + + if ( + this.env.pos.config.product_configurator && + _.some( + product.attribute_line_ids, + (id) => id in this.env.pos.attributes_by_ptal_id + ) + ) { + const attributes = _.map( + product.attribute_line_ids, + (id) => this.env.pos.attributes_by_ptal_id[id] + ).filter((attr) => attr !== undefined); + const {confirmed, payload} = await this.showPopup( + "ProductConfiguratorPopup", + { + product: product, + attributes: attributes, + } + ); + + if (confirmed) { + description = payload.selected_attributes.join(", "); + price_extra += payload.price_extra; + } else { + return; + } + } + + // Gather lot information if required. + if ( + ["serial", "lot"].includes(product.tracking) && + (this.env.pos.picking_type.use_create_lots || + this.env.pos.picking_type.use_existing_lots) + ) { + const isAllowOnlyOneLot = product.isAllowOnlyOneLot(); + if (isAllowOnlyOneLot) { + packLotLinesToEdit = []; + } else { + const orderline = this.currentOrder + .get_orderlines() + .filter((line) => !line.get_discount()) + .find((line) => line.product.id === product.id); + if (orderline) { + packLotLinesToEdit = orderline.getPackLotLinesToEdit(); + } else { + packLotLinesToEdit = []; + } + } + const {confirmed, payload} = await this.showPopup("EditListPopup", { + title: this.env._t("Lot/Serial Number(s) Required"), + isSingleItem: isAllowOnlyOneLot, + array: packLotLinesToEdit, + }); + if (confirmed) { + // Segregate the old and new packlot lines + const modifiedPackLotLines = Object.fromEntries( + payload.newArray + .filter((item) => item.id) + .map((item) => [item.id, item.text]) + ); + const newPackLotLines = payload.newArray + .filter((item) => !item.id) + .map((item) => ({lot_name: item.text})); + + draftPackLotLines = {modifiedPackLotLines, newPackLotLines}; + } else { + // We don't proceed on adding product. + return; + } + } + + // Take the weight if necessary. + if (product.to_weight && this.env.pos.config.iface_electronic_scale) { + // Show the ScaleScreen to weigh the product. + if (this.isScaleAvailable) { + const {confirmed, payload} = await this.showTempScreen( + "ScaleScreen", + { + product, + } + ); + if (confirmed) { + // ///////////////////////////// + // Overload Section + // We add the tare to the payload + // ///////////////////////////// + weight = payload.weight; + tare = payload.tare; + } else { + // Do not add the product; + return; + } + } else { + await this._onScaleNotAvailable(); + } + } + + return { + draftPackLotLines, + quantity: weight, + description, + price_extra, + tare: tare, + }; + } + + _setValue(val) { + super._setValue(val); + if (this.currentOrder.get_selected_orderline()) { + if (this.state.numpadMode === "tare") { + if (this.env.pos.config.iface_tare_method === "barcode") { + this.showPopup("ErrorPopup", { + title: this.env._t("Feature Disabled"), + body: this.env._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 { + this.currentOrder + .get_selected_orderline() + .set_tare(val, true); + } catch (error) { + this.showPopup("ErrorPopup", { + title: this.env._t("We can not apply this tare"), + body: error.message, + }); + } + } + } + } + } + }; + + Registries.Component.extend(ProductScreen, TareProductScreen); + + return ProductScreen; +}); diff --git a/pos_tare/static/src/js/Screens/ScaleScreen/ScaleScreen.js b/pos_tare/static/src/js/Screens/ScaleScreen/ScaleScreen.js new file mode 100644 index 0000000000..0823000499 --- /dev/null +++ b/pos_tare/static/src/js/Screens/ScaleScreen/ScaleScreen.js @@ -0,0 +1,52 @@ +odoo.define("pos_tare.ScaleScreen", function (require) { + "use strict"; + + const Registries = require("point_of_sale.Registries"); + const ScaleScreen = require("point_of_sale.ScaleScreen"); + const {useState} = owl.hooks; + const {useAutofocus} = require("web.custom_hooks"); + + const ColaborScaleScreen = (ScaleScreen) => + class extends ScaleScreen { + constructor() { + super(...arguments); + this.state = useState({ + tare: this.props.product.tare_weight, + weight: 0, + gross_weight: 0, + }); + useAutofocus({selector: "#input_weight_tare"}); + } + + _readScale() { + if (this.env.pos.config.iface_gross_weight_method === "scale") { + super._readScale(); + } + } + + async _setWeight() { + await super._setWeight(); + this.state.gross_weight = this.state.weight; + this.state.weight -= this.state.tare; + } + + updateWeight() { + this.state.weight = this.state.gross_weight - this.state.tare; + } + + confirm() { + this.props.resolve({ + confirmed: true, + payload: { + weight: this.state.weight, + tare: this.state.tare, + }, + }); + this.trigger("close-temp-screen"); + } + }; + + Registries.Component.extend(ScaleScreen, ColaborScaleScreen); + + return ScaleScreen; +}); diff --git a/pos_tare/static/src/js/db.js b/pos_tare/static/src/js/db.js deleted file mode 100644 index a8a0ffff1a..0000000000 --- a/pos_tare/static/src/js/db.js +++ /dev/null @@ -1,13 +0,0 @@ -/* -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). -*/ - -odoo.define("pos_tare.db", function (require) { - "use strict"; - - var models = require("point_of_sale.models"); - - models.load_fields("product.product", ["tare_weight"]); -}); diff --git a/pos_tare/static/src/js/models.js b/pos_tare/static/src/js/models.js index f02663383d..89affe3161 100644 --- a/pos_tare/static/src/js/models.js +++ b/pos_tare/static/src/js/models.js @@ -1,15 +1,26 @@ odoo.define("pos_tare.models", function (require) { "use strict"; - var core = require("web.core"); var models = require("point_of_sale.models"); + models.load_fields("product.product", ["tare_weight"]); var pos_tare_tools = require("pos_tare.tools"); - var _t = core._t; - var _super_ = models.Orderline.prototype; + var _superOrder_ = models.Order.prototype; + + var OrderWithTare = models.Order.extend({ + add_product: function (product, options) { + var res = _superOrder_.add_product.call(this, product, options); + if (options.tare !== undefined) { + this.get_last_orderline().set_tare(options.tare); + } + return res; + }, + }); + var OrderLineWithTare = models.Orderline.extend({ // ///////////////////////////// // Overload Section // ///////////////////////////// + initialize: function (session, attributes) { this.tare = 0; return _super_.initialize.call(this, session, attributes); @@ -65,11 +76,6 @@ odoo.define("pos_tare.models", function (require) { 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. @@ -114,4 +120,5 @@ odoo.define("pos_tare.models", function (require) { }); models.Orderline = OrderLineWithTare; + models.Order = OrderWithTare; }); diff --git a/pos_tare/static/src/js/screens.js b/pos_tare/static/src/js/screens.js deleted file mode 100644 index c7d31e1680..0000000000 --- a/pos_tare/static/src/js/screens.js +++ /dev/null @@ -1,211 +0,0 @@ -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) - ); - } - }, - }); - - var _super_ScaleScreenWidget_order_product = - screens.ScaleScreenWidget.prototype.order_product; - - screens.ScaleScreenWidget.include({ - // ///////////////////////////// - // Overload Section - // ///////////////////////////// - - show: function () { - this._super(); - this.tare = this.get_product().tare_weight; - if (this.tare) { - this.$("#input_weight_tare")[0].value = this.tare; - } - this.gross_weight = 0.0; - 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 () { - var self = this; - 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 if (isNaN(this.gross_weight)) { - this.gui.show_popup("error", { - title: _t("Incorrect Gross Weight Value"), - body: _t( - "Please set a numeric value" + " in the gross weight field." - ), - }); - } else if (this.weight <= 0) { - this.gui.show_popup("confirm", { - title: _t("Quantity lower or equal to zero"), - body: _t( - "The quantity is lower or equal to" + - " zero. Are you sure you want to continue ?" - ), - confirm: function () { - _super_ScaleScreenWidget_order_product.apply(self); - if (self.tare > 0.0) { - var order = self.pos.get_order(); - var orderline = order.get_last_orderline(); - orderline.set_tare(self.tare, false); - } - }, - }); - } 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.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("Feature Disabled"), - 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/xml/Screens/ProductScreen/NumpadWidget.xml b/pos_tare/static/src/xml/Screens/ProductScreen/NumpadWidget.xml new file mode 100644 index 0000000000..538069c210 --- /dev/null +++ b/pos_tare/static/src/xml/Screens/ProductScreen/NumpadWidget.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/pos_tare/static/src/xml/Screens/ProductScreen/Orderline.xml b/pos_tare/static/src/xml/Screens/ProductScreen/Orderline.xml new file mode 100644 index 0000000000..9b5c8a1544 --- /dev/null +++ b/pos_tare/static/src/xml/Screens/ProductScreen/Orderline.xml @@ -0,0 +1,24 @@ + + + + + + +
  • + + Gross Weight: + + - Tare: + ) + +
  • +
    +
    +
    + +
    diff --git a/pos_tare/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml b/pos_tare/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml new file mode 100644 index 0000000000..a1365def39 --- /dev/null +++ b/pos_tare/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml @@ -0,0 +1,22 @@ + + + + + + +
    + Gross Weight : +
    + Tare : +
    +
    +
    +
    +
    + +
    diff --git a/pos_tare/static/src/xml/Screens/ScaleScreen/ScaleScreen.xml b/pos_tare/static/src/xml/Screens/ScaleScreen/ScaleScreen.xml new file mode 100644 index 0000000000..a6b0169d1e --- /dev/null +++ b/pos_tare/static/src/xml/Screens/ScaleScreen/ScaleScreen.xml @@ -0,0 +1,54 @@ + + + + + + +
    + Gross Weight +
    + +
    + + +
    +
    + +
    + + +
    +
    +
    + Tare +
    +
    + + +
    +
    +
    +
    + +
    diff --git a/pos_tare/static/src/xml/pos_tare.xml b/pos_tare/static/src/xml/pos_tare.xml deleted file mode 100644 index d7f6036a30..0000000000 --- a/pos_tare/static/src/xml/pos_tare.xml +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - -
    - Gross Weight -
    - -
    - - -
    - - -
    -
    -
    - Tare -
    -
    - - -
    - - - - - - - -
  • - - Gross Weight: - - - Tare: - ) - -
  • -
    -
    -
    - - - - -
    - Gross Weight : -
    - Tare : -
    -
    -
    -
    -
    - - - - - - - ( - - - - - - - - ) - - - - - - - -
    - - - - - -
    - - - - - -
    - - - - - -
    - - - - - - -
    -
    - diff --git a/pos_tare/views/templates.xml b/pos_tare/views/templates.xml index 7020d2d9d2..268e36ed93 100644 --- a/pos_tare/views/templates.xml +++ b/pos_tare/views/templates.xml @@ -4,8 +4,14 @@