Browse Source

Merge PR #245 into 10.0

Signed-off-by rafaelbn
pull/424/head
OCA-git-bot 5 years ago
parent
commit
b34c9fab8c
  1. 5
      pos_payment_terminal/i18n/pos_payment_terminal.pot
  2. 1
      pos_payment_terminal/models/__init__.py
  3. 63
      pos_payment_terminal/models/pos_order.py
  4. 68
      pos_payment_terminal/static/src/js/pos_payment_terminal.js
  5. 1
      pos_payment_terminal/tests/__init__.py
  6. 50
      pos_payment_terminal/tests/test_transactions.py

5
pos_payment_terminal/i18n/pos_payment_terminal.pot

@ -33,6 +33,11 @@ msgstr ""
msgid "Payment Mode"
msgstr ""
#. module: pos_payment_terminal
#: model:ir.model,name:pos_payment_terminal.model_pos_order
msgid "Point of Sale Orders"
msgstr ""
#. module: pos_payment_terminal
#: model:ir.model.fields,help:pos_payment_terminal.field_account_journal_payment_mode
msgid "Select the payment mode sent to the payment terminal"

1
pos_payment_terminal/models/__init__.py

@ -2,3 +2,4 @@
from . import pos_config
from . import account_journal
from . import pos_order

63
pos_payment_terminal/models/pos_order.py

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
# © 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from collections import defaultdict
import logging
from odoo import models, api
_logger = logging.getLogger(__name__)
class PosOrder(models.Model):
_inherit = 'pos.order'
@api.model
def _match_transactions_to_payments(self, pos_order):
payments = pos_order['statement_ids']
transactions = pos_order['transactions']
pos_session = self.env['pos.session'].browse(
pos_order['pos_session_id'])
currency_digits = pos_session.currency_id.decimal_places
card_journals = self.env['account.journal'].search([
('id', 'in', [p[2]['journal_id'] for p in payments]),
('payment_mode', '!=', False),
])
card_payments = [record[2] for record in payments
if record[2]['journal_id'] in card_journals.ids]
def amount_cents(obj):
if 'amount_cents' in obj:
return obj['amount_cents']
else:
return int(round(obj['amount'] * pow(10, currency_digits)))
try:
for payment, transaction in match(card_payments, transactions,
key=amount_cents):
payment['note'] = transaction['reference']
except ValueError as e:
_logger.error("Error matching transactions to payments: %s",
e.args[0])
def _process_order(self, pos_order):
if pos_order.get('transactions'):
self._match_transactions_to_payments(pos_order)
return super(PosOrder, self)._process_order(pos_order)
def group_by(lists, key):
count = range(len(lists))
d = defaultdict(lambda: tuple([[] for _ in count]))
for i, objects in enumerate(lists):
for obj in objects:
d[key(obj)][i].append(obj)
return d
def match(al, bl, key):
for key, groups in group_by((al, bl), key).items():
if groups[0] and len(groups[0]) != len(groups[1]):
raise ValueError("Missing value for {!r}".format(key))
for val in zip(*groups):
yield val

68
pos_payment_terminal/static/src/js/pos_payment_terminal.js

