1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
from odoo.tools import format_date, str2bool
from odoo.addons.payment import utils as payment_utils
class AccountMove(models.Model):
_inherit = 'account.move'
transaction_ids = fields.Many2many(
string="Transactions", comodel_name='payment.transaction',
relation='account_invoice_transaction_rel', column1='invoice_id', column2='transaction_id',
readonly=True, copy=False)
authorized_transaction_ids = fields.Many2many(
string="Authorized Transactions", comodel_name='payment.transaction',
compute='_compute_authorized_transaction_ids', readonly=True, copy=False,
compute_sudo=True)
transaction_count = fields.Integer(
string="Transaction Count", compute='_compute_transaction_count'
)
amount_paid = fields.Monetary(
string="Amount paid",
compute='_compute_amount_paid'
)
@api.depends('transaction_ids')
def _compute_authorized_transaction_ids(self):
for invoice in self:
invoice.authorized_transaction_ids = invoice.transaction_ids.filtered(
lambda tx: tx.state == 'authorized'
)
@api.depends('transaction_ids')
def _compute_transaction_count(self):
for invoice in self:
invoice.transaction_count = len(invoice.transaction_ids)
@api.depends('transaction_ids')
def _compute_amount_paid(self):
""" Sum all the transaction amount for which state is in 'authorized' or 'done'
"""
for invoice in self:
invoice.amount_paid = sum(
invoice.transaction_ids.filtered(
lambda tx: tx.state in ('authorized', 'done')
).mapped('amount')
)
def _has_to_be_paid(self):
self.ensure_one()
transactions = self.transaction_ids.filtered(lambda tx: tx.state in ('pending', 'authorized', 'done'))
pending_transactions = transactions.filtered(
lambda tx: tx.state in {'pending', 'authorized'}
and tx.provider_code not in {'none', 'custom'})
enabled_feature = str2bool(
self.env['ir.config_parameter'].sudo().get_param(
'account_payment.enable_portal_payment'
)
)
return enabled_feature and bool(
(self.amount_residual or not transactions)
and self.state == 'posted'
and self.payment_state in ('not_paid', 'in_payment', 'partial')
and not self.currency_id.is_zero(self.amount_residual)
and self.amount_total
and self.move_type == 'out_invoice'
and not pending_transactions
)
def get_portal_last_transaction(self):
self.ensure_one()
return self.with_context(active_test=False).transaction_ids.sudo()._get_last()
def payment_action_capture(self):
""" Capture all transactions linked to this invoice. """
self.ensure_one()
payment_utils.check_rights_on_recordset(self)
# In sudo mode to bypass the checks on the rights on the transactions.
return self.transaction_ids.sudo().action_capture()
def payment_action_void(self):
""" Void all transactions linked to this invoice. """
payment_utils.check_rights_on_recordset(self)
# In sudo mode to bypass the checks on the rights on the transactions.
self.authorized_transaction_ids.sudo().action_void()
def action_view_payment_transactions(self):
action = self.env['ir.actions.act_window']._for_xml_id('payment.action_payment_transaction')
if len(self.transaction_ids) == 1:
action['view_mode'] = 'form'
action['res_id'] = self.transaction_ids.id
action['views'] = []
else:
action['domain'] = [('id', 'in', self.transaction_ids.ids)]
return action
def _get_default_payment_link_values(self):
next_payment_values = self._get_invoice_next_payment_values()
amount_max = next_payment_values['amount_due']
additional_info = {}
open_installments = []
if next_payment_values['installment_state'] in ('next', 'overdue'):
open_installments = []
for installment in next_payment_values['not_reconciled_installments']:
data = {
'type': installment['type'],
'number': installment['number'],
'amount': installment['amount_residual_currency_unsigned'],
'date_maturity': format_date(self.env, installment['date_maturity']),
}
open_installments.append(data)
elif next_payment_values['installment_state'] == 'epd':
amount_max = next_payment_values['next_amount_to_pay'] # with epd, next_amount_to_pay is the invoice amount residual
additional_info.update({
'has_eligible_epd': True,
'discount_date': next_payment_values['discount_date']
})
return {
'currency_id': self.currency_id.id,
'partner_id': self.partner_id.id,
'open_installments': open_installments,
'installment_state': next_payment_values['installment_state'],
'amount': next_payment_values['next_amount_to_pay'],
'amount_max': amount_max,
**additional_info
}
|