[FIX] account, payment: Various fixes for account payments/method lines

There is an issue when computing the suitable payment token ids making it impossible to
open a payment for a user without access to payment acquirers.

Also, the default computation of payment token was wrong and would never set it
correctly.

The compute for the method lines in payment would not filter unavailable acquirers
line and thus select them by default if they were first in line.

Also fix an issue with the ordering of payment method lines

X-original-commit: 73410a0fd76a70e1730883d35b79fc603741b59c
This commit is contained in:
Nicolas (vin)
2021-07-19 15:17:32 +00:00
parent bc25b371ef
commit 9e432ed243
6 changed files with 50 additions and 28 deletions
+4 -7
View File
@@ -383,16 +383,13 @@ class AccountPayment(models.Model):
This field is not computed in '_compute_payment_method_fields' because it's a stored editable one.
'''
for pay in self:
if pay.payment_type == 'inbound':
available_payment_methods = pay.journal_id.inbound_payment_method_line_ids
else:
available_payment_methods = pay.journal_id.outbound_payment_method_line_ids
available_payment_method_lines = pay.journal_id._get_available_payment_method_lines(pay.payment_type)
# Select the first available one by default.
if pay.payment_method_line_id in available_payment_methods:
if pay.payment_method_line_id in available_payment_method_lines:
pay.payment_method_line_id = pay.payment_method_line_id
elif available_payment_methods:
pay.payment_method_line_id = available_payment_methods[0]._origin
elif available_payment_method_lines:
pay.payment_method_line_id = available_payment_method_lines[0]._origin
else:
pay.payment_method_line_id = False
@@ -304,14 +304,11 @@ class AccountPaymentRegister(models.TransientModel):
@api.depends('payment_type', 'journal_id')
def _compute_payment_method_line_id(self):
for wizard in self:
if wizard.payment_type == 'inbound':
available_payment_methods = wizard.journal_id.inbound_payment_method_line_ids
else:
available_payment_methods = wizard.journal_id.outbound_payment_method_line_ids
available_payment_method_lines = wizard.journal_id._get_available_payment_method_lines(wizard.payment_type)
# Select the first available one by default.
if available_payment_methods:
wizard.payment_method_line_id = available_payment_methods[0]._origin
if available_payment_method_lines:
wizard.payment_method_line_id = available_payment_method_lines[0]._origin
else:
wizard.payment_method_line_id = False
+1 -1
View File
@@ -24,7 +24,7 @@ class AccountJournal(models.Model):
SELECT acquirer.id
FROM payment_acquirer acquirer
JOIN account_payment_method apm ON apm.code = acquirer.provider
LEFT JOIN account_payment_method_line apml ON apm.id = apml.payment_method_id
LEFT JOIN account_payment_method_line apml ON apm.id = apml.payment_method_id AND apml.journal_id IS NOT NULL
WHERE acquirer.state IN ('enabled', 'test') AND apm.payment_type = 'inbound'
AND apml.id IS NULL
AND acquirer.company_id IN %(company_ids)s
+17 -7
View File
@@ -36,11 +36,12 @@ class AccountPayment(models.Model):
)._origin
if payment.use_electronic_payment_method:
payment.suitable_payment_token_ids = self.env['payment.token'].search([
payment.suitable_payment_token_ids = self.env['payment.token'].sudo().search([
('company_id', '=', payment.company_id.id),
('acquirer_id.capture_manually', '=', False),
('partner_id', 'in', related_partner_ids.ids),
]).filtered(lambda t: t.acquirer_id.journal_id == payment.journal_id.id)
('acquirer_id.journal_id', '=', payment.journal_id.id),
])
else:
payment.suitable_payment_token_ids = [Command.clear()]
@@ -50,17 +51,24 @@ class AccountPayment(models.Model):
# Get a list of all electronic payment method codes.
# These codes are comprised of 'electronic' and the providers of each payment acquirer.
codes = [key for key in dict(self.env['payment.acquirer']._fields['provider']._description_selection(self.env))]
codes.append('electronic')
payment.use_electronic_payment_method = payment.payment_method_code in codes
@api.onchange('partner_id', 'payment_method_line_id', 'journal_id')
def _onchange_set_payment_token_id(self):
if not (self.payment_method_code == 'electronic' and self.partner_id and self.journal_id):
codes = [key for key in dict(self.env['payment.acquirer']._fields['provider']._description_selection(self.env))]
if not (self.payment_method_code in codes and self.partner_id and self.journal_id):
self.payment_token_id = False
return
self.payment_token_id = self.env['payment.token'].search([
('partner_id', 'in', self.related_partner_ids.ids),
related_partner_ids = (
self.partner_id
| self.partner_id.commercial_partner_id
| self.partner_id.commercial_partner_id.child_ids
)._origin
self.payment_token_id = self.env['payment.token'].sudo().search([
('company_id', '=', self.company_id.id),
('partner_id', 'in', related_partner_ids.ids),
('acquirer_id.capture_manually', '=', False),
('acquirer_id.journal_id', '=', self.journal_id.id),
], limit=1)
@@ -108,7 +116,9 @@ class AccountPayment(models.Model):
payments_need_tx = self.filtered(
lambda p: p.payment_token_id and not p.payment_transaction_id
)
transactions = payments_need_tx._create_payment_transaction()
# creating the transaction require to access data on payment acquirers, not always accessible to users
# able to create payments
transactions = payments_need_tx.sudo()._create_payment_transaction()
res = super(AccountPayment, self - payments_need_tx).action_post()
@@ -23,7 +23,16 @@ class AccountPaymentMethodLine(models.Model):
('provider', 'in', self.mapped('code')),
('company_id', 'in', self.journal_id.company_id.ids),
])
acquirers_map = {(x.provider, x.company_id): x for x in acquirers}
# Make sure to pick the active acquirer, if any.
acquirers_map = dict()
for acquirer in acquirers:
current_value = acquirers_map.get((acquirer.provider, acquirer.company_id), False)
if current_value and current_value.state != 'disabled':
continue
acquirers_map[(acquirer.provider, acquirer.company_id)] = acquirer
for line in self:
code = line.payment_method_id.code
company = line.journal_id.company_id
@@ -42,11 +42,12 @@ class AccountPaymentRegister(models.TransientModel):
| wizard.partner_id.commercial_partner_id.child_ids
)._origin
wizard.suitable_payment_token_ids = self.env['payment.token'].search([
wizard.suitable_payment_token_ids = self.env['payment.token'].sudo().search([
('company_id', '=', wizard.company_id.id),
('acquirer_id.capture_manually', '=', False),
('partner_id', 'in', related_partner_ids.ids),
]).filtered(lambda t: t.acquirer_id.journal_id == wizard.journal_id.id)
('acquirer_id.journal_id', '=', wizard.journal_id.id),
])
else:
wizard.suitable_payment_token_ids = [Command.clear()]
@@ -60,13 +61,21 @@ class AccountPaymentRegister(models.TransientModel):
@api.onchange('can_edit_wizard', 'payment_method_line_id', 'journal_id')
def _compute_payment_token_id(self):
codes = [key for key in dict(self.env['payment.acquirer']._fields['provider']._description_selection(self.env))]
for wizard in self:
related_partner_ids = (
wizard.partner_id
| wizard.partner_id.commercial_partner_id
| wizard.partner_id.commercial_partner_id.child_ids
)._origin
if wizard.can_edit_wizard \
and wizard.payment_method_line_id.code == 'electronic' \
and wizard.payment_method_line_id.code in codes \
and wizard.journal_id \
and wizard.suitable_payment_token_partner_ids:
wizard.payment_token_id = self.env['payment.token'].search([
('partner_id', 'in', wizard.suitable_payment_token_partner_ids.ids),
and related_partner_ids:
wizard.payment_token_id = self.env['payment.token'].sudo().search([
('company_id', '=', wizard.company_id.id),
('partner_id', 'in', related_partner_ids.ids),
('acquirer_id.capture_manually', '=', False),
('acquirer_id.journal_id', '=', wizard.journal_id.id),
], limit=1)