@ -20,9 +20,43 @@ odoo.define('pos_payment_terminal.pos_payment_terminal', function (require) {
models.load_fields('account.journal', ['payment_mode']);
devices.ProxyDevice.include({
init: function(parents, options) {
var self = this;
self._super(parents, options);
self.on('change:status', this, function(eh, status) {
if(!self.pos.chrome.screens) {
return;
}
var paymentwidget = self.pos.chrome.screens.payment;
var drivers = status.newValue.drivers;
var order = self.pos.get_order();
var in_transaction = false;
Object.keys(drivers).forEach(function(driver_name) {
if (drivers[driver_name].hasOwnProperty("in_transaction")) {
in_transaction = in_transaction || drivers[driver_name].in_transaction;
}
var transactions = drivers[driver_name].latest_transactions;
if(!!transactions && transactions.hasOwnProperty(order.uid)) {
var previous_transactions = order.transactions;
order.transactions = transactions[order.uid];
var has_new_transactions = (
!previous_transactions ||
previous_transactions.length < order.transactions.length
);
if(has_new_transactions && order.is_paid()) {
paymentwidget.validate_order();
}
}
});
order.in_transaction = in_transaction;
paymentwidget.order_changes();
});
},
payment_terminal_transaction_start: function(line_cid, currency_iso, currency_decimals){
var line;
var lines = this.pos.get_order().get_paymentlines();
var order = this.pos.get_order();
var lines = order.get_paymentlines();
for ( var i = 0; i < lines.length; i++ ) {
if (lines[i].cid === line_cid) {
line = lines[i];
@ -32,7 +66,8 @@ odoo.define('pos_payment_terminal.pos_payment_terminal', function (require) {
var data = {'amount' : line.get_amount(),
'currency_iso' : currency_iso,
'currency_decimals' : currency_decimals,
'payment_mode' : line.cashregister.journal.payment_mode};
'payment_mode' : line.cashregister.journal.payment_mode,
'order_id': order.uid};
//console.log(JSON.stringify(data));
this.message('payment_terminal_transaction_start', {'payment_info' : JSON.stringify(data)});
},
@ -41,13 +76,40 @@ odoo.define('pos_payment_terminal.pos_payment_terminal', function (require) {
screens.PaymentScreenWidget.include({
render_paymentlines : function(){
this._super.apply(this, arguments);
this._super.apply(this, arguments);
var self = this;
this.$('.paymentlines-container').unbind('click').on('click', '.payment-terminal-transaction-start', function(event){
// Why this "on" thing links severaltime the button to the action if I don't use "unlink" to reset the button links before ?
//console.log(event.target);
self.pos.get_order().in_transaction = true;
self.order_changes();
self.pos.proxy.payment_terminal_transaction_start($(this).data('cid'), self.pos.currency.name, self.pos.currency.decimals);
});
},
order_changes: function(){
this._super.apply(this, arguments);
var order = this.pos.get_order();
if (!order) {
return;
} else if (order.in_transaction) {
self.$('.next').html('<img src="/web/static/src/img/spin.png" style="animation: fa-spin 1s infinite steps(12);width: 20px;height: auto;vertical-align: middle;">');
} else {
self.$('.next').html('Validate <i class="fa fa-angle-double-right"></i>');
}
}
});
var _orderproto = models.Order.prototype;
models.Order = models.Order.extend({
initialize: function(){
_orderproto.initialize.apply(this, arguments);
this.in_transaction = false;
},
export_as_JSON: function() {
var vals = _orderproto.export_as_JSON.apply(this, arguments);
vals['transactions'] = this.transactions || {};
return vals;
}
});
});

1
pos_payment_terminal/tests/__init__.py

@ -0,0 +1 @@
from . import test_transactions

50
pos_payment_terminal/tests/test_transactions.py

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018-TODAY ACSONE SA/NV (<https://www.acsone.eu>).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.addons.point_of_sale.tests.common import TestPointOfSaleCommon
class TestTransactions(TestPointOfSaleCommon):
def test_matching(self):
card_journal_id = self.env['account.journal'].create({
'name': 'Card Journal',
'code': 'CARD',
'type': 'bank',
'payment_mode': 'card',
}).id
cash_journal_id = 0
pos_order = {
'pos_session_id': self.pos_order_session0.id,
'statement_ids': [
(0, 0, {
'name': 'Payment1',
'amount': 45.2,
'journal_id': card_journal_id,
}),
(0, 0, {
'name': 'Payment2',
'amount': 10.5,
'journal_id': card_journal_id,
}),
(0, 0, {
'name': 'Payment3',
'amount': 22.0,
'journal_id': cash_journal_id,
}),
],
'transactions': [
{
'reference': 'ABCDE',
'amount_cents': 1050,
},
{
'reference': 'XPTO',
'amount_cents': 4520,
},
]
}
self.env['pos.order']._match_transactions_to_payments(pos_order)
self.assertEquals(pos_order['statement_ids'][0][2]['note'], 'XPTO')
self.assertEquals(pos_order['statement_ids'][1][2]['note'], 'ABCDE')
Loading…
Cancel
Save