mirror of
https://github.com/bringout/oca-ocb-l10n_asia-pacific.git
synced 2026-04-25 20:22:06 +02:00
19.0 vanilla
This commit is contained in:
parent
7dc55599c6
commit
7f43bbbfcc
650 changed files with 45260 additions and 33436 deletions
2
odoo-bringout-oca-ocb-l10n_id/l10n_id/tests/__init__.py
Normal file
2
odoo-bringout-oca-ocb-l10n_id/l10n_id/tests/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from . import test_qris_transaction
|
||||
from . import test_qris
|
||||
196
odoo-bringout-oca-ocb-l10n_id/l10n_id/tests/test_qris.py
Normal file
196
odoo-bringout-oca-ocb-l10n_id/l10n_id/tests/test_qris.py
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
from markupsafe import Markup
|
||||
|
||||
from odoo.fields import Command
|
||||
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
from odoo.tests import tagged
|
||||
from unittest.mock import patch
|
||||
from freezegun import freeze_time
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestQris(AccountTestInvoicingCommon):
|
||||
""" Test QRIS QR generation on invoices and auto-payment registration"""
|
||||
|
||||
@classmethod
|
||||
@AccountTestInvoicingCommon.setup_chart_template('id')
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.company_data['company'].qr_code = True
|
||||
cls.company_data['company'].partner_id.update({
|
||||
'country_id': cls.env.ref('base.id').id,
|
||||
'city': 'Jakarta',
|
||||
})
|
||||
|
||||
cls.acc_qris_id = cls.env['res.partner.bank'].create({
|
||||
'acc_number': '123456789012345678',
|
||||
'partner_id': cls.company_data['company'].partner_id.id,
|
||||
'l10n_id_qris_api_key': 'apikey',
|
||||
'l10n_id_qris_mid': 'mid',
|
||||
'allow_out_payment': True,
|
||||
})
|
||||
cls.qris_qr_invoice = cls.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'currency_id': cls.env.ref('base.IDR').id,
|
||||
'partner_bank_id': cls.acc_qris_id.id,
|
||||
'company_id': cls.company_data['company'].id,
|
||||
'invoice_line_ids': [Command.create({'quantity': 1, 'price_unit': 100})],
|
||||
'qr_code_method': 'id_qr',
|
||||
})._post()
|
||||
|
||||
cls.success_qris_get = {
|
||||
"status": "success",
|
||||
"data": {
|
||||
"qris_content": "Test Content",
|
||||
"qris_request_date": "2024-02-27 11:13:42",
|
||||
"qris_invoiceid": "413255111",
|
||||
"qris_nmid": "ID1020021181745"
|
||||
}
|
||||
}
|
||||
cls.success_qris_get_second = {
|
||||
"status": "success",
|
||||
"data": {
|
||||
"qris_content": "Test Content Second",
|
||||
"qris_request_date": "2024-02-27 11:13:42",
|
||||
"qris_invoiceid": "413255111",
|
||||
"qris_nmid": "ID1020021181745"
|
||||
}
|
||||
}
|
||||
|
||||
cls.qris_status_fail = {
|
||||
"status": "failed",
|
||||
"data": {
|
||||
"qris_status": "unpaid"
|
||||
}
|
||||
}
|
||||
|
||||
cls.qris_status_success = {
|
||||
"status": "success",
|
||||
"data": {
|
||||
"qris_status": "paid",
|
||||
"qris_payment_customername": "Zainal Arief",
|
||||
"qris_payment_methodby": "Sakuku"
|
||||
},
|
||||
"qris_api_version_code": "2206091709"
|
||||
}
|
||||
|
||||
@freeze_time("2024-02-27 04:15:00")
|
||||
def test_qris_qr_code_generation(self):
|
||||
""" QR-Code generation conditions:
|
||||
|
||||
- should only come from portal side
|
||||
- only call the API when the QRIS transaction not found or lasted for > 30 minutes
|
||||
- if transaction found and < 30 minutes, no API call needed
|
||||
"""
|
||||
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.success_qris_get
|
||||
) as patched:
|
||||
# QR code shouldn't be generated without the context.
|
||||
result = self.qris_qr_invoice._generate_qr_code()
|
||||
self.assertIsNone(result)
|
||||
|
||||
# But of course, should be with it.
|
||||
result = self.qris_qr_invoice.with_context({'is_online_qr': True})._generate_qr_code()
|
||||
self.assertIsNotNone(result)
|
||||
|
||||
# Confirm that a transaction should be registered on the invoice
|
||||
qr_details = self.qris_qr_invoice.l10n_id_qris_transaction_ids
|
||||
self.assertEqual(len(qr_details), 1)
|
||||
|
||||
qris_data = self.success_qris_get['data']
|
||||
self.assertEqual(qr_details.qris_invoice_id, qris_data['qris_invoiceid'])
|
||||
self.assertEqual(qr_details.qris_content, qris_data['qris_content'])
|
||||
patched.assert_called_once()
|
||||
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.success_qris_get
|
||||
) as patched:
|
||||
# Check the API is not called again, as it should reuse the existing QR until it is expired
|
||||
self.qris_qr_invoice.with_context({'is_online_qr': True})._generate_qr_code()
|
||||
patched.assert_not_called()
|
||||
|
||||
# Check that if the qr code has expired, we correctly generate a new one.
|
||||
qr_details.qris_creation_datetime = '2024-02-27 03:00:00'
|
||||
self.qris_qr_invoice.with_context({'is_online_qr': True})._generate_qr_code()
|
||||
patched.assert_called_once()
|
||||
|
||||
self.assertEqual(len(self.qris_qr_invoice.l10n_id_qris_transaction_ids), 2)
|
||||
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.success_qris_get_second
|
||||
):
|
||||
self.qris_qr_invoice.l10n_id_qris_transaction_ids[-1]['qris_creation_datetime'] = '2024-02-27 03:00:00'
|
||||
self.qris_qr_invoice.with_context({'is_online_qr': True})._generate_qr_code()
|
||||
|
||||
# Ensure that the l10n_id_latest_qris_content is the new one, while now there are 3 qris transactions linked to the inovice
|
||||
qr_details = self.qris_qr_invoice.l10n_id_qris_transaction_ids
|
||||
qris_data = self.success_qris_get_second['data']
|
||||
self.assertEqual(qr_details[-1].qris_invoice_id, qris_data['qris_invoiceid'])
|
||||
self.assertEqual(qr_details[-1].qris_content, qris_data['qris_content'])
|
||||
|
||||
self.assertEqual(len(self.qris_qr_invoice.l10n_id_qris_transaction_ids), 3)
|
||||
|
||||
@freeze_time("2024-02-27 04:15:00")
|
||||
def test_fetch_payment_status_fail(self):
|
||||
""" If API return unpaid status """
|
||||
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.success_qris_get
|
||||
):
|
||||
self.qris_qr_invoice.with_context({'is_online_qr': True})._generate_qr_code()
|
||||
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.qris_status_fail
|
||||
):
|
||||
self.qris_qr_invoice.action_l10n_id_update_payment_status()
|
||||
self.assertEqual(self.qris_qr_invoice.payment_state, 'not_paid')
|
||||
|
||||
@freeze_time("2024-02-27 04:15:00")
|
||||
def test_fetch_payment_status_success(self):
|
||||
""" If API returns 'paid' status """
|
||||
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.success_qris_get
|
||||
):
|
||||
self.qris_qr_invoice.with_context({'is_online_qr': True})._generate_qr_code()
|
||||
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.qris_status_success
|
||||
):
|
||||
self.qris_qr_invoice.action_l10n_id_update_payment_status()
|
||||
self.assertEqual(self.qris_qr_invoice.payment_state, self.env['account.move']._get_invoice_in_payment_state())
|
||||
# Ensure that the message is logged as expected.
|
||||
self.assertEqual(
|
||||
self.qris_qr_invoice.message_ids[0].body,
|
||||
Markup('<p>This invoice was paid by Zainal Arief using QRIS with the payment method Sakuku.</p>')
|
||||
)
|
||||
# One of the QRIS transactions linked to the invoice should be paid already
|
||||
self.assertTrue(any(self.qris_qr_invoice.l10n_id_qris_transaction_ids.mapped('paid')))
|
||||
|
||||
@freeze_time("2024-02-27 04:15:00")
|
||||
def test_gc_no_remove_transactions_unpaid_within_30(self):
|
||||
# Case 2: Unsuccessful, latest transaction is < 30 minutes, should avoid garbage-collection
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.success_qris_get
|
||||
):
|
||||
self.qris_qr_invoice.with_context({'is_online_qr': True})._generate_qr_code()
|
||||
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.qris_status_fail
|
||||
):
|
||||
self.qris_qr_invoice.action_l10n_id_update_payment_status()
|
||||
self.assertEqual(self.env['l10n_id.qris.transaction'].search_count([]), 1)
|
||||
self.env['l10n_id.qris.transaction']._gc_remove_pointless_qris_transactions()
|
||||
self.assertEqual(self.env['l10n_id.qris.transaction'].search_count([]), 1)
|
||||
|
||||
@freeze_time("2024-02-27 05:15:00")
|
||||
def test_gc_remove_transactions_unpaid_after_30(self):
|
||||
# Case 3: Unsuccessful, latest transaction is > 30 minutes, should be garbage-collected
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.success_qris_get
|
||||
):
|
||||
self.qris_qr_invoice.with_context({'is_online_qr': True})._generate_qr_code()
|
||||
self.assertEqual(self.env['l10n_id.qris.transaction'].search_count([]), 1)
|
||||
self.env['l10n_id.qris.transaction']._gc_remove_pointless_qris_transactions()
|
||||
self.assertEqual(self.env['l10n_id.qris.transaction'].search_count([]), 0)
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
|
||||
from odoo.fields import Command
|
||||
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
from odoo.tests import tagged
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestQrisTransaction(AccountTestInvoicingCommon):
|
||||
""" Testing the behaviours of QRIS Transaction """
|
||||
|
||||
@classmethod
|
||||
@AccountTestInvoicingCommon.setup_chart_template('id')
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.invoice = cls.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'invoice_date': '2019-05-01',
|
||||
'date': '2019-05-01',
|
||||
'invoice_line_ids': [
|
||||
Command.create({'name': 'line1', 'price_unit': 110.0}),
|
||||
],
|
||||
})
|
||||
cls.qris_status_success = {
|
||||
"status": "success",
|
||||
"data": {
|
||||
"qris_status": "paid",
|
||||
"qris_payment_customername": "Zainal Arief",
|
||||
"qris_payment_methodby": "Sakuku"
|
||||
},
|
||||
"qris_api_version_code": "2206091709"
|
||||
}
|
||||
cls.qris_status_fail = {
|
||||
"status": "failed",
|
||||
"data": {
|
||||
"qris_status": "unpaid"
|
||||
}
|
||||
}
|
||||
|
||||
cls.acc_qris_id = cls.env['res.partner.bank'].create({
|
||||
'acc_number': '123456789012345678',
|
||||
'partner_id': cls.company_data['company'].partner_id.id,
|
||||
'l10n_id_qris_api_key': 'apikey',
|
||||
'l10n_id_qris_mid': 'mid',
|
||||
})
|
||||
|
||||
# Utility method to help create QRIS transactions
|
||||
def _create_sample_transaction(self, model, model_id, qris_id, amount, create_at, content):
|
||||
return self.env['l10n_id.qris.transaction'].create({
|
||||
'model': model,
|
||||
'model_id': model_id,
|
||||
'qris_invoice_id': qris_id,
|
||||
'qris_amount': amount,
|
||||
'qris_creation_datetime': create_at,
|
||||
'qris_content': content,
|
||||
})
|
||||
|
||||
def test_retrieve_backend_record(self):
|
||||
""" Test the _get_record method to retrieve original record accordingly """
|
||||
trx = self._create_sample_transaction(
|
||||
"account.move", str(self.invoice.id), "11254", 11000, "2024-08-01", "qris_content_sample"
|
||||
)
|
||||
invoice = trx._get_record()
|
||||
self.assertEqual(invoice, self.invoice)
|
||||
|
||||
def test_latest_transaction(self):
|
||||
""" Test method _get_latest_transaction"""
|
||||
self._create_sample_transaction(
|
||||
"account.move", "1", "11254", 11000, "2024-08-01 03:00:00", "qris_content_sample"
|
||||
)
|
||||
self._create_sample_transaction(
|
||||
"account.move", "1", "11254", 11000, "2024-08-01 03:00:15", "qris_content_sample_latest"
|
||||
)
|
||||
|
||||
trx = self.env['l10n_id.qris.transaction']._get_latest_transaction('account.move', '1')
|
||||
self.assertTrue(
|
||||
trx['qris_amount'] == 11000 and trx['qris_content'] == "qris_content_sample_latest"
|
||||
)
|
||||
|
||||
def test_l10n_id_get_qris_qr_statuses(self):
|
||||
""" Test the method _l10n_id_get_qris_qr_statuses """
|
||||
|
||||
# Create QRIS transaction with 2 entries in invoice details
|
||||
trx = self._create_sample_transaction(
|
||||
"account.move", "1", "11253", 11000, "2024-08-01", "qris_content_sample"
|
||||
)
|
||||
trx |= self._create_sample_transaction(
|
||||
"account.move", "1", "11254", 11000, "2024-08-01", "qris_content_sample"
|
||||
)
|
||||
|
||||
# if QRIS returns success, _l10n_id_make_request should only be called once and
|
||||
# status returned is {'paid': True, 'qr_statuses': [{self.qris_status_success}]}
|
||||
# and check that the transaction is also paid
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.qris_status_success
|
||||
) as patched:
|
||||
res = trx._l10n_id_get_qris_qr_statuses()
|
||||
patched.assert_called_once()
|
||||
self.assertEqual(len(res['qr_statuses']), 1)
|
||||
success_response = res['qr_statuses'][0]
|
||||
self.assertTrue(res['paid'] and success_response['qris_payment_customername'] == 'Zainal Arief' and trx[0].paid)
|
||||
|
||||
# if QRIS returns fail for all, _l10n_id_make-request should be called twice and
|
||||
# status returned is {'paid': False, 'qr_statuses': [{self.qris_status}, {self.qris_status_fail}]}
|
||||
with patch(
|
||||
'odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', return_value=self.qris_status_fail
|
||||
) as patched:
|
||||
res = trx._l10n_id_get_qris_qr_statuses()
|
||||
self.assertEqual(patched.call_count, 2)
|
||||
self.assertEqual(len(res['qr_statuses']), 2)
|
||||
Loading…
Add table
Add a link
Reference in a new issue