Browse Source

Merge pull request #1 from legalsylvain/12.0-mig-tare-fix

12.0 mig tare fix
pull/501/head
François Kawala 4 years ago
committed by GitHub
parent
commit
a4adce439d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      pos_tare/__manifest__.py
  2. 10
      pos_tare/demo/pos_tare_demo.xml
  3. 1
      pos_tare/models/__init__.py
  4. 4
      pos_tare/models/barcode_rule.py
  5. 41
      pos_tare/models/pos_config.py
  6. 15
      pos_tare/models/pos_order_line.py
  7. 8
      pos_tare/pos_tare.xml
  8. 1
      pos_tare/readme/CONTRIBUTORS.rst
  9. 1
      pos_tare/readme/ROADMAP.rst
  10. BIN
      pos_tare/static/description/pos_ticket.png
  11. 114
      pos_tare/static/src/js/models.js
  12. 269
      pos_tare/static/src/js/pos_tare.js
  13. 137
      pos_tare/static/src/js/screens.js
  14. 62
      pos_tare/static/src/js/tools.js
  15. 81
      pos_tare/static/src/xml/pos_tare.xml
  16. 28
      pos_tare/views/pos_config_view.xml
  17. 10
      pos_tare/views/templates.xml
  18. 54
      pos_tare/views/view_pos_config.xml
  19. 16
      pos_tare/views/view_pos_order.xml

30
pos_tare/__manifest__.py

@ -3,21 +3,21 @@
{
"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'],
'depends': ['point_of_sale'],
'demo': ['demo/pos_tare_demo.xml'],
'data': [
'pos_tare.xml',
'views/pos_config_view.xml',
'data/barcode_rule.xml',
"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"],
"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',
"qweb": [
"static/src/xml/pos_tare.xml",
],
'installable': True,
"installable": True,
}

10
pos_tare/demo/pos_tare_demo.xml

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="product_uom_kgm_dbg" model="uom.uom">
<field name="category_id" ref="uom.product_uom_categ_kgm"/>
<field name="name">Kg</field>
<field name="factor" eval="1"/>
<field name="rounding" eval="0.001"/>
<field name="uom_type">bigger</field>
</record>
</odoo>

1
pos_tare/models/__init__.py

@ -1,2 +1,3 @@
from . import pos_config
from . import pos_order_line
from . import barcode_rule

4
pos_tare/models/barcode_rule.py

@ -1,9 +1,9 @@
from odoo import _, models, fields
from odoo import models, fields
class BarcodeRule(models.Model):
_inherit = 'barcode.rule'
type = fields.Selection(selection_add=[
('tare', _('Tare'))
('tare', 'Tare')
])

41
pos_tare/models/pos_config.py

@ -1,18 +1,39 @@
from odoo import models, fields
from odoo import api, models, fields
class PosConfig(models.Model):
_inherit = 'pos.config'
_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'),
("manual", "Input the tare manually"),
("barcode", "Scan a barcode to set the tare"),
("both", "Manual input and barcode"),
],
string='Tare input method',
default='Both',
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';",
"* '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")

15
pos_tare/models/pos_order_line.py

@ -0,0 +1,15 @@
# Copyright (C) 2020-Today: GRAP (<http://www.grap.coop/>)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, 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")
)

8
pos_tare/pos_tare.xml

@ -1,8 +0,0 @@
<odoo>
<template id="assets_backend" name="pos_tare" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<link rel="stylesheet" href="/pos_tare/static/src/css/pos_tare.css"/>
<script type="text/javascript" src="/pos_tare/static/src/js/pos_tare.js"></script>
</xpath>
</template>
</odoo>

1
pos_tare/readme/CONTRIBUTORS.rst

