# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models, _ from odoo.exceptions import ValidationError class AccountMove(models.Model): _inherit = 'account.move' transaction_ids = fields.Many2many('payment.transaction', 'account_invoice_transaction_rel', 'invoice_id', 'transaction_id', string='Transactions', copy=False, readonly=True) authorized_transaction_ids = fields.Many2many('payment.transaction', compute='_compute_authorized_transaction_ids', string='Authorized Transactions', copy=False, readonly=True) @api.depends('transaction_ids') def _compute_authorized_transaction_ids(self): for trans in self: trans.authorized_transaction_ids = trans.transaction_ids.filtered(lambda t: t.state == 'authorized') def get_portal_last_transaction(self): self.ensure_one() return self.with_context(active_test=False).transaction_ids.get_last_transaction() def _create_payment_transaction(self, vals): '''Similar to self.env['payment.transaction'].create(vals) but the values are filled with the current invoices fields (e.g. the partner or the currency). :param vals: The values to create a new payment.transaction. :return: The newly created payment.transaction record. ''' # Ensure the currencies are the same. currency = self[0].currency_id if any(inv.currency_id != currency for inv in self): raise ValidationError(_('A transaction can\'t be linked to invoices having different currencies.')) # Ensure the partner are the same. partner = self[0].partner_id if any(inv.partner_id != partner for inv in self): raise ValidationError(_('A transaction can\'t be linked to invoices having different partners.')) # Try to retrieve the acquirer. However, fallback to the token's acquirer. acquirer_id = vals.get('acquirer_id') acquirer = None payment_token_id = vals.get('payment_token_id') if payment_token_id: payment_token = self.env['payment.token'].sudo().browse(payment_token_id) # Check payment_token/acquirer matching or take the acquirer from token if acquirer_id: acquirer = self.env['payment.acquirer'].browse(acquirer_id) if payment_token and payment_token.acquirer_id != acquirer: raise ValidationError(_('Invalid token found! Token acquirer %s != %s') % ( payment_token.acquirer_id.name, acquirer.name)) if payment_token and payment_token.partner_id != partner: raise ValidationError(_('Invalid token found! Token partner %s != %s') % ( payment_token.partner.name, partner.name)) else: acquirer = payment_token.acquirer_id # Check an acquirer is there. if not acquirer_id and not acquirer: raise ValidationError(_('A payment acquirer is required to create a transaction.')) if not acquirer: acquirer = self.env['payment.acquirer'].browse(acquirer_id) # Check a journal is set on acquirer. if not acquirer.journal_id: raise ValidationError(_('A journal must be specified for the acquirer %s.', acquirer.name)) if not acquirer_id and acquirer: vals['acquirer_id'] = acquirer.id vals.update({ 'amount': sum(self.mapped('amount_residual')), 'currency_id': currency.id, 'partner_id': partner.id, 'invoice_ids': [(6, 0, self.ids)], }) transaction = self.env['payment.transaction'].create(vals) # Process directly if payment_token if transaction.payment_token_id: transaction.s2s_do_transaction() return transaction def payment_action_capture(self): self.authorized_transaction_ids.s2s_capture_transaction() def payment_action_void(self): self.authorized_transaction_ids.s2s_void_transaction()