Browse Source

Merge pull request #2 from Fkawala/12.0-mig-tare-wip

Proxy print + Tare button cc. @legalsylvain merci pour le fix escpos, il reste aussi a changer le comportement du bouton QTY pour que celui-ci change le "gross weight" et pas le "net weight" quand la tare est renseignée. Je vais essayer de faire ca demain matin avant le boulot, mais j'ai peu de bande passante en ce moment, désolé...
pull/501/head
François Kawala 4 years ago
committed by GitHub
parent
commit
7675ff1f5d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      pos_tare/__init__.py
  2. 6
      pos_tare/models/__init__.py
  3. 8
      pos_tare/static/src/css/pos_tare.css
  4. 73
      pos_tare/static/src/js/models.js
  5. 77
      pos_tare/static/src/js/screens.js
  6. 97
      pos_tare/static/src/xml/pos_tare.xml

2
pos_tare/__init__.py

@ -1 +1 @@
from . import models
from . import models # noqa: F401

6
pos_tare/models/__init__.py

@ -1,3 +1,3 @@
from . import pos_config
from . import pos_order_line
from . import barcode_rule
from . import pos_config # noqa: F401
from . import pos_order_line # noqa: F401
from . import barcode_rule # noqa: F401

8
pos_tare/static/src/css/pos_tare.css

@ -47,3 +47,11 @@
outline: none;
box-shadow: 0px 0px 0px 3px #6EC89B;
}
.pos .actionpad .button.pay {
height: 216px;
}
.pos .numpad button.input-button.numpad-backspace {
width: 216px;
}

73
pos_tare/static/src/js/models.js

@ -7,6 +7,32 @@ odoo.define('pos_tare.models', function (require) {
var _t = core._t;
class ValidationError extends Error {
constructor(message, gui) {
super(message); // (1)
this.name = "ValidationError"; // (2)
this.gui = gui;
}
}
var _NumpadState_ = models.NumpadState.prototype;
var NumpadState = models.NumpadState.extend({
appendNewChar: function (newChar) {
try {
_NumpadState_.appendNewChar.call(this, newChar);
} catch (error) {
if (error instanceof ValidationError) {
var title = _t("Error while applying the numpad action");
var popup = {title: title, body: error.message};
error.gui.show_popup('error', popup);
_NumpadState_.deleteLastChar.call(this);
} else {
throw error;
}
}
},
});
var _super_ = models.Orderline.prototype;
var OrderLineWithTare = models.Orderline.extend({
@ -38,41 +64,46 @@ odoo.define('pos_tare.models', function (require) {
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) {
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));
// 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_unit = this.pos.units_by_id[this.pos.config.iface_tare_uom_id[0]];
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);
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."),
throw new ValidationError(_.str.sprintf(
_t("The tare weight is %s %s, it's greater or equal" +
" to the gross weight %s. To apply this tare would" +
" result in a negative net weight and a negative" +
" price. This tare can not be applied to this item."),
tare_in_product_uom_string, line_unit.name,
this.get_quantity_str_with_unit()));
this.get_quantity_str_with_unit()), this.pos.gui);
}
// Update the quantity with the new weight net of tare quantity.
this.set_quantity(net_quantity);
@ -83,16 +114,24 @@ odoo.define('pos_tare.models', function (require) {
},
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(),
this.get_unit()
);
return tare_str + ' ' + unit.name;
},
@ -101,14 +140,16 @@ odoo.define('pos_tare.models', function (require) {
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(),
this.get_gross_weight(),
this.get_unit()
);
return gross_weight_str + ' ' + unit.name;
},
});
models.NumpadState = NumpadState;
models.Orderline = OrderLineWithTare;
});

77
pos_tare/static/src/js/screens.js