@ -1,4 +1,3 @@
- Sylvain LE GAL (https://www.twitter.com/legalsylvain)
- Le Nid
- CoopITEasy

1
pos_tare/readme/ROADMAP.rst

@ -1 +0,0 @@
- Print tare value on customer receipt.

BIN
pos_tare/static/description/pos_ticket.png

After

Width: 500  |  Height: 395  |  Size: 24 KiB

114
pos_tare/static/src/js/models.js

@ -0,0 +1,114 @@
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();
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) {
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));
}
// We convert the tare that is always measured in the same UoM into
// the unit of measure for this order line.
var tare_unit = this.pos.units_by_id[this.pos.config.iface_tare_uom_id[0]];
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;
// 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, line_unit.name,
this.get_quantity_str_with_unit()));
}
// 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);
},
get_tare: function () {
return this.tare;
},
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_tare() + this.get_quantity(),
this.get_unit(),
);
return gross_weight_str + ' ' + unit.name;
},
});
models.Orderline = OrderLineWithTare;
});

269
pos_tare/static/src/js/pos_tare.js

@ -1,269 +0,0 @@
odoo.define('pos_barcode_tare.screens', function (require) {
"use strict";
var core = require('web.core');
var models = require('point_of_sale.models');
var screens = require('point_of_sale.screens');
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;
// 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;
};
// 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);
};
// 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);
} 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 () {
console.log("okok");
this._super();
if (this.pos.config.iface_tare_method !== 'Manual') {
console.log("okokokok");
this.pos.barcode_reader.set_action_callback(
'tare',
_.bind(this.barcode_tare_action, this));
}
},
});
screens.ScaleScreenWidget.include({
// /////////////////////////////
// Overload Section
// /////////////////////////////
// Overload show function
// add an handler on the
show: function () {
this._super();
this.tare = 0.0;
var self = this;
this.$('#input_weight_tare').keyup(function (event) {
self.onchange_tare(event);
});
this.$('#input_weight_tare').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 () {
// TODO Set a warning, if the value is incorrect;
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);
}
}
},
// /////////////////////////////
// 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);
},
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);
},
});
// Update Orderline model
var _super_ = models.Orderline.prototype;
var OrderLineWithTare = 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));
}
// 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 = format_tare(this.pos,
tare_in_product_uom, unit);
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;
},
});
models.Orderline = OrderLineWithTare;
return {OrderLineWithTare: OrderLineWithTare,
get_unit: get_unit};
});

137
pos_tare/static/src/js/screens.js

@ -0,0 +1,137 @@
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;
// 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 () {
// TODO Set a warning, if the value is incorrect;
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);
},
});
});

62
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,
};
});

81
pos_tare/static/src/xml/pos_tare.xml

@ -1,60 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-extend="ScaleScreenWidget">
<t t-jquery=".js-weight" t-operation="before">
<t t-if="widget.pos.config.iface_tare_method != 'Barcode'">
<t t-if="widget.pos.config.iface_tare_method != 'barcode'">
<div class="weight-label">
Gross Weight
</div>
<div class="weight-value weight-value-fixed" id="container_weight_gross"/>
<t t-if="widget.pos.config.iface_gross_weight_method == 'scale'">
<div class="weight-value weight-value-fixed"
id="container_weight_gross"/>
</t>
<t t-else="1">
<div class="weight-value weight-value-alterable">
<input type="text" class="input-weight" id="input_gross_weight" placeholder="0.000"/>
<t t-esc="widget.pos.config.iface_tare_uom_id[1]"/>
</div>
</t>
<div class="weight-label">
Tare
</div>
<div class="weight-value weight-value-alterable">
<input type="text" class="input-weight" id="input_weight_tare" placeholder="0.000"/> Kg
<input type="text" class="input-weight" id="input_weight_tare" placeholder="0.000"/>
<t t-esc="widget.pos.config.iface_tare_uom_id[1]"/>
</div>
</t>
</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 t-extend="Orderline">
<t t-jquery=".info-list:last-child" t-operation="append">
<t t-if="line.get_tare() !== 0">
<li class="info">
<i class="fa fa-beer"/>
Tare : <t t-esc="line.get_tare_str_with_unit()" />
</li>
</t>
</t>
</t>
<t t-name="PosTicket" t-extend="PosTicket">
<t t-jquery="tr[t-foreach='orderlines'] > td:nth-child(1)"
t-operation="append">
<t t-if="orderline.get_tare() > 0">
<div class="pos-disc-font">
Gross Weight : <t t-esc="orderline.get_gross_weight_str_with_unit()" /><br/>
Tare : <t t-esc="orderline.get_tare_str_with_unit()" /><br/>
</div>
</t>
</t>
</t>
<!-- TODO Overload XmlReceipt for Proxy usage -->
<!-- <t t-name="XmlReceipt" t-extend="XmlReceipt">
</t> -->
</templates>

