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