Commit 67b04f69 by François C.

Merge branch '4612-cb-dej-issuer' into 'dev_cooperatic'

4612 cb dej issuer

See merge request !57
parents c17e57ac 50064609
......@@ -33,6 +33,7 @@ that allows customer to buy food products in grocery stores or pay in restaurant
Configuration
=============
Products
~~~~~~~~
......@@ -46,19 +47,28 @@ Products
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/product_category_form.png
Journals
~~~~~~~~
* configures your Account journals, mentioning the type of Meal Voucher:
- Paper : the journal will be used when scanning meal voucher barcodes
- Dematerialized: the journal will be used for dematerialized meal vouchers
- Mixed: Specific configuration if your accountant want to use a single journal for Credit card AND dematerialized meal vouchers. In that case, the button of this journal will be duplicated, and an extra text can be set to display an alternative label.
- Paper : the journal will be used when scanning meal voucher barcodes
- Dematerialized: the journal will be used for dematerialized meal vouchers
- Mixed: Specific configuration if your accountant want to use a single journal for Credit card AND dematerialized meal vouchers. In that case, the button of this journal will be duplicated, and an extra text can be set to display an alternative label.
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/account_journal_form.png
Point of sale
~~~~~~~~
* go your point of sale configuration form, and set the maximum amount allowed by ticket. (optional)
.. figure:: https://raw.githubusercontent.com/legalsylvain/pos/12.0-ADD-pos_meal_voucher/pos_meal_voucher/static/description/pos_config_form.png
* configure if you want to allow or forbid to exceed the maximum allowed by ticket and for order (Give change on meal voucher)
* configure if you want to display a cuttlery icon before products name in pos
* configure if you want to allow or forbid to exceed the maximum allowed by ticket and by order (Give change on meal voucher)
* configure if you want the cashier to fill in the meal voucher issuer on CB payments
Usage
......@@ -89,8 +99,8 @@ It is a non blocking warning, because we don't want to prevent an order to be do
if products are not correctly set, or if a recent law changed the maximum amount that can
be used each day. (A recent case occured in France, during the Covid-19 pandemy)
If you want to make it impossible to finish an order if the amount of meal voucher is too big then uncheck the option "meal_voucher_change_accepted"
In this case if the cashier tries to validate the order the warning will redirect him to the paiement page.
If you want to make it impossible to finish an order if the amount of meal voucher is too big, then uncheck the option "meal_voucher_change_accepted".
In this case if the cashier tries to validate the order the warning will redirect him to the payment page.
Note
~~~~
......
......@@ -15,6 +15,7 @@
],
"data": [
"data/barcode_rule.xml",
"data/ir_config_parameter_data.xml",
"views/view_account_journal.xml",
"views/view_pos_config.xml",
"views/view_product_category.xml",
......
<?xml version="1.0"?>
<odoo noupdate="0">
<record id="meal_voucher_issuers" model="ir.config_parameter">
<field name="key">pos_meal_voucher.meal_voucher_issuers</field>
<field name="value">["Bimpli", "Up", "Sodexo", "Eden Red", "Swile"]</field>
</record>
</odoo>
......@@ -11,3 +11,6 @@ class AccountBankStatementLine(models.Model):
statement_note = fields.Char(
string="Number ID of the meal voucher")
meal_voucher_issuer = fields.Char(
string="Issuing entity of the meal voucher")
......@@ -20,3 +20,7 @@ class PosConfig(models.Model):
meal_voucher_change_accepted = fields.Boolean(
string="Give change on meal voucher",
default=True)
meal_voucher_ask_for_issuer = fields.Boolean(
string="Ask the cashier for the meal voucher issuer for CB payments",
default=True)
......@@ -15,6 +15,7 @@ class PosOrder(models.Model):
def _payment_fields(self, cr, uid, ui_paymentline, context=None):
res = super(PosOrder, self)._payment_fields(cr, uid, ui_paymentline)
res["statement_note"] = ui_paymentline.get("statement_note", False)
res["meal_voucher_issuer"] = ui_paymentline.get("meal_voucher_issuer", False)
return res
def add_payment(self, cr, uid, order_id, data, context=None):
......@@ -72,12 +73,17 @@ class PosOrder(models.Model):
statement_note = ''
if 'statement_note' in data:
statement_note = data['statement_note']
meal_voucher_issuer = ''
if 'meal_voucher_issuer' in data:
meal_voucher_issuer = data['meal_voucher_issuer']
args.update({
'statement_id': statement_id,
'pos_statement_id': order_id,
'journal_id': journal_id,
'ref': order.session_id.name,
'statement_note': statement_note,
'meal_voucher_issuer': meal_voucher_issuer,
})
statement_line_obj.create(cr, uid, args, context=context)
......
......@@ -63,3 +63,6 @@
padding: 8px 12px;
}
.popup-textinput select {
margin: 10px 16px !important;
}
\ No newline at end of file
......@@ -174,17 +174,20 @@ odoo.define("pos_meal_voucher.models", function (require) {
// See odoo/addons/point_of_sale/models/pos_order.py:59
// and then in the name of the statement line.
// See odoo/addons/point_of_sale/models/pos_order.py:950
this.statement_note = '';
this.manual_meal_voucher = false;
this.statement_note = this.statement_note || '';
this.meal_voucher_issuer = this.meal_voucher_issuer || '';
this.manual_meal_voucher = this.manual_meal_voucher || false;
},
init_from_JSON: function (json) {
PaymentlineSuper.init_from_JSON.apply(this, arguments);
this.statement_note = json.statement_note;
this.meal_voucher_issuer = json.meal_voucher_issuer;
},
export_as_JSON: function () {
var res = PaymentlineSuper.export_as_JSON.apply(this, arguments);
res.statement_note = this.statement_note;
res.meal_voucher_issuer = this.meal_voucher_issuer;
return res;
},
......@@ -203,9 +206,54 @@ odoo.define("pos_meal_voucher.models", function (require) {
return (
this.cashregister.journal.meal_voucher_type == "paper") ;
},
set_meal_voucher_issuer: function(value){
this.order.assert_editable();
this.meal_voucher_issuer = value;
this.trigger('change',this);
},
});
models.Paymentline = Paymentline;
var gui = require('point_of_sale.gui');
var PopupWidget = require('point_of_sale.popups');
var SelectOrTextInputPopupWidget = PopupWidget.extend({
template: 'TextInputPopupWidget',
show: function(options){
options = options || {};
this._super(options);
this.renderElement();
// On input change of value, reset select, and vice versa
this.$("input").on("input", (e) => {
if (e.target.value !== '') {
this.$("select").val('').change();
}
})
this.$("select").on("change", (e) => {
if (e.target.value !== '') {
this.$("input").val('');
}
})
},
click_confirm: function(){
var value =
this.$('select').find(":selected").val() ?
this.$('select').find(":selected").val() :
this.$('input,textarea').val();
// At least one field is mandatory
if (value === '') {
return;
}
this.gui.close_popup();
if( this.options.confirm ){
this.options.confirm.call(this,value);
}
},
});
gui.define_popup({name:'select-or-textinput', widget: SelectOrTextInputPopupWidget});
});
......@@ -10,6 +10,8 @@ odoo.define("pos_meal_voucher.screens", function (require) {
var formats = require('web.formats');
var _t = core._t;
var QWeb = core.qweb;
var Model = require('web.DataModel');
var config_parameter = new Model('ir.config_parameter');
screens.ScreenWidget.include({
barcode_meal_voucher_payment_action: function (code) {
......@@ -115,7 +117,6 @@ odoo.define("pos_meal_voucher.screens", function (require) {
screens.PaymentScreenWidget.include({
//check if POS if configured to accept payment in meal voucher
meal_voucher_activated: function() {
var is_meal_voucher_method = this.pos.cashregisters.map(function(cash_register) {
......@@ -133,8 +134,6 @@ odoo.define("pos_meal_voucher.screens", function (require) {
var self = this;
this._super(parent, options);
// This is a keydown handler that prevents backspace from
// doing a back navigation. It also makes sure that keys that
// do not generate a keypress in Chrom{e,ium} (eg. delete,
......@@ -195,6 +194,13 @@ odoo.define("pos_meal_voucher.screens", function (require) {
};
this.meal_voucher_issuers = [];
// get meal voucher issuers from config
config_parameter.call('get_param', ['pos_meal_voucher.meal_voucher_issuers'])
.then( function(value){
self.meal_voucher_issuers = JSON.parse(value);
});
},
payment_input: function(input) {
......@@ -270,6 +276,12 @@ odoo.define("pos_meal_voucher.screens", function (require) {
});
return methods;
},
remove_selected_paymentline: function(order) {
this.pos.get_order().remove_paymentline(order.selected_paymentline);
var paymentScreen = this.pos.gui.current_screen;
paymentScreen.reset_input();
paymentScreen.render_paymentlines();
},
click_paymentmethods: function(id) {
var self = this;
var methods = this._super.apply(this, arguments);
......@@ -286,20 +298,20 @@ odoo.define("pos_meal_voucher.screens", function (require) {
'title': _t("Impossible de payer en titre restaurant"),
'body': _t("Aucun article du panier n'est éligible en titres restaurants (Montant éligible : 0€)."),
cancel: function() {
this.pos.get_order().remove_paymentline(order.selected_paymentline);
var paymentScreen = this.pos.gui.current_screen;
paymentScreen.reset_input();
paymentScreen.render_paymentlines();
self.remove_selected_paymentline(order);
}
});
return false;
}
// if user choose card meal voucher
if(order.selected_paymentline.is_meal_voucher() && order.selected_paymentline.is_dematerialized_meal_voucher()){
// update selected (last) payment line & order with meal voucher data
function update_order_meal_voucher_data(issuer = '') {
var total_eligible = order.get_total_meal_voucher_eligible();
var total_received = order.get_total_meal_voucher_received();
var max_amount = this.pos.config.max_meal_voucher_amount;
var max_amount = self.pos.config.max_meal_voucher_amount;
var current_max = total_eligible;
if (max_amount) {
current_max = Math.min(total_eligible, max_amount);
......@@ -310,11 +322,45 @@ odoo.define("pos_meal_voucher.screens", function (require) {
const max_curent_amount = current_max-total_received +order.selected_paymentline.get_amount();
order.selected_paymentline.set_amount(max_curent_amount);
order.selected_paymentline.set_meal_voucher_issuer(issuer);
paymentScreen.order_changes();
paymentScreen.render_paymentlines();
paymentScreen.$(".paymentline.selected .edit").text(paymentScreen.format_currency_no_symbol(max_curent_amount));
}
// If required by the config, ask for the meal voucher issuer
if (this.pos.config.meal_voucher_ask_for_issuer) {
let select_data = [{
'val': "",
'text': "- Choississez un émetteur"
}];
for (let issuer of this.meal_voucher_issuers) {
select_data.push({
"val": issuer,
"text": issuer
});
}
this.gui.show_popup("select-or-textinput", {
'title': _t("Émetteur du titre restaurant"),
'body': _t("Si l'émetteur n'est pas dans la liste ci-dessus, veuillez le noter dans le champs ci-dessous : "),
'selectText': _t("Veuillez sélectionner l'émetteur de CB déj dans la liste ci-dessous : "),
'selectData': select_data,
confirm: function(value) {
let issuer = value;
update_order_meal_voucher_data(issuer)
},
cancel: function(value) {
self.remove_selected_paymentline(order);
},
});
} else {
update_order_meal_voucher_data();
}
}
// If user choose paper meal voucher
// Open a popup asking for the number of the meal voucher
if(order.selected_paymentline.is_meal_voucher() && order.selected_paymentline.is_paper_meal_voucher()){
......@@ -332,12 +378,7 @@ odoo.define("pos_meal_voucher.screens", function (require) {
},
cancel: function(vaue) {
this.pos.get_order().remove_paymentline(order.selected_paymentline);
var paymentScreen = this.pos.gui.current_screen;
paymentScreen.reset_input();
paymentScreen.render_paymentlines();
self.remove_selected_paymentline(order);
},
});
}
......
......@@ -68,9 +68,28 @@
</td>
</t>
</t>
<t t-jquery="td.col-name" t-operation="append">
<t t-if="line.meal_voucher_issuer !== ''">
<span class="meal-voucher-issuer">
[<t t-esc="line.meal_voucher_issuer"/>]
</span>
</t>
</t>
</t>
<t t-extend="TextInputPopupWidget">
<t t-jquery="p.title" t-operation="after">
<t t-if="widget.options.selectText">
<p class="body"><t t-esc="widget.options.selectText"/></p>
</t>
<t t-if="widget.options.selectData">
<select class="select body">
<t t-as="element" t-foreach="widget.options.selectData">
<option t-att-value="element.val">
<t t-esc="element.text"/>
</option>
</t>
</select>
</t>
<p class="body"><t t-esc=" widget.options.body || '' "/></p>
</t>
</t>
......
......@@ -15,6 +15,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
<field name="max_meal_voucher_amount"/>
<field name="meal_voucher_display_product_screen"/>
<field name="meal_voucher_change_accepted"/>
<field name="meal_voucher_ask_for_issuer"/>
</group>
</field>
</field>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment