Browse Source
pos_payment_terminal: receive transaction refs
pos_payment_terminal: receive transaction refs
Provide a mechanism to send the order UID to the payment terminal, which can then pass the transaction reference generated by the payment provider back to Odoo, and which is then added to the order payment lines. This allows their subsequent reconciliation. The order is also automatically validated when the payment finishes.pull/389/head
andreparames
7 years ago
committed by
Denis Roussel
5 changed files with 147 additions and 2 deletions
-
1pos_payment_terminal/models/__init__.py
-
60pos_payment_terminal/models/pos_order.py
-
38pos_payment_terminal/static/src/js/pos_payment_terminal.js
-
1pos_payment_terminal/tests/__init__.py
-
49pos_payment_terminal/tests/test_transactions.py
@ -0,0 +1,60 @@ |
|||||
|
# -*- 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'] |
||||
|
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'] * 100)) |
||||
|
|
||||
|
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 |
@ -0,0 +1 @@ |
|||||
|
from . import test_transactions |
@ -0,0 +1,49 @@ |
|||||
|
# -*- 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). |
||||
|
|
||||
|
import odoo |
||||
|
|
||||
|
|
||||
|
class TestTransactions(odoo.tests.TransactionCase): |
||||
|
|
||||
|
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 = { |
||||
|
'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') |
Write
Preview
Loading…
Cancel
Save
Reference in new issue