From 941310d26b9146e01ab7947bd5b5bfaa3f2638fe Mon Sep 17 00:00:00 2001 From: Cedric Collins Date: Fri, 14 Oct 2022 16:29:06 -0500 Subject: [PATCH] [IMP] payment_forte: improve unit test and allow setting journal on the payment acquirer --- payment_forte/__manifest__.py | 1 + payment_forte/data/payment_acquirer_data.xml | 12 +-- .../models/account_payment_method.py | 5 - payment_forte/models/payment.py | 57 ++++------- payment_forte/tests/test_forte.py | 99 ++++++++++--------- payment_forte/views/payment_views.xml | 8 +- 6 files changed, 79 insertions(+), 103 deletions(-) diff --git a/payment_forte/__manifest__.py b/payment_forte/__manifest__.py index 8d0fbd8d..59baac32 100644 --- a/payment_forte/__manifest__.py +++ b/payment_forte/__manifest__.py @@ -11,4 +11,5 @@ 'data/payment_acquirer_data.xml', ], 'installable': True, + 'license': 'LGPL-3', } diff --git a/payment_forte/data/payment_acquirer_data.xml b/payment_forte/data/payment_acquirer_data.xml index 30d06c90..705c7911 100644 --- a/payment_forte/data/payment_acquirer_data.xml +++ b/payment_forte/data/payment_acquirer_data.xml @@ -6,25 +6,23 @@ Forte forte - test - 1000 - 1001 - dummy - dummy + True + False + + True + True Forte eCheck forte inbound - echeck Forte eCheck forte outbound - echeck diff --git a/payment_forte/models/account_payment_method.py b/payment_forte/models/account_payment_method.py index 5ee4a600..3c747cba 100644 --- a/payment_forte/models/account_payment_method.py +++ b/payment_forte/models/account_payment_method.py @@ -3,11 +3,6 @@ from odoo import api, models, fields class AccountPaymentMethod(models.Model): _inherit = 'account.payment.method' - forte_type = fields.Selection([ - ('echeck', 'eCheck'), - ('creditcard', 'Credit Card'), - ]) - @api.model def _get_payment_method_information(self): res = super()._get_payment_method_information() diff --git a/payment_forte/models/payment.py b/payment_forte/models/payment.py index a58406ed..bac34916 100644 --- a/payment_forte/models/payment.py +++ b/payment_forte/models/payment.py @@ -1,7 +1,11 @@ +import logging + from odoo import api, fields, models -from odoo.exceptions import ValidationError +from odoo.exceptions import UserError from .forte_request import ForteAPI -from json import dumps + + +_logger = logging.getLogger(__name__) def forte_get_api(acquirer): @@ -20,32 +24,12 @@ class PaymentAcquirerForte(models.Model): forte_location_id = fields.Char(string='Location ID') # Probably move to Journal... forte_access_id = fields.Char(string='Access ID') forte_secure_key = fields.Char(string='Secure Key') - - def _get_feature_support(self): - """Get advanced feature support by provider. - - Each provider should add its technical in the corresponding - key for the following features: - * fees: support payment fees computations - * authorize: support authorizing payment (separates - authorization and capture) - * tokenize: support saving payment data in a payment.tokenize - object - """ - res = super(PaymentAcquirerForte, self)._get_feature_support() - res['authorize'].append('authorize') - res['tokenize'].append('authorize') - return res - - def forte_test_credentials(self): + + def _get_default_payment_method_id(self): self.ensure_one() - api = forte_get_api(self) - resp = api.test_authenticate() - if not resp.ok: - result = resp.json() - if result and result.get('response'): - raise ValidationError('Error: ' + dumps(result.get('response'))) - return True + if self.provider != 'forte': + return super()._get_default_payment_method_id() + return self.env.ref('payment_forte.payment_method_forte_echeck_inbound').id class TxForte(models.Model): @@ -75,24 +59,21 @@ class TxForte(models.Model): account_holder = self.token_id.forte_account_holder method = self.payment_id.payment_method_id - # if not self.env.context.get('payment_type'): if not method or not method.payment_type: _logger.warning('Trying to do a payment with Forte and no contextual payment_type will result in an inbound transaction.') - # if self.env.context.get('payment_type') == 'inbound': - if method.forte_type == 'echeck': - if method.payment_type == 'outbound': - resp = api.echeck_credit(location, amount, account_type, routing_number, account_number, account_holder) - else: - resp = api.echeck_sale(location, amount, account_type, routing_number, account_number, account_holder) - # elif method.forte_type == 'creditcard': + + if method.payment_type == 'outbound': + resp = api.echeck_credit(location, amount, account_type, routing_number, account_number, account_holder) + else: + resp = api.echeck_sale(location, amount, account_type, routing_number, account_number, account_holder) if resp.ok and resp.json()['response']['response_desc'] == 'APPROVED': ref = resp.json()['response']['authorization_code'] return self.write({'state': 'done', 'acquirer_reference': ref}) else: - result = resp.json() - if result and result.get('response'): - raise ValidationError('Error: ' + dumps(result.get('response'))) + result = resp.json() and resp.json().get('response') + if result: + raise UserError('Error: %s - %s' % (result.get('response_code'), result.get('response_desc'))) class PaymentToken(models.Model): diff --git a/payment_forte/tests/test_forte.py b/payment_forte/tests/test_forte.py index ef0b0ae8..c91a0c42 100644 --- a/payment_forte/tests/test_forte.py +++ b/payment_forte/tests/test_forte.py @@ -1,35 +1,43 @@ -from odoo.addons.payment.tests.common import PaymentCommon +from json import dumps +from unittest import SkipTest +import logging + from odoo.exceptions import ValidationError from odoo.tests import tagged +from odoo.addons.payment.tests.common import PaymentCommon +from ..models.payment import forte_get_api + + +_logger = logging.getLogger(__name__) + + class ForteCommon(PaymentCommon): @classmethod def setUpClass(cls, chart_template_ref=None): super().setUpClass(chart_template_ref=chart_template_ref) - - cls.currency_usd = cls._prepare_currency('USD') + cls.forte = cls._prepare_acquirer('forte', update_values={ 'fees_active': False, # Only activate fees in dedicated tests - 'forte_organization_id': '366035', - 'forte_location_id': '223008', - 'forte_access_id': 'a7b45fe9ff8d1d5406ae6f98791958da', - 'forte_secure_key': '20ee1d1f5a4afbf9db03af2c81f067c5', }) + + if not cls.forte.forte_secure_key: + skip_message = 'Credentials have not been configured for Forte, skipping tests...' + _logger.warning(skip_message) + raise SkipTest(skip_message) # override defaults for helpers cls.acquirer = cls.forte - cls.currency = cls.currency_usd - cls.forte = cls.acquirer - cls.method = cls.env.ref('payment_forte.payment_method_forte_echeck_inbound') - cls.journal = cls.env['account.journal'].search([], limit=1)[0] - cls.journal.write({ - 'inbound_payment_method_line_ids': [(0, 0, { - 'name': 'Electronic', - 'payment_method_id': cls.method.id, - })], - }) - cls.method_line = cls.journal.inbound_payment_method_line_ids.filtered(lambda l: l.payment_method_id == cls.method) - cls.buyer = cls.env['res.partner'].search([('customer_rank', '>=', 1)], limit=1)[0] + cls.inbound_payment_method_line = cls.acquirer.journal_id.inbound_payment_method_line_ids.filtered(lambda l: l.code == 'forte') + + def forte_test_credentials(self): + api = forte_get_api(self.acquirer) + resp = api.test_authenticate() + if not resp.ok: + result = resp.json() + if result and result.get('response'): + raise ValidationError('Error: ' + dumps(result.get('response'))) + return True @tagged('post_install', '-at_install') @@ -37,38 +45,31 @@ class ForteACH(ForteCommon): def test_10_forte_api(self): self.assertEqual(self.forte.state, 'test', 'Must test with test environment.') - response = self.forte.forte_test_credentials() + self.assertTrue(self.forte_test_credentials()) # Create/Save a Payment Token. # Change Token numbers to real values if you want to try to get an approval. - token = self.env['payment.token'].create({ - 'name': 'Test Token 1234', - 'partner_id': self.buyer.id, - 'acquirer_id': self.forte.id, - 'acquirer_ref': 'Test Token', - 'forte_account_type': 'Checking', - 'forte_routing_number': '021000021', - 'forte_account_number': '000111222', - 'forte_account_holder': self.buyer.name, - }) + token = self.create_token( + forte_account_type='Checking', + forte_routing_number='021000021', + forte_account_number='000111222', + forte_account_holder=self.partner.name, + ) # Create Payment - try: - payment = self.env['account.payment'].create({ - 'payment_type': 'inbound', - 'journal_id': self.journal.id, - 'partner_id': self.buyer.id, - 'payment_token_id': token.id, - 'payment_method_id': self.method.id, - 'payment_method_line_id': self.method_line.id, - 'amount': 22.00, - }) - - payment.action_post() - self.assertTrue(payment.payment_transaction_id) - self.assertEqual(payment.payment_transaction_id.amount, 22.00) - self.assertTrue(payment.payment_transaction_id.acquirer_reference) - except ValidationError as e: - # U02 account not authorized. - if e.name.find('U02') < 0: - raise e + payment = self.env['account.payment'].create({ + 'payment_type': 'inbound', + 'partner_type': 'customer', + 'amount': 22.0, + # 'date': '2019-01-01', + 'currency_id': self.currency.id, + 'partner_id': self.partner.id, + 'journal_id': self.acquirer.journal_id.id, + 'payment_method_line_id': self.inbound_payment_method_line.id, + 'payment_token_id': token.id, + }) + + payment.action_post() + self.assertTrue(payment.payment_transaction_id) + self.assertEqual(payment.payment_transaction_id.amount, 22.00) + self.assertTrue(payment.payment_transaction_id.acquirer_reference) diff --git a/payment_forte/views/payment_views.xml b/payment_forte/views/payment_views.xml index 9ca49e4f..95c1686c 100644 --- a/payment_forte/views/payment_views.xml +++ b/payment_forte/views/payment_views.xml @@ -7,10 +7,10 @@ - - - - + + + +