@ -11,30 +11,29 @@ odoo.define('pos_tare.screens', function (require) {
// 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.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({
@ -55,7 +54,7 @@ odoo.define('pos_tare.screens', function (require) {
});
if (this.pos.config.iface_gross_weight_method === 'scale') {
this.$('#input_weight_tare').focus();
} else{
} else {
this.pos.proxy_queue.clear();
this.$('#input_gross_weight').focus();
}
@ -134,4 +133,32 @@ odoo.define('pos_tare.screens', function (require) {
});
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') {
order.get_selected_orderline().set_quantity(val);
} 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 {
order.get_selected_orderline().set_tare(val, true);
}
}
}
},
});
});

97
pos_tare/static/src/xml/pos_tare.xml

@ -1,7 +1,6 @@
<?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'">
@ -9,8 +8,7 @@
Gross Weight
</div>
<t t-if="widget.pos.config.iface_gross_weight_method == 'scale'">
<div class="weight-value weight-value-fixed"
id="container_weight_gross"/>
<div class="weight-value weight-value-fixed" id="container_weight_gross"/>
</t>
<t t-else="1">
<div class="weight-value weight-value-alterable">
@ -33,27 +31,98 @@
<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()" />
<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">
<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/>
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>
</t>
<t t-name="XmlReceipt" t-extend="XmlReceipt">
<t t-jquery=".orderlines" t-operation="inner">
<t t-foreach='receipt.orderlines' t-as='line'>
<t t-set='simple' t-value='line.discount === 0 and line.unit_name === "Unit(s)" and line.quantity === 1' />
<t t-if='simple'>
<line>
<left><t t-esc='line.product_name_wrapped[0]' /></left>
<right><value t-att-value-decimals='pos.currency.decimals'><t t-esc='line.price_display' /></value></right>
</line>
<t t-call="XmlReceiptWrappedProductNameLines"/>
</t>
<t t-if='!simple'>
<line><left><t t-esc='line.product_name_wrapped[0]' /></left></line>
<t t-call="XmlReceiptWrappedProductNameLines"/>
<t t-if='line.discount !== 0'>
<line indent='1'><left>Discount: <t t-esc='line.discount' />%</left></line>
</t>
<line indent='1'>
<left>
<value t-att-value-decimals='pos.dp["Product Unit of Measure"]' value-autoint='on'>
<t t-if="line.tare_quantity !== 0">
<t t-esc="line.gross_quantity" /> -
<t t-esc="line.tare_quantity"/> =
</t>
<t t-esc='line.quantity' />
</value>
<t t-if='line.unit_name !== "Unit(s)"'>
<t t-esc='line.unit_name' />
</t>
x
<value t-att-value-decimals='pos.dp["Product Price"]'>
<t t-esc='line.price' />
</value>
</left>
<right>
<value t-att-value-decimals='pos.currency.decimals'><t t-esc='line.price_display' /></value>
</right>
</line>
</t>
</t>
</t>
</t>
<!-- TODO Overload XmlReceipt for Proxy usage -->
<!-- <t t-name="XmlReceipt" t-extend="XmlReceipt">
</t> -->
<t t-name="NumpadWidget">
<div class="numpad">
<button class="input-button number-char">1</button>
<button class="input-button number-char">2</button>
<button class="input-button number-char">3</button>
<button class="mode-button" data-mode='quantity'>Qty</button>
<br />
<button class="input-button number-char">4</button>
<button class="input-button number-char">5</button>
<button class="input-button number-char">6</button>
<button class="mode-button" data-mode='tare'>Tare</button>
<br />
<button class="input-button number-char">7</button>
<button class="input-button number-char">8</button>
<button class="input-button number-char">9</button>
<button class="mode-button" data-mode='discount'>Disc</button>
<br />
<button class="input-button numpad-minus" >+/-</button>
<button class="input-button number-char">0</button>
<button class="input-button number-char">.</button>
<button class="mode-button" data-mode='price'>Price</button>
<button class="input-button numpad-backspace">
<img style="pointer-events: none;" src="/point_of_sale/static/src/img/backspace.png" width="24" height="21" alt="Backspace"/>
</button>
</div>
</t>
</templates>
Loading…
Cancel
Save