diff --git a/addons/account_payment/models/payment_provider.py b/addons/account_payment/models/payment_provider.py
index fad7ef33640..e218fa9990b 100644
--- a/addons/account_payment/models/payment_provider.py
+++ b/addons/account_payment/models/payment_provider.py
@@ -3,7 +3,7 @@
from odoo import api, fields, models
-class Paymentprovider(models.Model):
+class PaymentProvider(models.Model):
_inherit = 'payment.provider'
journal_id = fields.Many2one(
diff --git a/addons/payment/models/payment_provider.py b/addons/payment/models/payment_provider.py
index 1b6aa7595a3..e2128ca620c 100644
--- a/addons/payment/models/payment_provider.py
+++ b/addons/payment/models/payment_provider.py
@@ -102,6 +102,19 @@ class PaymentProvider(models.Model):
column1='payment_id',
column2='country_id',
)
+ available_currency_ids = fields.Many2many(
+ string="Currencies",
+ help="The currencies available with this payment provider. Leave empty not to restrict "
+ "any.",
+ comodel_name='res.currency',
+ relation='payment_currency_rel',
+ column1="payment_provider_id",
+ column2="currency_id",
+ compute='_compute_available_currency_ids',
+ store=True,
+ readonly=False,
+ context={'active_test': False},
+ )
maximum_amount = fields.Monetary(
string="Maximum Amount",
help="The maximum payment amount that this payment provider is available for. Leave blank "
@@ -190,6 +203,22 @@ class PaymentProvider(models.Model):
#=== COMPUTE METHODS ===#
+ @api.depends('code')
+ def _compute_available_currency_ids(self):
+ """ Compute the available currencies based on their support by the providers.
+
+ If the provider does not filter out any currency, the field is left empty for UX reasons.
+
+ :return: None
+ """
+ all_currencies = self.env['res.currency'].with_context(active_test=False).search([])
+ for provider in self:
+ supported_currencies = provider._get_supported_currencies()
+ if supported_currencies < all_currencies: # Some currencies have been filtered out.
+ provider.available_currency_ids = supported_currencies
+ else:
+ provider.available_currency_ids = None
+
@api.depends('state', 'module_state')
def _compute_color(self):
""" Update the color of the kanban card based on the state of the provider.
@@ -242,6 +271,7 @@ class PaymentProvider(models.Model):
'show_cancel_msg': True,
})
+ @api.depends('code')
def _compute_feature_support_fields(self):
""" Compute the feature support fields based on the provider.
@@ -415,8 +445,8 @@ class PaymentProvider(models.Model):
""" Select and return the providers matching the criteria.
The criteria are that providers must not be disabled, be in the company that is provided,
- and support the country of the partner if it exists. The criteria can be further refined
- by providing the keyword arguments.
+ support the country of the partner if it exists, and be compatible with the currency if
+ provided. The criteria can be further refined by providing the keyword arguments.
:param int company_id: The company to which providers must belong, as a `res.company` id.
:param int partner_id: The partner making the payment, as a `res.partner` id.
@@ -462,6 +492,16 @@ class PaymentProvider(models.Model):
]
])
+ # Handle the available currencies (only if supported currencies list is not empty).
+ if currency:
+ domain = expression.AND([
+ domain, [
+ '|',
+ ('available_currency_ids', '=', False),
+ ('available_currency_ids', 'in', [currency.id]),
+ ]
+ ])
+
# Handle tokenization support requirements.
if force_tokenization or self._is_tokenization_required(**kwargs):
domain = expression.AND([domain, [('allow_tokenization', '=', True)]])
@@ -473,6 +513,21 @@ class PaymentProvider(models.Model):
compatible_providers = self.env['payment.provider'].search(domain)
return compatible_providers
+ def _get_supported_currencies(self):
+ """ Return the supported currencies for the payment provider.
+
+ By default, all currencies are considered supported, including the inactive ones. For a
+ provider to filter out specific currencies, it must override this method and return the
+ subset of supported currencies.
+
+ Note: `self.ensure_one()`
+
+ :return: The supported currencies.
+ :rtype: res.currency
+ """
+ self.ensure_one()
+ return self.env['res.currency'].with_context(active_test=False).search([])
+
def _is_tokenization_required(self, **kwargs):
""" Return whether tokenizing the transaction is required given its context.
diff --git a/addons/payment/tests/common.py b/addons/payment/tests/common.py
index 44e3deaa405..6e92dc5ffc6 100644
--- a/addons/payment/tests/common.py
+++ b/addons/payment/tests/common.py
@@ -79,6 +79,7 @@ class PaymentCommon(BaseCommon):
'is_published': True,
'allow_tokenization': True,
'redirect_form_view_id': redirect_form.id,
+ 'available_currency_ids': [Command.set((cls.currency_euro + cls.currency_usd).ids)],
})
cls.provider = cls.dummy_provider
diff --git a/addons/payment/tests/test_payment_provider.py b/addons/payment/tests/test_payment_provider.py
index cd0233ef68f..614ce799b25 100644
--- a/addons/payment/tests/test_payment_provider.py
+++ b/addons/payment/tests/test_payment_provider.py
@@ -2,6 +2,7 @@
from unittest.mock import patch
+from odoo import Command
from odoo.tests import tagged
from odoo.addons.payment.tests.common import PaymentCommon
@@ -70,6 +71,30 @@ class TestPaymentProvider(PaymentCommon):
)
self.assertNotIn(self.provider, compatible_providers)
+ def test_provider_compatible_with_available_currencies(self):
+ """ Test that the provider is compatible with its available currencies. """
+ compatible_providers = self.provider._get_compatible_providers(
+ self.company.id, self.partner.id, self.amount, currency_id=self.currency_euro.id
+ )
+ self.assertIn(self.provider, compatible_providers)
+
+ def test_provider_not_compatible_with_unavailable_currencies(self):
+ """ Test that the provider is not compatible with a currency that is not available. """
+ # Make sure the list of available currencies is not empty.
+ self.provider.available_currency_ids = [Command.unlink(self.currency_usd.id)]
+ compatible_providers = self.provider._get_compatible_providers(
+ self.company.id, self.partner.id, self.amount, currency_id=self.currency_usd.id
+ )
+ self.assertNotIn(self.provider, compatible_providers)
+
+ def test_provider_compatible_when_no_available_currency_set(self):
+ """ Test that the provider is always compatible when no available currency is set. """
+ self.provider.available_currency_ids = [Command.clear()]
+ compatible_providers = self.provider._get_compatible_providers(
+ self.company.id, self.partner.id, self.amount, currency_id=self.currency_euro.id
+ )
+ self.assertIn(self.provider, compatible_providers)
+
def test_fees_null_when_deactivated(self):
""" Test that extra fees of a provider are null if these fees are deactivated. """
self.provider.write({
diff --git a/addons/payment/views/payment_provider_views.xml b/addons/payment/views/payment_provider_views.xml
index 25a1668d094..4adf8766460 100644
--- a/addons/payment/views/payment_provider_views.xml
+++ b/addons/payment/views/payment_provider_views.xml
@@ -84,10 +84,19 @@
+
+
+
+
+
+ options="{'no_create': True}"/>
diff --git a/addons/payment_alipay/models/payment_provider.py b/addons/payment_alipay/models/payment_provider.py
index 6af246c92b2..507c0e6ff08 100644
--- a/addons/payment_alipay/models/payment_provider.py
+++ b/addons/payment_alipay/models/payment_provider.py
@@ -41,7 +41,8 @@ class PaymentProvider(models.Model):
@api.model
def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of payment to unlist Alipay providers for unsupported currencies. """
+ """ Override of payment to unlist Alipay providers when the currency is not CNY in case of
+ express checkout. """
providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
currency = self.env['res.currency'].browse(currency_id).exists()
diff --git a/addons/payment_asiapay/data/neutralize.sql b/addons/payment_asiapay/data/neutralize.sql
index e9674ac07ec..8c5a2229a45 100644
--- a/addons/payment_asiapay/data/neutralize.sql
+++ b/addons/payment_asiapay/data/neutralize.sql
@@ -1,6 +1,5 @@
-- disable asiapay payment provider
UPDATE payment_provider
SET asiapay_merchant_id = NULL,
- asiapay_currency_id = NULL,
asiapay_secure_hash_secret = NULL,
asiapay_secure_hash_function = NULL;
diff --git a/addons/payment_asiapay/models/payment_provider.py b/addons/payment_asiapay/models/payment_provider.py
index 8537df4cb1e..a4373be2584 100644
--- a/addons/payment_asiapay/models/payment_provider.py
+++ b/addons/payment_asiapay/models/payment_provider.py
@@ -2,7 +2,8 @@
from hashlib import new as hashnew
-from odoo import api, fields, models
+from odoo import _, api, fields, models
+from odoo.exceptions import ValidationError
from odoo.addons.payment_asiapay import const
@@ -10,10 +11,6 @@ from odoo.addons.payment_asiapay import const
class PaymentProvider(models.Model):
_inherit = 'payment.provider'
- def _domain_asiapay_currency_id(self):
- currency_xmlids = [f'base.{key}' for key in const.CURRENCY_MAPPING]
- return [('id', 'in', [self.env.ref(xmlid).id for xmlid in currency_xmlids])]
-
code = fields.Selection(
selection_add=[('asiapay', "AsiaPay")], ondelete={'asiapay': 'set default'}
)
@@ -22,13 +19,6 @@ class PaymentProvider(models.Model):
help="The Merchant ID solely used to identify your AsiaPay account.",
required_if_provider='asiapay',
)
- asiapay_currency_id = fields.Many2one(
- string="AsiaPay Currency",
- help="The currency associated to your AsiaPay account.",
- comodel_name='res.currency',
- domain=_domain_asiapay_currency_id,
- required_if_provider='asiapay',
- )
asiapay_secure_hash_secret = fields.Char(
string="AsiaPay Secure Hash Secret",
required_if_provider='asiapay',
@@ -42,21 +32,16 @@ class PaymentProvider(models.Model):
required_if_provider='asiapay',
)
+ # ==== CONSTRAINT METHODS ===#
+
+ @api.constrains('available_currency_ids', 'state')
+ def _limit_available_currency_ids(self):
+ for provider in self.filtered(lambda p: p.code == 'asiapay'):
+ if len(provider.available_currency_ids) > 1 and provider.state != 'disabled':
+ raise ValidationError(_("Only one currency can be selected by AsiaPay account."))
+
# === BUSINESS METHODS ===#
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of `payment` to filter out AsiaPay providers for unsupported currencies. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency:
- providers = providers.filtered(
- lambda p: p.code != 'asiapay' or currency == p.asiapay_currency_id
- )
-
- return providers
-
def _asiapay_get_api_url(self):
""" Return the URL of the API corresponding to the provider's state.
diff --git a/addons/payment_asiapay/models/payment_transaction.py b/addons/payment_asiapay/models/payment_transaction.py
index b5a2e1e6faa..7aa6728ff18 100644
--- a/addons/payment_asiapay/models/payment_transaction.py
+++ b/addons/payment_asiapay/models/payment_transaction.py
@@ -88,7 +88,7 @@ class PaymentTransaction(models.Model):
'merchant_id': self.provider_id.asiapay_merchant_id,
'amount': self.amount,
'reference': self.reference,
- 'currency_code': const.CURRENCY_MAPPING[self.provider_id.asiapay_currency_id.name],
+ 'currency_code': const.CURRENCY_MAPPING[self.provider_id.available_currency_ids[0].name],
'mps_mode': 'SCP',
'return_url': urls.url_join(base_url, AsiaPayController._return_url),
'payment_type': 'N',
diff --git a/addons/payment_asiapay/tests/common.py b/addons/payment_asiapay/tests/common.py
index a0a3b777d6e..75e6582cc2f 100644
--- a/addons/payment_asiapay/tests/common.py
+++ b/addons/payment_asiapay/tests/common.py
@@ -1,5 +1,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo import Command
+
from odoo.addons.payment.tests.common import PaymentCommon
@@ -11,9 +13,9 @@ class AsiaPayCommon(PaymentCommon):
cls.asiapay = cls._prepare_provider('asiapay', update_values={
'asiapay_merchant_id': '123456789',
- 'asiapay_currency_id': cls.currency_euro,
'asiapay_secure_hash_secret': 'coincoin_motherducker',
'asiapay_secure_hash_function': 'sha1',
+ 'available_currency_ids': [Command.set(cls.currency_euro.ids)],
})
cls.provider = cls.asiapay
diff --git a/addons/payment_asiapay/views/payment_provider_views.xml b/addons/payment_asiapay/views/payment_provider_views.xml
index 4606b82b2d1..be784509ab0 100644
--- a/addons/payment_asiapay/views/payment_provider_views.xml
+++ b/addons/payment_asiapay/views/payment_provider_views.xml
@@ -11,9 +11,6 @@
-
+
+ {'required': [('code', '=', 'asiapay'), ('state', '!=', 'disabled')]}
+
diff --git a/addons/payment_authorize/models/payment_provider.py b/addons/payment_authorize/models/payment_provider.py
index 2b4e3363abc..d0934cf9f34 100644
--- a/addons/payment_authorize/models/payment_provider.py
+++ b/addons/payment_authorize/models/payment_provider.py
@@ -27,10 +27,6 @@ class PaymentProvider(models.Model):
authorize_client_key = fields.Char(
string="API Client Key",
help="The public client key. To generate directly from Odoo or from Authorize.Net backend.")
- # Authorize.Net supports only one currency: "One gateway account is required for each currency"
- # See https://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/Authorize-Net-UK-Europe-Update/ba-p/35957
- authorize_currency_id = fields.Many2one(
- string="Authorize Currency", comodel_name='res.currency')
authorize_payment_method_type = fields.Selection(
string="Allow Payments From",
help="Determines with what payment method the customer can pay.",
@@ -51,6 +47,16 @@ class PaymentProvider(models.Model):
"method type on the duplicated provider."
))
+ # Authorize.Net supports only one currency: "One gateway account is required for each currency"
+ # See https://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/Authorize-Net-UK-Europe-Update/ba-p/35957
+ @api.constrains('available_currency_ids', 'state')
+ def _limit_available_currency_ids(self):
+ for provider in self.filtered(lambda p: p.code == 'authorize'):
+ if len(provider.available_currency_ids) > 1 and provider.state != 'disabled':
+ raise ValidationError(
+ _("Only one currency can be selected by Authorize.Net account.")
+ )
+
#=== COMPUTE METHODS ===#
def _compute_feature_support_fields(self):
@@ -104,24 +110,11 @@ class PaymentProvider(models.Model):
raise UserError(_("Could not fetch merchant details:\n%s", res_content['err_msg']))
currency = self.env['res.currency'].search([('name', 'in', res_content.get('currencies'))])
- self.authorize_currency_id = currency
+ self.available_currency_ids = [Command.set(currency.ids)]
self.authorize_client_key = res_content.get('publicClientKey')
# === BUSINESS METHODS ===#
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of payment to unlist Authorize providers for unsupported currencies. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency:
- providers = providers.filtered(
- lambda p: p.code != 'authorize' or currency == p.authorize_currency_id
- )
-
- return providers
-
def _get_validation_amount(self):
""" Override of payment to return the amount for Authorize.Net validation operations.
@@ -144,4 +137,4 @@ class PaymentProvider(models.Model):
if self.code != 'authorize':
return res
- return self.authorize_currency_id
+ return self.available_currency_ids[0]
diff --git a/addons/payment_authorize/tests/common.py b/addons/payment_authorize/tests/common.py
index 152deef461e..db06872a653 100644
--- a/addons/payment_authorize/tests/common.py
+++ b/addons/payment_authorize/tests/common.py
@@ -1,5 +1,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo.fields import Command
+
from odoo.addons.payment.tests.common import PaymentCommon
@@ -13,7 +15,7 @@ class AuthorizeCommon(PaymentCommon):
'authorize_login': 'dummy',
'authorize_transaction_key': 'dummy',
'authorize_signature_key': '00000000',
- 'authorize_currency_id': cls.currency_usd.id,
+ 'available_currency_ids': [Command.set(cls.currency_usd.ids)]
})
cls.provider = cls.authorize
diff --git a/addons/payment_authorize/tests/test_authorize.py b/addons/payment_authorize/tests/test_authorize.py
index 54dc046daf0..e0d0fb382d0 100644
--- a/addons/payment_authorize/tests/test_authorize.py
+++ b/addons/payment_authorize/tests/test_authorize.py
@@ -14,7 +14,7 @@ from .common import AuthorizeCommon
class AuthorizeTest(AuthorizeCommon):
def test_compatible_providers(self):
- # Note: in the test common, 'USD' is specified as authorize_currency_id
+ # Note: in the test common, 'USD' is specified as the currency linked to the user account.
unsupported_currency = self._prepare_currency('CHF')
providers = self.env['payment.provider']._get_compatible_providers(
self.company.id, self.partner.id, self.amount, currency_id=unsupported_currency.id
@@ -43,6 +43,6 @@ class AuthorizeTest(AuthorizeCommon):
))
def test_validation(self):
- self.assertEqual(self.authorize.authorize_currency_id, self.currency_usd)
+ self.assertEqual(self.authorize.available_currency_ids[0], self.currency_usd)
self.assertEqual(self.authorize._get_validation_amount(), 0.01)
self.assertEqual(self.authorize._get_validation_currency(), self.currency_usd)
diff --git a/addons/payment_authorize/views/payment_provider_views.xml b/addons/payment_authorize/views/payment_provider_views.xml
index e2ce31ae3dd..0e7f7ff0ab7 100644
--- a/addons/payment_authorize/views/payment_provider_views.xml
+++ b/addons/payment_authorize/views/payment_provider_views.xml
@@ -27,15 +27,14 @@
-
-
-
-
-
-
-
+
+
+
diff --git a/addons/payment_buckaroo/const.py b/addons/payment_buckaroo/const.py
index e8da19d6da2..0521f5db781 100644
--- a/addons/payment_buckaroo/const.py
+++ b/addons/payment_buckaroo/const.py
@@ -10,3 +10,17 @@ STATUS_CODES_MAPPING = {
'refused': (690,),
'error': (490, 491, 492,),
}
+
+# The currencies supported by Buckaroo, in ISO 4217 format.
+# See https://support.buckaroo.eu/frequently-asked-questions
+# Last seen online: 7 November 2022.
+SUPPORTED_CURRENCIES = [
+ 'EUR',
+ 'GBP',
+ 'PLN',
+ 'DKK',
+ 'NOK',
+ 'SEK',
+ 'CHF',
+ 'USD',
+]
diff --git a/addons/payment_buckaroo/models/payment_provider.py b/addons/payment_buckaroo/models/payment_provider.py
index e26fdafc199..05744e1b1ad 100644
--- a/addons/payment_buckaroo/models/payment_provider.py
+++ b/addons/payment_buckaroo/models/payment_provider.py
@@ -6,6 +6,8 @@ from werkzeug import urls
from odoo import fields, models
+from odoo.addons.payment_buckaroo.const import SUPPORTED_CURRENCIES
+
class PaymentProvider(models.Model):
_inherit = 'payment.provider'
@@ -18,6 +20,15 @@ class PaymentProvider(models.Model):
buckaroo_secret_key = fields.Char(
string="Buckaroo Secret Key", required_if_provider='buckaroo', groups='base.group_system')
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return the supported currencies. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'buckaroo':
+ supported_currencies = supported_currencies.filtered(
+ lambda c: c.name in SUPPORTED_CURRENCIES
+ )
+ return supported_currencies
+
def _buckaroo_get_api_url(self):
""" Return the API URL according to the state.
diff --git a/addons/payment_flutterwave/const.py b/addons/payment_flutterwave/const.py
index c38618a1d55..11eab44bcb1 100644
--- a/addons/payment_flutterwave/const.py
+++ b/addons/payment_flutterwave/const.py
@@ -7,6 +7,7 @@
SUPPORTED_CURRENCIES = [
'GBP',
'CAD',
+ 'XAF',
'CLP',
'COP',
'EGP',
@@ -24,7 +25,6 @@ SUPPORTED_CURRENCIES = [
'TZS',
'UGX',
'USD',
- 'XAF',
'XOF',
'ZMW',
]
diff --git a/addons/payment_flutterwave/models/payment_provider.py b/addons/payment_flutterwave/models/payment_provider.py
index 0d05e92c1eb..5735dbdc8b0 100644
--- a/addons/payment_flutterwave/models/payment_provider.py
+++ b/addons/payment_flutterwave/models/payment_provider.py
@@ -49,19 +49,24 @@ class PaymentProvider(models.Model):
# === BUSINESS METHODS ===#
@api.model
- def _get_compatible_providers(self, *args, currency_id=None, is_validation=False, **kwargs):
- """ Override of payment to filter out Flutterwave providers for unsupported currencies or
- for validation operations. """
- providers = super()._get_compatible_providers(
- *args, currency_id=currency_id, is_validation=is_validation, **kwargs
- )
+ def _get_compatible_providers(self, *args, is_validation=False, **kwargs):
+ """ Override of `payment` to filter out Flutterwave providers for validation operations. """
+ providers = super()._get_compatible_providers(*args, is_validation=is_validation, **kwargs)
- currency = self.env['res.currency'].browse(currency_id).exists()
- if (currency and currency.name not in SUPPORTED_CURRENCIES) or is_validation:
+ if is_validation:
providers = providers.filtered(lambda p: p.code != 'flutterwave')
return providers
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return the supported currencies. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'flutterwave':
+ supported_currencies = supported_currencies.filtered(
+ lambda c: c.name in SUPPORTED_CURRENCIES
+ )
+ return supported_currencies
+
def _flutterwave_make_request(self, endpoint, payload=None, method='POST'):
""" Make a request to Flutterwave API at the specified endpoint.
diff --git a/addons/payment_mercado_pago/models/payment_provider.py b/addons/payment_mercado_pago/models/payment_provider.py
index 1e963422560..a63267ed42b 100644
--- a/addons/payment_mercado_pago/models/payment_provider.py
+++ b/addons/payment_mercado_pago/models/payment_provider.py
@@ -6,7 +6,7 @@ import pprint
import requests
from werkzeug import urls
-from odoo import _, api, fields, models
+from odoo import _, fields, models
from odoo.exceptions import ValidationError
from odoo.addons.payment_mercado_pago.const import SUPPORTED_CURRENCIES
@@ -15,7 +15,7 @@ from odoo.addons.payment_mercado_pago.const import SUPPORTED_CURRENCIES
_logger = logging.getLogger(__name__)
-class Paymentprovider(models.Model):
+class PaymentProvider(models.Model):
_inherit = 'payment.provider'
code = fields.Selection(
@@ -29,16 +29,14 @@ class Paymentprovider(models.Model):
# === BUSINESS METHODS === #
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of `payment` to unlist Mercado Pago providers for unsupported currencies. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency and currency.name not in SUPPORTED_CURRENCIES:
- providers = providers.filtered(lambda p: p.code != 'mercado_pago')
-
- return providers
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return the supported currencies. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'mercado_pago':
+ supported_currencies = supported_currencies.filtered(
+ lambda c: c.name in SUPPORTED_CURRENCIES
+ )
+ return supported_currencies
def _mercado_pago_make_request(self, endpoint, payload=None, method='POST'):
""" Make a request to Mercado Pago API at the specified endpoint.
diff --git a/addons/payment_mercado_pago/tests/test_payment_transaction.py b/addons/payment_mercado_pago/tests/test_payment_transaction.py
index d94bd32d2c3..41f57cfb703 100644
--- a/addons/payment_mercado_pago/tests/test_payment_transaction.py
+++ b/addons/payment_mercado_pago/tests/test_payment_transaction.py
@@ -62,7 +62,7 @@ class TestPaymentTransaction(MercadoPagoCommon, PaymentHttpCommon):
successful payment. """
tx = self._create_transaction(flow='redirect')
with patch(
- 'odoo.addons.payment_mercado_pago.models.payment_provider.Paymentprovider'
+ 'odoo.addons.payment_mercado_pago.models.payment_provider.PaymentProvider'
'._mercado_pago_make_request', return_value=self.verification_data
):
tx._process_notification_data(self.redirect_notification_data)
diff --git a/addons/payment_mollie/const.py b/addons/payment_mollie/const.py
index a0d68f8d92f..81748c88106 100644
--- a/addons/payment_mollie/const.py
+++ b/addons/payment_mollie/const.py
@@ -12,11 +12,37 @@ SUPPORTED_LOCALES = [
]
# Currency codes in ISO 4217 format supported by mollie.
-# See https://docs.mollie.com/payments/multicurrency
+# Note: support varies per payment method.
+# See https://docs.mollie.com/payments/multicurrency. Last seen online: 22 September 2022.
SUPPORTED_CURRENCIES = [
- 'AED', 'AUD', 'BGN', 'BRL', 'CAD', 'CHF',
- 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HRK',
- 'HUF', 'ILS', 'ISK', 'JPY', 'MXN', 'MYR',
- 'NOK', 'NZD', 'PHP', 'PLN', 'RON', 'RUB',
- 'SEK', 'SGD', 'THB', 'TWD', 'USD', 'ZAR'
+ 'AED',
+ 'AUD',
+ 'BGN',
+ 'BRL',
+ 'CAD',
+ 'CHF',
+ 'CZK',
+ 'DKK',
+ 'EUR',
+ 'GBP',
+ 'HKD',
+ 'HRK',
+ 'HUF',
+ 'ILS',
+ 'ISK',
+ 'JPY',
+ 'MXN',
+ 'MYR',
+ 'NOK',
+ 'NZD',
+ 'PHP',
+ 'PLN',
+ 'RON',
+ 'RUB',
+ 'SEK',
+ 'SGD',
+ 'THB',
+ 'TWD',
+ 'USD',
+ 'ZAR'
]
diff --git a/addons/payment_mollie/models/payment_provider.py b/addons/payment_mollie/models/payment_provider.py
index d58932df9aa..2b0b8389a79 100755
--- a/addons/payment_mollie/models/payment_provider.py
+++ b/addons/payment_mollie/models/payment_provider.py
@@ -5,7 +5,7 @@ import logging
import requests
from werkzeug import urls
-from odoo import _, api, fields, models, service
+from odoo import _, fields, models, service
from odoo.exceptions import ValidationError
from odoo.addons.payment_mollie.const import SUPPORTED_CURRENCIES
@@ -27,16 +27,14 @@ class PaymentProvider(models.Model):
#=== BUSINESS METHODS ===#
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of payment to unlist Mollie providers for unsupported currencies. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency and currency.name not in SUPPORTED_CURRENCIES:
- providers = providers.filtered(lambda p: p.code != 'mollie')
-
- return providers
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return the supported currencies. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'mollie':
+ supported_currencies = supported_currencies.filtered(
+ lambda c: c.name in SUPPORTED_CURRENCIES
+ )
+ return supported_currencies
def _mollie_make_request(self, endpoint, data=None, method='POST'):
""" Make a request at mollie endpoint.
diff --git a/addons/payment_paypal/const.py b/addons/payment_paypal/const.py
index 5ad95e6462d..1f02c1d0791 100644
--- a/addons/payment_paypal/const.py
+++ b/addons/payment_paypal/const.py
@@ -1,6 +1,8 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
# ISO 4217 codes of currencies supported by PayPal
+# See https://developer.paypal.com/docs/reports/reference/paypal-supported-currencies/.
+# Last seen on: 22 September 2022.
SUPPORTED_CURRENCIES = (
'AUD',
'BRL',
diff --git a/addons/payment_paypal/models/payment_provider.py b/addons/payment_paypal/models/payment_provider.py
index 3f48840256d..0aa4c998e1f 100644
--- a/addons/payment_paypal/models/payment_provider.py
+++ b/addons/payment_paypal/models/payment_provider.py
@@ -2,7 +2,7 @@
import logging
-from odoo import _, api, fields, models
+from odoo import _, fields, models
from odoo.addons.payment_paypal.const import SUPPORTED_CURRENCIES
@@ -35,16 +35,14 @@ class PaymentProvider(models.Model):
#=== BUSINESS METHODS ===#
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of payment to unlist PayPal providers when the currency is not supported. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency and currency.name not in SUPPORTED_CURRENCIES:
- providers = providers.filtered(lambda p: p.code != 'paypal')
-
- return providers
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return the supported currencies. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'paypal':
+ supported_currencies = supported_currencies.filtered(
+ lambda c: c.name in SUPPORTED_CURRENCIES
+ )
+ return supported_currencies
def _paypal_get_api_url(self):
""" Return the API URL according to the provider state.
diff --git a/addons/payment_payulatam/const.py b/addons/payment_payulatam/const.py
new file mode 100644
index 00000000000..6738c357ebe
--- /dev/null
+++ b/addons/payment_payulatam/const.py
@@ -0,0 +1,14 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+# Supported currencies of PayuLatam, in ISO 4217 currency codes.
+# https://developers.payulatam.com/latam/en/docs/getting-started/response-codes-and-variables.html#accepted-currencies.
+# Last seen online: 22 September 2022.
+SUPPORTED_CURRENCIES = [
+ 'ARS',
+ 'BRL',
+ 'CLP',
+ 'COP',
+ 'MXN',
+ 'PEN',
+ 'USD'
+]
diff --git a/addons/payment_payulatam/models/payment_provider.py b/addons/payment_payulatam/models/payment_provider.py
index 27e58e6d342..630aebbfed4 100644
--- a/addons/payment_payulatam/models/payment_provider.py
+++ b/addons/payment_payulatam/models/payment_provider.py
@@ -2,11 +2,10 @@
from hashlib import md5
-from odoo import api, fields, models
+from odoo import fields, models
from odoo.tools.float_utils import float_repr
-SUPPORTED_CURRENCIES = ('ARS', 'BRL', 'CLP', 'COP', 'MXN', 'PEN', 'USD')
-
+from odoo.addons.payment_payulatam.const import SUPPORTED_CURRENCIES
class PaymentProvider(models.Model):
_inherit = 'payment.provider'
@@ -25,16 +24,14 @@ class PaymentProvider(models.Model):
string="PayU Latam API Key", required_if_provider='payulatam',
groups='base.group_system')
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of payment to unlist PayU Latam providers for unsupported currencies. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency and currency.name not in SUPPORTED_CURRENCIES:
- providers = providers.filtered(lambda p: p.code != 'payulatam')
-
- return providers
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return the supported currencies. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'payulatam':
+ supported_currencies = supported_currencies.filtered(
+ lambda c: c.name in SUPPORTED_CURRENCIES
+ )
+ return supported_currencies
def _payulatam_generate_sign(self, values, incoming=True):
""" Generate the signature for incoming or outgoing communications.
diff --git a/addons/payment_payulatam/tests/test_payulatam.py b/addons/payment_payulatam/tests/test_payulatam.py
index afc7be8ffcf..e8218a998f2 100644
--- a/addons/payment_payulatam/tests/test_payulatam.py
+++ b/addons/payment_payulatam/tests/test_payulatam.py
@@ -12,22 +12,12 @@ from odoo.tools import mute_logger
from odoo.addons.payment.tests.http_common import PaymentHttpCommon
from odoo.addons.payment_payulatam.controllers.main import PayuLatamController
-from odoo.addons.payment_payulatam.models.payment_provider import SUPPORTED_CURRENCIES
from odoo.addons.payment_payulatam.tests.common import PayULatamCommon
@tagged('post_install', '-at_install')
class PayULatamTest(PayULatamCommon, PaymentHttpCommon):
- def test_compatibility_with_supported_currencies(self):
- """ Test that the PayULatam provider is compatible with all supported currencies. """
- for supported_currency_code in SUPPORTED_CURRENCIES:
- supported_currency = self._prepare_currency(supported_currency_code)
- compatible_providers = self.env['payment.provider']._get_compatible_providers(
- self.company.id, self.partner.id, self.amount, currency_id=supported_currency.id
- )
- self.assertIn(self.payulatam, compatible_providers)
-
def test_incompatibility_with_unsupported_currency(self):
""" Test that the PayULatam provider is not compatible with an unsupported currency. """
compatible_providers = self.env['payment.provider']._get_compatible_providers(
diff --git a/addons/payment_payumoney/models/payment_provider.py b/addons/payment_payumoney/models/payment_provider.py
index 1d92186d832..0ff91e78bdd 100644
--- a/addons/payment_payumoney/models/payment_provider.py
+++ b/addons/payment_payumoney/models/payment_provider.py
@@ -2,7 +2,7 @@
import hashlib
-from odoo import api, fields, models
+from odoo import fields, models
class PaymentProvider(models.Model):
@@ -16,16 +16,12 @@ class PaymentProvider(models.Model):
payumoney_merchant_salt = fields.Char(
string="Merchant Salt", required_if_provider='payumoney', groups='base.group_system')
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of payment to unlist PayUmoney providers when the currency is not INR. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency and currency.name != 'INR':
- providers = providers.filtered(lambda p: p.code != 'payumoney')
-
- return providers
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return EUR as the only supported currency. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'payumoney':
+ supported_currencies = supported_currencies.filtered(lambda c: c.name == 'INR')
+ return supported_currencies
def _payumoney_generate_sign(self, values, incoming=True):
""" Generate the shasign for incoming or outgoing communications.
diff --git a/addons/payment_razorpay/const.py b/addons/payment_razorpay/const.py
index 2aaf70bb644..5a43c4a4645 100644
--- a/addons/payment_razorpay/const.py
+++ b/addons/payment_razorpay/const.py
@@ -2,15 +2,100 @@
# The currencies supported by Razorpay, in ISO 4217 format. Last updated on May 26, 2021.
# See https://razorpay.com/docs/payments/payments/international-payments/#supported-currencies.
+# Last seen online: 16 November 2022.
SUPPORTED_CURRENCIES = [
- 'AED', 'ALL', 'AMD', 'ARS', 'AUD', 'AWG', 'BBD', 'BDT', 'BMD', 'BND', 'BOB', 'BSD', 'BWP',
- 'BZD', 'CAD', 'CHF', 'CNY', 'COP', 'CRC', 'CUP', 'CZK', 'DKK', 'DOP', 'DZD', 'EGP', 'ETB',
- 'EUR', 'FJD', 'GBP', 'GHS', 'GIP', 'GMD', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF',
- 'IDR', 'ILS', 'INR', 'JMD', 'KES', 'KGS', 'KHR', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD',
- 'LSL', 'MAD', 'MDL', 'MKD', 'MMK', 'MNT', 'MOP', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'NAD',
- 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'PEN', 'PGK', 'PHP', 'PKR', 'QAR', 'RUB', 'SAR', 'SCR',
- 'SEK', 'SGD', 'SLL', 'SOS', 'SSP', 'SVC', 'SZL', 'THB', 'TTD', 'TZS', 'USD', 'UYU', 'UZS',
- 'YER', 'ZAR',
+ 'AED',
+ 'ALL',
+ 'AMD',
+ 'ARS',
+ 'AUD',
+ 'AWG',
+ 'BBD',
+ 'BDT',
+ 'BMD',
+ 'BND',
+ 'BOB',
+ 'BSD',
+ 'BWP',
+ 'BZD',
+ 'CAD',
+ 'CHF',
+ 'CNY',
+ 'COP',
+ 'CRC',
+ 'CUP',
+ 'CZK',
+ 'DKK',
+ 'DOP',
+ 'DZD',
+ 'EGP',
+ 'ETB',
+ 'EUR',
+ 'FJD',
+ 'GBP',
+ 'GHS',
+ 'GIP',
+ 'GMD',
+ 'GTQ',
+ 'GYD',
+ 'HKD',
+ 'HNL',
+ 'HRK',
+ 'HTG',
+ 'HUF',
+ 'IDR',
+ 'ILS',
+ 'INR',
+ 'JMD',
+ 'KES',
+ 'KGS',
+ 'KHR',
+ 'KYD',
+ 'KZT',
+ 'LAK',
+ 'LKR',
+ 'LRD',
+ 'LSL',
+ 'MAD',
+ 'MDL',
+ 'MKD',
+ 'MMK',
+ 'MNT',
+ 'MOP',
+ 'MUR',
+ 'MVR',
+ 'MWK',
+ 'MXN',
+ 'MYR',
+ 'NAD',
+ 'NGN',
+ 'NIO',
+ 'NOK',
+ 'NPR',
+ 'NZD',
+ 'PEN',
+ 'PGK',
+ 'PHP',
+ 'PKR',
+ 'QAR',
+ 'RUB',
+ 'SAR',
+ 'SCR',
+ 'SEK',
+ 'SGD',
+ 'SLL',
+ 'SOS',
+ 'SSP',
+ 'SVC',
+ 'SZL',
+ 'THB',
+ 'TTD',
+ 'TZS',
+ 'USD',
+ 'UYU',
+ 'UZS',
+ 'YER',
+ 'ZAR',
]
# Mapping of transaction states to Razorpay's payment statuses.
diff --git a/addons/payment_razorpay/models/payment_provider.py b/addons/payment_razorpay/models/payment_provider.py
index c28275515ea..39eea782949 100644
--- a/addons/payment_razorpay/models/payment_provider.py
+++ b/addons/payment_razorpay/models/payment_provider.py
@@ -8,7 +8,7 @@ import pprint
import requests
from werkzeug.urls import url_join
-from odoo import _, api, fields, models
+from odoo import _, fields, models
from odoo.exceptions import ValidationError
from odoo.addons.payment_razorpay.const import SUPPORTED_CURRENCIES
@@ -51,16 +51,14 @@ class PaymentProvider(models.Model):
# === BUSINESS METHODS ===#
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of `payment` to filter out Razorpay providers for unsupported currencies. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency and currency.name not in SUPPORTED_CURRENCIES:
- providers = providers.filtered(lambda p: p.code != 'razorpay')
-
- return providers
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return the supported currencies. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'razorpay':
+ supported_currencies = supported_currencies.filtered(
+ lambda c: c.name in SUPPORTED_CURRENCIES
+ )
+ return supported_currencies
def _razorpay_make_request(self, endpoint, payload=None, method='POST'):
""" Make a request to Razorpay API at the specified endpoint.
diff --git a/addons/payment_sips/models/const.py b/addons/payment_sips/const.py
similarity index 79%
rename from addons/payment_sips/models/const.py
rename to addons/payment_sips/const.py
index bfadc210d43..7dccc23e2bb 100644
--- a/addons/payment_sips/models/const.py
+++ b/addons/payment_sips/const.py
@@ -3,12 +3,7 @@
# ISO 4217 Data for currencies supported by sips
# NOTE: these are listed on the Atos Wordline SIPS POST documentation page
# at https://documentation.sips.worldline.com/en/WLSIPS.001-GD-Data-dictionary.html#Sips.001_DD_en-Value-currencyCode
-# Yet with the simu environment, some of these currencies are *not* working
-# I have no way to know if this is caused by the SIMU environment, or if it's
-# the doc of SIPS that lists currencies that don't work, but since this list is
-# restrictive, I'm gonna assume they are supported when using the right flow
-# and payment methods, which may not work in SIMU...
-# Since SIPS advises to use 'in production', well...
+# Last seen on: 22 September 2022.
SUPPORTED_CURRENCIES = {
'ARS': '032',
'AUD': '036',
diff --git a/addons/payment_sips/models/payment_provider.py b/addons/payment_sips/models/payment_provider.py
index 6be08652f7c..a68437c7bf0 100644
--- a/addons/payment_sips/models/payment_provider.py
+++ b/addons/payment_sips/models/payment_provider.py
@@ -3,9 +3,9 @@
from hashlib import sha256
-from odoo import api, fields, models
+from odoo import fields, models
-from .const import SUPPORTED_CURRENCIES
+from odoo.addons.payment_sips.const import SUPPORTED_CURRENCIES
class PaymentProvider(models.Model):
@@ -29,16 +29,14 @@ class PaymentProvider(models.Model):
sips_version = fields.Char(
string="Interface Version", required_if_provider='sips', default="HP_2.31")
- @api.model
- def _get_compatible_providers(self, *args, currency_id=None, **kwargs):
- """ Override of payment to unlist Sips providers when the currency is not supported. """
- providers = super()._get_compatible_providers(*args, currency_id=currency_id, **kwargs)
-
- currency = self.env['res.currency'].browse(currency_id).exists()
- if currency and currency.name not in SUPPORTED_CURRENCIES:
- providers = providers.filtered(lambda p: p.code != 'sips')
-
- return providers
+ def _get_supported_currencies(self):
+ """ Override of `payment` to return the supported currencies. """
+ supported_currencies = super()._get_supported_currencies()
+ if self.code == 'sips':
+ supported_currencies = supported_currencies.filtered(
+ lambda c: c.name in SUPPORTED_CURRENCIES.keys()
+ )
+ return supported_currencies
def _sips_generate_shasign(self, data):
""" Generate the shasign for incoming or outgoing communications.
diff --git a/addons/payment_sips/models/payment_transaction.py b/addons/payment_sips/models/payment_transaction.py
index 416f6a97e39..8dbc2be229a 100644
--- a/addons/payment_sips/models/payment_transaction.py
+++ b/addons/payment_sips/models/payment_transaction.py
@@ -10,8 +10,8 @@ from odoo import _, api, models
from odoo.exceptions import ValidationError
from odoo.addons.payment import utils as payment_utils
+from odoo.addons.payment_sips.const import RESPONSE_CODES_MAPPING, SUPPORTED_CURRENCIES
from odoo.addons.payment_sips.controllers.main import SipsController
-from .const import RESPONSE_CODES_MAPPING, SUPPORTED_CURRENCIES
_logger = logging.getLogger(__name__)
diff --git a/addons/payment_sips/tests/test_sips.py b/addons/payment_sips/tests/test_sips.py
index a482cc99519..4c6eed939a9 100644
--- a/addons/payment_sips/tests/test_sips.py
+++ b/addons/payment_sips/tests/test_sips.py
@@ -12,7 +12,6 @@ from odoo.tools import mute_logger
from odoo.addons.payment.tests.http_common import PaymentHttpCommon
from odoo.addons.payment_sips.controllers.main import SipsController
-from odoo.addons.payment_sips.models.payment_provider import SUPPORTED_CURRENCIES
from odoo.addons.payment_sips.tests.common import SipsCommon
@@ -20,13 +19,6 @@ from odoo.addons.payment_sips.tests.common import SipsCommon
class SipsTest(SipsCommon, PaymentHttpCommon):
def test_compatible_providers(self):
- for curr in SUPPORTED_CURRENCIES:
- currency = self._prepare_currency(curr)
- providers = self.env['payment.provider']._get_compatible_providers(
- self.company.id, self.partner.id, self.amount, currency_id=currency.id
- )
- self.assertIn(self.sips, providers)
-
unsupported_currency = self._prepare_currency('VEF')
providers = self.env['payment.provider']._get_compatible_providers(
self.company.id, self.partner.id, self.amount, currency_id=unsupported_currency.id