[FIX] payment_{ogone,payulatam}: use the document name in the reference

Before this commit, the implementation of Ogone and PayU Latam's
requirements regarding the transaction reference was preventing the
computation of the reference prefix from being based on the related
document (invoice, SO).

This commit attempts to compute the reference based on the document if
no reference prefix is provided, before applying the said requirements.

task-2494916

closes odoo/odoo#72291

X-original-commit: f18a1d67b769ea69a07fb3c0343e092038df5c93
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
Antoine Vandevenne (anv)
2021-06-17 13:32:07 +00:00
parent 5813242fe0
commit 1f0a6167d6
6 changed files with 90 additions and 46 deletions
@@ -20,7 +20,7 @@ class PaymentTransaction(models.Model):
_inherit = 'payment.transaction'
@api.model
def _compute_reference(self, provider, prefix=None, **kwargs):
def _compute_reference(self, provider, prefix=None, separator='-', **kwargs):
""" Override of payment to ensure that Ogone requirements for references are satisfied.
Ogone requirements for references are as follows:
@@ -31,12 +31,20 @@ class PaymentTransaction(models.Model):
:param str provider: The provider of the acquirer handling the transaction
:param str prefix: The custom prefix used to compute the full reference
:param str separator: The custom separator used to separate the prefix from the suffix
:return: The unique reference for the transaction
:rtype: str
"""
if provider != 'ogone':
return super()._compute_reference(provider, prefix=prefix, **kwargs)
if not prefix:
# If no prefix is provided, it could mean that a module has passed a kwarg intended for
# the `_compute_reference_prefix` method, as it is only called if the prefix is empty.
# We call it manually here because singularizing the prefix would generate a default
# value if it was empty, hence preventing the method from ever being called and the
# transaction from received a reference named after the related document.
prefix = self.sudo()._compute_reference_prefix(provider, separator, **kwargs) or None
prefix = payment_utils.singularize_reference_prefix(prefix=prefix, max_length=40)
return super()._compute_reference(provider, prefix=prefix, **kwargs)
+1
View File
@@ -1,4 +1,5 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.payment.tests.common import PaymentCommon
+31 -19
View File
@@ -2,6 +2,7 @@
from freezegun import freeze_time
from odoo.fields import Command
from odoo.tests import tagged
from odoo.tools import mute_logger
@@ -15,32 +16,45 @@ from ..controllers.main import OgoneController
class OgoneTest(OgoneCommon):
def test_validation_amount(self):
""" Test the value of the validation amount. """
self.assertEqual(self.ogone._get_validation_amount(), 1.0)
# freeze time for consistent singularize_prefix behavior during the test
@freeze_time("2011-11-02 12:00:21")
def test_reference(self):
tx = self.create_transaction(flow="redirect", reference="")
self.assertEqual(tx.reference, "tx-20111102120021",
"Ogone: transaction reference wasn't correctly singularized.")
# Test prefixes of length > 40 chars
reference = self.env['payment.transaction']._compute_reference(
provider=self.ogone.provider,
prefix="This is a reference of more than 40 characters to annoy ogone",
@freeze_time('2011-11-02 12:00:21') # Freeze time for consistent singularization behavior
def test_reference_is_singularized(self):
""" Test singularization of reference prefixes. """
reference = self.env['payment.transaction']._compute_reference(self.ogone.provider)
self.assertEqual(
reference, 'tx-20111102120021', "transaction reference was not correctly singularized"
)
self.assertEqual(reference, "This is a reference of mo-20111102120021")
@freeze_time('2011-11-02 12:00:21') # Freeze time for consistent singularization behavior
def test_reference_is_stripped_at_max_length(self):
""" Test stripping of reference prefixes of length > 40 chars. """
reference = self.env['payment.transaction']._compute_reference(
self.ogone.provider,
prefix='this is a reference of more than 40 characters to annoy ogone',
)
self.assertEqual(reference, 'this is a reference of mo-20111102120021')
self.assertEqual(len(reference), 40)
# freeze time for consistent singularize_prefix behavior during the test
@freeze_time("2011-11-02 12:00:21")
@freeze_time('2011-11-02 12:00:21') # Freeze time for consistent singularization behavior
def test_reference_is_computed_based_on_document_name(self):
""" Test computation of reference prefixes based on the provided invoice. """
invoice = self.env['account.move'].create({})
reference = self.env['payment.transaction']._compute_reference(
self.ogone.provider, invoice_ids=[Command.set([invoice.id])]
)
self.assertEqual(reference, 'MISC/2011/11/0001-20111102120021')
@freeze_time('2011-11-02 12:00:21') # Freeze time for consistent singularization behavior
def test_redirect_form_values(self):
""" Test the values of the redirect form inputs. """
return_url = self._build_url(OgoneController._flexcheckout_return_url)
expected_values = {
'ACCOUNT_PSPID': self.ogone.ogone_pspid,
'ALIAS_ALIASID': payment_utils.singularize_reference_prefix(prefix='ODOO-ALIAS'),
'ALIAS_ORDERID': self.reference,
'ALIAS_STOREPERMANENTLY': 'N', # 'Y' if self.tokenize
'ALIAS_STOREPERMANENTLY': 'N', # 'Y' if self.tokenize
'CARD_PAYMENTMETHOD': 'CreditCard',
'LAYOUT_LANGUAGE': self.partner.lang,
'PARAMETERS_ACCEPTURL': return_url,
@@ -50,7 +64,7 @@ class OgoneTest(OgoneCommon):
expected_values, incoming=False, format_keys=True
).upper()
tx = self.create_transaction(flow="redirect")
tx = self.create_transaction(flow='redirect')
with mute_logger('odoo.addons.payment.models.payment_transaction'):
processing_values = tx._get_processing_values()
@@ -64,7 +78,5 @@ class OgoneTest(OgoneCommon):
self.assertEqual(
inputs[form_key],
value,
"Ogone: received value %s for input %s (expected %s)" % (
inputs[form_key], form_key, value,
)
f"received value {inputs[form_key]} for input {form_key} (expected {value})"
)
@@ -34,6 +34,15 @@ class PaymentTransaction(models.Model):
:rtype: str
"""
if provider == 'payulatam':
if not prefix:
# If no prefix is provided, it could mean that a module has passed a kwarg intended
# for the `_compute_reference_prefix` method, as it is only called if the prefix is
# empty. We call it manually here because singularizing the prefix would generate a
# default value if it was empty, hence preventing the method from ever being called
# and the transaction from received a reference named after the related document.
prefix = self.sudo()._compute_reference_prefix(
provider, separator, **kwargs
) or None
prefix = payment_utils.singularize_reference_prefix(prefix=prefix, separator=separator)
return super()._compute_reference(provider, prefix=prefix, separator=separator, **kwargs)
+2 -1
View File
@@ -1,8 +1,9 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.payment.tests.common import PaymentCommon
class PayulatamCommon(PaymentCommon):
class PayULatamCommon(PaymentCommon):
@classmethod
def setUpClass(cls, chart_template_ref=None):
@@ -3,42 +3,53 @@
from freezegun import freeze_time
from odoo.exceptions import ValidationError
from odoo.fields import Command
from odoo.tests import tagged
from odoo.tools import mute_logger
from .common import PayulatamCommon
from .common import PayULatamCommon
from ..controllers.main import PayuLatamController
from ..models.payment_acquirer import SUPPORTED_CURRENCIES
@tagged('post_install', '-at_install')
class PayUlatamTest(PayulatamCommon):
class PayULatamTest(PayULatamCommon):
def test_compatible_acquirers(self):
for curr in SUPPORTED_CURRENCIES:
currency = self._prepare_currency(curr)
acquirers = self.env['payment.acquirer']._get_compatible_acquirers(
partner_id=self.partner.id,
company_id=self.company.id,
currency_id=currency.id,
def test_compatibility_with_supported_currencies(self):
""" Test that the PayULatam acquirer is compatible with all supported currencies. """
for supported_currency_code in SUPPORTED_CURRENCIES:
supported_currency = self._prepare_currency(supported_currency_code)
compatible_acquirers = self.env['payment.acquirer']._get_compatible_acquirers(
self.company.id, self.partner.id, currency_id=supported_currency.id,
)
self.assertIn(self.payulatam, acquirers)
self.assertIn(self.payulatam, compatible_acquirers)
acquirers = self.env['payment.acquirer']._get_compatible_acquirers(
partner_id=self.partner.id,
company_id=self.company.id,
currency_id=self.currency_euro.id,
def test_incompatibility_with_unsupported_currency(self):
""" Test that the PayULatam acquirer is not compatible with an unsupported currency. """
compatible_acquirers = self.env['payment.acquirer']._get_compatible_acquirers(
self.company.id, self.partner.id, currency_id=self.currency_euro.id,
)
self.assertNotIn(self.payulatam, acquirers)
self.assertNotIn(self.payulatam, compatible_acquirers)
# freeze time for consistent singularize_prefix behavior during the test
@freeze_time("2011-11-02 12:00:21")
def test_reference(self):
tx = self.create_transaction(flow="redirect", reference="")
self.assertEqual(tx.reference, "tx-20111102120021",
"Payulatam: transaction reference wasn't correctly singularized.")
@freeze_time('2011-11-02 12:00:21') # Freeze time for consistent singularization behavior
def test_reference_is_singularized(self):
""" Test singularization of reference prefixes. """
reference = self.env['payment.transaction']._compute_reference(self.payulatam.provider)
self.assertEqual(
reference, 'tx-20111102120021', "transaction reference was not correctly singularized"
)
@freeze_time('2011-11-02 12:00:21') # Freeze time for consistent singularization behavior
def test_reference_is_computed_based_on_document_name(self):
""" Test computation of reference prefixes based on the provided invoice. """
invoice = self.env['account.move'].create({})
reference = self.env['payment.transaction']._compute_reference(
self.payulatam.provider, invoice_ids=[Command.set([invoice.id])]
)
self.assertEqual(reference, 'MISC/2011/11/0001-20111102120021')
def test_redirect_form_values(self):
""" Test the values of the redirect form inputs. """
tx = self.create_transaction(flow='redirect')
with mute_logger('odoo.addons.payment.models.payment_transaction'):
processing_values = tx._get_processing_values()
@@ -56,13 +67,15 @@ class PayUlatamTest(PayulatamCommon):
'buyerEmail': self.partner.email,
'buyerFullName': self.partner.name,
'responseUrl': self._build_url(PayuLatamController._return_url),
'test': str(1), # test is always done in test mode.
'test': str(1), # testing is always performed in test mode
}
expected_values['signature'] = self.payulatam._payulatam_generate_sign(
expected_values, incoming=False)
expected_values, incoming=False
)
self.assertEqual(form_info['action'],
'https://sandbox.checkout.payulatam.com/ppp-web-gateway-payu/')
self.assertEqual(
form_info['action'], 'https://sandbox.checkout.payulatam.com/ppp-web-gateway-payu/'
)
self.assertDictEqual(form_info['inputs'], expected_values)
def test_feedback_processing(self):