28
pos_tare/views/pos_config_view.xml

@ -1,28 +0,0 @@
<?xml version="1.0"?>
<odoo>
<record model="ir.ui.view" id="view_pos_config_form">
<field name="name">view.pos.config.form</field>
<field name="model">pos.config</field>
<field name="inherit_id" ref="point_of_sale.pos_config_view_form" />
<field name="priority" eval="30"/>
<field name="arch" type="xml">
<xpath expr="//h2[@name='order']/following-sibling::*[position()=1]" position="inside">
<div class="col-xs-12 col-lg-6 o_setting_box" id="iface_tare_method">
<div class="o_setting_right_pane">
<label for="iface_tare_method" string="Tare method"/>
<div class="text-muted">
Configure how to tare products to weight with a scale.
</div>
<div class="content-group">
<div class="mt16">
<field name="iface_tare_method" class="o_light_label"/>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

10
pos_tare/views/templates.xml

@ -0,0 +1,10 @@
<odoo>
<template id="assets" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<link rel="stylesheet" href="/pos_tare/static/src/css/pos_tare.css"/>
<script type="text/javascript" src="/pos_tare/static/src/js/tools.js"></script>
<script type="text/javascript" src="/pos_tare/static/src/js/models.js"></script>
<script type="text/javascript" src="/pos_tare/static/src/js/screens.js"></script>
</xpath>
</template>
</odoo>

54
pos_tare/views/view_pos_config.xml

@ -0,0 +1,54 @@
<?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.pos_config_view_form" />
<field name="priority" eval="30"/>
<field name="arch" type="xml">
<xpath expr="//h2[@name='order']/following-sibling::*[position()=1]" position="inside">
<div class="col-xs-12 col-lg-6 o_setting_box" id="iface_tare_method">
<div class="o_setting_right_pane">
<label for="iface_tare_method" string="Tare Input Method"/>
<div class="text-muted">
Configure how to tare products to weight with a scale.
</div>
<div class="content-group">
<div class="mt16">
<field name="iface_tare_method" class="o_light_label"/>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" id="iface_tare_method">
<div class="o_setting_right_pane">
<label for="iface_tare_uom_id" string="Tare UoM"/>
<div class="text-muted">
Unit of Measure of the tares.
</div>
<div class="content-group">
<div class="mt16">
<field name="iface_tare_uom_id" class="o_light_label"/>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" id="iface_gross_weight_method">
<div class="o_setting_right_pane">
<label for="iface_gross_weight_method" string="Gross Weight Input Method"/>
<div class="text-muted">
Configure how to input Gross Weight.
</div>
<div class="content-group">
<div class="mt16">
<field name="iface_gross_weight_method" class="o_light_label"/>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

16
pos_tare/views/view_pos_order.xml

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<odoo>
<record model="ir.ui.view" id="view_pos_order_form">
<field name="model">pos.order</field>
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form"/>
<field name="arch" type="xml">
<field name="qty" position="after">
<field name="tare"/>
</field>
</field>
</record>
</odoo>
Loading…
Cancel
Save