Files
tryton/modules/account_payment_sepa/tests/test_module.py
T

432 lines
15 KiB
Python
Raw Normal View History

2014-12-02 12:54:47 +01:00
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
2014-03-10 23:12:36 +01:00
import os
from decimal import Decimal
2016-03-06 22:51:42 +01:00
from io import BytesIO, open
2018-06-26 19:11:43 +02:00
from unittest.mock import Mock, patch
2014-08-04 16:47:44 +02:00
2021-12-11 17:58:41 +01:00
from lxml import etree
from trytond.exceptions import UserError
from trytond.modules.account.tests import create_chart
from trytond.modules.account_payment_sepa.payment import CAMT054
from trytond.modules.company.tests import (
CompanyTestMixin, create_company, set_company)
from trytond.modules.currency.tests import create_currency
from trytond.pool import Pool
2016-02-06 19:12:05 +01:00
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
2014-03-10 23:12:36 +01:00
from trytond.transaction import Transaction
2016-02-06 19:12:05 +01:00
2014-03-10 23:12:36 +01:00
def setup_environment():
pool = Pool()
Address = pool.get('party.address')
Party = pool.get('party.party')
Bank = pool.get('bank')
Identifier = pool.get('party.identifier')
2016-02-06 19:12:05 +01:00
currency = create_currency('EUR')
company = create_company(currency=currency)
2016-10-31 13:26:20 +01:00
sepa = Identifier(party=company.party, code='ES23ZZZ47690558N',
2020-04-20 14:28:05 +02:00
type='eu_at_02')
sepa.save()
bank_party = Party(name='European Bank')
bank_party.save()
bank = Bank(party=bank_party, bic='BICODEBBXXX')
bank.save()
customer = Party(name='Customer')
2021-03-31 23:59:33 +02:00
address = Address(street='street', postal_code='1234', city='City')
customer.addresses = [address]
customer.save()
return {
'company': company,
'bank': bank,
'customer': customer,
}
def setup_accounts(bank, company, customer):
pool = Pool()
Account = pool.get('bank.account')
return Account.create([{
'bank': bank,
'owners': [('add', [company.party])],
'currency': company.currency.id,
'numbers': [('create', [{
'type': 'iban',
'number': 'ES8200000000000000000000',
}])]}, {
'bank': bank,
'owners': [('add', [customer])],
'currency': company.currency.id,
'numbers': [('create', [{
'type': 'iban',
'number': 'ES3600000000050000000001',
}])]}])
def setup_mandate(company, customer, account):
pool = Pool()
Mandate = pool.get('account.payment.sepa.mandate')
Date = pool.get('ir.date')
return Mandate.create([{
'company': company,
'party': customer,
'account_number': account.numbers[0],
'identification': 'MANDATE',
'type': 'recurrent',
2016-10-11 18:14:27 +02:00
'sequence_type_rcur': False,
'signature_date': Date.today(),
'state': 'validated',
}])[0]
def setup_journal(flavor, kind, company, account):
pool = Pool()
Journal = pool.get('account.payment.journal')
journal = Journal()
journal.name = flavor
journal.company = company
journal.currency = company.currency
journal.process_method = 'sepa'
journal.sepa_bank_account_number = account.numbers[0]
journal.sepa_payable_flavor = 'pain.001.001.03'
journal.sepa_receivable_flavor = 'pain.008.001.02'
setattr(journal, 'sepa_%s_flavor' % kind, flavor)
journal.save()
return journal
2019-12-18 22:53:55 +01:00
def validate_file(flavor, kind, xsd=None):
'Test generated files are valid'
pool = Pool()
Payment = pool.get('account.payment')
PaymentGroup = pool.get('account.payment.group')
Date = pool.get('ir.date')
ProcessPayment = pool.get('account.payment.process', type='wizard')
if xsd is None:
xsd = flavor
environment = setup_environment()
company = environment['company']
bank = environment['bank']
customer = environment['customer']
with set_company(company):
company_account, customer_account = setup_accounts(
bank, company, customer)
setup_mandate(company, customer, customer_account)
journal = setup_journal(flavor, kind, company, company_account)
payment, = Payment.create([{
'company': company,
'party': customer,
'journal': journal,
'kind': kind,
'amount': Decimal('1000.0'),
2022-04-11 20:41:56 +02:00
'state': 'approved' if kind == 'payable' else 'submitted',
2019-12-18 22:53:55 +01:00
'description': 'PAYMENT',
'date': Date.today(),
}])
session_id, _, _ = ProcessPayment.create()
process_payment = ProcessPayment(session_id)
with Transaction().set_context(
active_model=Payment.__name__, active_ids=[payment.id]):
2019-12-18 22:53:55 +01:00
_, data = process_payment.do_process(None)
group, = PaymentGroup.browse(data['res_id'])
message, = group.sepa_messages
assert message.type == 'out', message.type
assert message.state == 'waiting', message.state
sepa_string = bytes(message.message)
sepa_xml = etree.fromstring(sepa_string)
schema_file = os.path.join(os.path.dirname(__file__),
'%s.xsd' % xsd)
schema = etree.XMLSchema(etree.parse(schema_file))
schema.assertValid(sepa_xml)
class AccountPaymentSepaTestCase(CompanyTestMixin, ModuleTestCase):
2014-03-10 23:12:36 +01:00
'Test Account Payment SEPA module'
2015-01-27 18:13:01 +01:00
module = 'account_payment_sepa'
2016-02-06 19:12:05 +01:00
@with_transaction()
2014-03-10 23:12:36 +01:00
def test_pain001_001_03(self):
'Test pain001.001.03 xsd validation'
2019-12-18 22:53:55 +01:00
validate_file('pain.001.001.03', 'payable')
2014-03-10 23:12:36 +01:00
2016-02-06 19:12:05 +01:00
@with_transaction()
2014-03-10 23:12:36 +01:00
def test_pain001_001_05(self):
'Test pain001.001.05 xsd validation'
2019-12-18 22:53:55 +01:00
validate_file('pain.001.001.05', 'payable')
2014-03-10 23:12:36 +01:00
2016-02-06 19:12:05 +01:00
@with_transaction()
def test_pain001_003_03(self):
'Test pain001.003.03 xsd validation'
2019-12-18 22:53:55 +01:00
validate_file('pain.001.003.03', 'payable')
2016-02-06 19:12:05 +01:00
@with_transaction()
2014-03-10 23:12:36 +01:00
def test_pain008_001_02(self):
'Test pain008.001.02 xsd validation'
2019-12-18 22:53:55 +01:00
validate_file('pain.008.001.02', 'receivable')
2014-03-10 23:12:36 +01:00
2016-02-06 19:12:05 +01:00
@with_transaction()
2014-03-10 23:12:36 +01:00
def test_pain008_001_04(self):
'Test pain008.001.04 xsd validation'
2019-12-18 22:53:55 +01:00
validate_file('pain.008.001.04', 'receivable')
2014-03-10 23:12:36 +01:00
2016-02-06 19:12:05 +01:00
@with_transaction()
def test_pain008_003_02(self):
'Test pain008.003.02 xsd validation'
2019-12-18 22:53:55 +01:00
validate_file('pain.008.003.02', 'receivable')
2016-02-06 19:12:05 +01:00
@with_transaction()
def test_sepa_mandate_sequence(self):
'Test SEPA mandate sequence'
2016-02-06 19:12:05 +01:00
pool = Pool()
Configuration = pool.get('account.configuration')
Sequence = pool.get('ir.sequence')
2021-03-11 23:00:10 +01:00
SequenceType = pool.get('ir.sequence.type')
2016-02-06 19:12:05 +01:00
Party = pool.get('party.party')
Mandate = pool.get('account.payment.sepa.mandate')
2016-02-06 19:12:05 +01:00
party = Party(name='Test')
party.save()
company = create_company()
with set_company(company):
mandate = Mandate(party=party)
mandate.save()
self.assertFalse(mandate.identification)
2021-03-11 23:00:10 +01:00
sequence_type, = SequenceType.search([
('name', '=', "SEPA Mandate"),
], limit=1)
sequence = Sequence(name="Test", sequence_type=sequence_type)
sequence.save()
config = Configuration(1)
config.sepa_mandate_sequence = sequence
config.save()
mandate = Mandate(party=party)
mandate.save()
self.assertTrue(mandate.identification)
2016-02-06 19:12:05 +01:00
@with_transaction()
def test_identification_unique(self):
'Test unique identification constraint'
2016-02-06 19:12:05 +01:00
pool = Pool()
Party = pool.get('party.party')
Mandate = pool.get('account.payment.sepa.mandate')
2016-02-06 19:12:05 +01:00
same_id = '1'
2016-02-06 19:12:05 +01:00
party = Party(name='Test')
party.save()
company = create_company()
with set_company(company):
mandate = Mandate(party=party, identification=same_id)
mandate.save()
for i in range(2):
mandate = Mandate(party=party)
mandate.save()
mandate = Mandate(party=party, identification='')
mandate.save()
2014-06-23 15:20:36 +02:00
self.assertEqual(mandate.identification, None)
Mandate.write([mandate], {
'identification': '',
})
self.assertEqual(mandate.identification, None)
self.assertRaises(UserError, Mandate.create, [{
'party': party.id,
'identification': same_id,
}])
2016-02-06 19:12:05 +01:00
@with_transaction()
def test_payment_sepa_bank_account_number(self):
'Test Payment.sepa_bank_account_number'
2016-02-06 19:12:05 +01:00
pool = Pool()
Payment = pool.get('account.payment')
Mandate = pool.get('account.payment.sepa.mandate')
AccountNumber = pool.get('bank.account.number')
Party = pool.get('party.party')
BankAccount = pool.get('bank.account')
2016-02-06 19:12:05 +01:00
company = create_company()
with set_company(company):
create_chart(company)
account_number = AccountNumber()
mandate = Mandate(account_number=account_number)
payment = Payment(kind='receivable', sepa_mandate=mandate)
self.assertEqual(id(payment.sepa_bank_account_number),
id(account_number))
other_account_number = AccountNumber(type='other')
iban_account_number = AccountNumber(type='iban')
bank_account = BankAccount(
numbers=[other_account_number, iban_account_number])
party = Party(
bank_accounts=[bank_account])
payment = Payment(kind='payable', party=party)
self.assertEqual(id(payment.sepa_bank_account_number),
id(iban_account_number))
2016-02-06 19:12:05 +01:00
@with_transaction()
def test_payment_sequence_type(self):
'Test payment sequence type'
2016-02-06 19:12:05 +01:00
pool = Pool()
Date = pool.get('ir.date')
Payment = pool.get('account.payment')
ProcessPayment = pool.get('account.payment.process', type='wizard')
2016-02-06 19:12:05 +01:00
environment = setup_environment()
company = environment['company']
bank = environment['bank']
customer = environment['customer']
with set_company(company):
company_account, customer_account = setup_accounts(
bank, company, customer)
2016-10-11 18:14:27 +02:00
mandate = setup_mandate(company, customer, customer_account)
journal = setup_journal('pain.008.001.02', 'receivable',
company, company_account)
self.assertFalse(mandate.has_payments)
2016-10-11 18:14:27 +02:00
self.assertEqual(mandate.sequence_type, 'FRST')
mandate.sequence_type_rcur = True
self.assertEqual(mandate.sequence_type, 'RCUR')
mandate.sequence_type_rcur = False
payment, = Payment.create([{
'company': company,
'party': customer,
'journal': journal,
'kind': 'receivable',
'amount': Decimal('1000.0'),
2022-04-11 20:41:56 +02:00
'state': 'submitted',
'description': 'PAYMENT',
'date': Date.today(),
}])
session_id, _, _ = ProcessPayment.create()
process_payment = ProcessPayment(session_id)
with Transaction().set_context(
active_model=Payment.__name__, active_ids=[payment.id]):
_, data = process_payment.do_process(None)
self.assertEqual(payment.sepa_mandate_sequence_type, 'FRST')
self.assertTrue(payment.sepa_mandate.has_payments)
payments = Payment.create([{
'company': company,
'party': customer,
'journal': journal,
'kind': 'receivable',
'amount': Decimal('2000.0'),
2022-04-11 20:41:56 +02:00
'state': 'submitted',
'description': 'PAYMENT',
'date': Date.today(),
}, {
'company': company,
'party': customer,
'journal': journal,
'kind': 'receivable',
'amount': Decimal('3000.0'),
2022-04-11 20:41:56 +02:00
'state': 'submitted',
'description': 'PAYMENT',
'date': Date.today(),
},
])
session_id, _, _ = ProcessPayment.create()
process_payment = ProcessPayment(session_id)
payment_ids = [p.id for p in payments]
with Transaction().set_context(
active_model=Payment.__name__, active_ids=payment_ids):
_, data = process_payment.do_process(None)
for payment in payments:
self.assertEqual(payment.sepa_mandate_sequence_type, 'RCUR')
self.assertTrue(payment.sepa_info_id)
self.assertIsNotNone(payment.group.sepa_id)
2016-02-06 19:12:05 +01:00
@with_transaction()
2014-08-04 16:47:44 +02:00
def handle_camt054(self, flavor):
'Handle camt.054'
2016-02-06 19:12:05 +01:00
pool = Pool()
Message = pool.get('account.payment.sepa.message')
2014-08-04 16:47:44 +02:00
2016-02-06 19:12:05 +01:00
message_file = os.path.join(os.path.dirname(__file__),
'%s.xml' % flavor)
2018-06-26 19:11:43 +02:00
with open(message_file, 'rb') as fp:
message = fp.read()
2016-02-06 19:12:05 +01:00
namespace = Message.get_namespace(message)
self.assertEqual(namespace,
'urn:iso:std:iso:20022:tech:xsd:%s' % flavor)
2014-08-04 16:47:44 +02:00
2016-02-06 19:12:05 +01:00
payment = Mock()
Payment = Mock()
Payment.search.return_value = [payment]
2014-08-04 16:47:44 +02:00
2016-02-06 19:12:05 +01:00
handler = CAMT054(BytesIO(message), Payment)
self.assertEqual(handler.msg_id, 'AAAASESS-FP-00001')
Payment.search.assert_called_with([
('sepa_end_to_end_id', '=', 'MUELL/FINP/RA12345'),
('kind', '=', 'payable'),
])
Payment.succeed.assert_called_with([payment])
payment.reset_mock()
Payment.reset_mock()
with patch.object(CAMT054, 'is_returned') as is_returned:
is_returned.return_value = True
2014-08-04 16:47:44 +02:00
handler = CAMT054(BytesIO(message), Payment)
2016-02-06 19:12:05 +01:00
Payment.save.assert_called_with([payment])
Payment.fail.assert_called_with([payment])
2014-08-04 16:47:44 +02:00
def test_camt054_001_01(self):
'Test camt.054.001.01 handling'
self.handle_camt054('camt.054.001.01')
def test_camt054_001_02(self):
'Test camt.054.001.02 handling'
self.handle_camt054('camt.054.001.02')
def test_camt054_001_03(self):
'Test camt.054.001.03 handling'
self.handle_camt054('camt.054.001.03')
def test_camt054_001_04(self):
'Test camt.054.001.04 handling'
self.handle_camt054('camt.054.001.04')
2016-02-06 19:12:05 +01:00
@with_transaction()
2015-01-20 18:49:54 +01:00
def test_sepa_mandate_report(self):
'Test sepa mandate report'
2016-02-06 19:12:05 +01:00
pool = Pool()
Report = pool.get('account.payment.sepa.mandate', type='report')
2015-01-20 18:49:54 +01:00
2016-02-06 19:12:05 +01:00
environment = setup_environment()
company = environment['company']
bank = environment['bank']
customer = environment['customer']
with set_company(company):
2015-01-20 18:49:54 +01:00
company_account, customer_account = setup_accounts(
bank, company, customer)
mandate = setup_mandate(company, customer, customer_account)
oext, content, _, _ = Report.execute([mandate.id], {})
self.assertEqual(oext, 'odt')
self.assertTrue(content)
2014-03-10 23:12:36 +01:00
del ModuleTestCase