You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
2.1 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2018 ACSONE SA/NV
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  4. from collections import defaultdict
  5. import logging
  6. from odoo import models, api
  7. _logger = logging.getLogger(__name__)
  8. class PosOrder(models.Model):
  9. _inherit = 'pos.order'
  10. @api.model
  11. def _match_transactions_to_payments(self, pos_order):
  12. payments = pos_order['statement_ids']
  13. transactions = pos_order['transactions']
  14. pos_session = self.env['pos.session'].browse(
  15. pos_order['pos_session_id'])
  16. currency_digits = pos_session.currency_id.decimal_places
  17. card_journals = self.env['account.journal'].search([
  18. ('id', 'in', [p[2]['journal_id'] for p in payments]),
  19. ('payment_mode', '!=', False),
  20. ])
  21. card_payments = [record[2] for record in payments
  22. if record[2]['journal_id'] in card_journals.ids]
  23. def amount_cents(obj):
  24. if 'amount_cents' in obj:
  25. return obj['amount_cents']
  26. else:
  27. return int(round(obj['amount'] * pow(10, currency_digits)))
  28. try:
  29. for payment, transaction in match(card_payments, transactions,
  30. key=amount_cents):
  31. payment['note'] = transaction['reference']
  32. except ValueError as e:
  33. _logger.error("Error matching transactions to payments: %s",
  34. e.args[0])
  35. def _process_order(self, pos_order):
  36. if pos_order.get('transactions'):
  37. self._match_transactions_to_payments(pos_order)
  38. return super(PosOrder, self)._process_order(pos_order)
  39. def group_by(lists, key):
  40. count = range(len(lists))
  41. d = defaultdict(lambda: tuple([[] for _ in count]))
  42. for i, objects in enumerate(lists):
  43. for obj in objects:
  44. d[key(obj)][i].append(obj)
  45. return d
  46. def match(al, bl, key):
  47. for key, groups in group_by((al, bl), key).items():
  48. if groups[0] and len(groups[0]) != len(groups[1]):
  49. raise ValueError("Missing value for {!r}".format(key))
  50. for val in zip(*groups):
  51. yield val