Odoo18-Base/addons/l10n_id_pos/tests/test_qris_pos.py
2025-01-06 10:57:38 +07:00

234 lines
10 KiB
Python

from odoo.exceptions import ValidationError
from odoo.tests import tagged
from odoo.addons.account.tests.common import AccountTestInvoicingHttpCommon
from unittest.mock import patch
from freezegun import freeze_time
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestPosQris(AccountTestInvoicingHttpCommon):
""" Testing QRIS payment via PoS """
@classmethod
@AccountTestInvoicingHttpCommon.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',
})
cls.product_1 = cls.env['product.product'].create({
'name': 'Test Product',
'available_in_pos': True,
'list_price': 1000,
'taxes_id': False,
})
# Create user.
cls.pos_user = cls.env['res.users'].create({
'name': 'A simple PoS man!',
'login': 'pos_user',
'password': 'pos_user',
'groups_id': [
(4, cls.env.ref('base.group_user').id),
(4, cls.env.ref('point_of_sale.group_pos_user').id),
(4, cls.env.ref('account.group_account_invoice').id),
],
})
cls.company = cls.company_data['company']
cls.pos_receivable_bank = cls.copy_account(cls.company.account_default_pos_receivable_account_id, {'name': 'POS Receivable Bank'})
cls.outstanding_bank = cls.copy_account(cls.outbound_payment_method_line.payment_account_id, {'name': 'Outstanding Bank'})
cls.company_data['default_journal_bank'].write({'bank_account_id': cls.acc_qris_id.id})
cls.bank_pm = cls.env['pos.payment.method'].create({
'name': 'Cash',
'journal_id': cls.company_data['default_journal_bank'].id,
'receivable_account_id': cls.pos_receivable_bank.id,
'outstanding_account_id': cls.outstanding_bank.id,
'company_id': cls.company.id,
})
cls.qris_pm = cls.env['pos.payment.method'].create({
'name': 'QRIS',
'journal_id': cls.company_data['default_journal_bank'].id,
'receivable_account_id': cls.pos_receivable_bank.id,
'outstanding_account_id': cls.outstanding_bank.id,
'company_id': cls.company.id,
'payment_method_type': 'qr_code',
'qr_code_method': 'id_qr'
})
cls.main_pos_config = cls.env['pos.config'].create({
'name': 'Shop',
'module_pos_restaurant': False,
# Make sure there is one extra payment method for the tour tests to work.
# Because if the tour only use the qr payment method, the total amount won't be displayed,
# causing the tour test to fail.
'payment_method_ids': [(4, cls.bank_pm.id), (4, cls.qris_pm.id)],
})
def test_qris_transaction_allow_pos_order(self):
""" pos.order model should be created """
self.env['l10n_id.qris.transaction'].create({
'model': 'pos.order',
'model_id': '1234512345'
})
self.env['l10n_id.qris.transaction'].create({
'model': 'account.move',
'model_id': '1'
})
with self.assertRaises(ValidationError):
self.env['l10n_id.qris.transaction'].create({
'model': 'new.model',
'model_id': '1',
})
def test_qris_link_with_pos_order(self):
""" Test whether it's possible to link QRIS transaction with a pos.order record through
UUID field instead of id """
self.main_pos_config.with_user(self.pos_user).open_ui()
pos_order = self.env['pos.order'].create({
'company_id': self.env.company.id,
'session_id': self.main_pos_config.current_session_id.id,
'partner_id': self.partner_a.id,
'access_token': '1234567890',
'uuid': '1234512345',
'lines': [(0, 0, {
'name': "OL/0001",
'product_id': self.product_1.id,
'price_unit': 10000,
'discount': 0.0,
'qty': 1.0,
'tax_ids': False,
'price_subtotal': 10,
'price_subtotal_incl': 10,
})],
'amount_tax': 0,
'amount_total': 10,
'amount_paid': 10.0,
'amount_return': 10.0,
})
qris_transaction = self.env['l10n_id.qris.transaction'].create({
'model': 'pos.order',
'model_id': '1234512345',
})
record = qris_transaction._get_record()
self.assertEqual(pos_order, record)
def test_tour_qris_payment_fail(self):
""" Add products, show QR code and confirm. When confirming, the result will be status
unpaid and so it should trigger a warning dialog informing it"""
def _patched_make_qris_request(endpoint, params):
if endpoint == 'show_qris.php':
return {
"status": "success",
"data": {
"qris_content": "Test Content",
"qris_request_date": "2024-02-27 11:13:42",
"qris_invoiceid": "413255111",
"qris_nmid": "ID1020021181745"
}
}
elif endpoint == 'checkpaid_qris.php':
return {
"status": "failed",
"data": {
"qris_status": "unpaid"
}
}
self.main_pos_config.with_user(self.pos_user).open_ui()
with patch('odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', side_effect=_patched_make_qris_request):
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PaymentScreenQRISPaymentFail', login="pos_user")
def test_tour_qris_payment_success(self):
""" Successful fetching status should proceed next to go to receipt screen"""
def _patched_make_qris_request(endpoint, params):
if endpoint == 'show_qris.php':
return {
"status": "success",
"data": {
"qris_content": "Test Content",
"qris_request_date": "2024-02-27 11:13:42",
"qris_invoiceid": "413255111",
"qris_nmid": "ID1020021181745"
}
}
elif endpoint == 'checkpaid_qris.php':
return {
"status": "success",
"data": {
"qris_status": "paid",
"qris_payment_customername": "Zainal Arief",
"qris_payment_methodby": "Sakuku"
},
"qris_api_version_code": "2206091709"
}
self.main_pos_config.with_user(self.pos_user).open_ui()
with patch('odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', side_effect=_patched_make_qris_request):
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PaymentScreenQRISPaymentSuccess', login="pos_user")
@freeze_time("2024-02-27 04:15:00")
def test_only_call_api_call_once(self):
""" Simulate generating QR, cancel the popup, when we click show QR again, it shouldn't trigger
to fetch new QR code from QRIS"""
def _patched_make_qris_request(endpoint, params):
if endpoint == 'show_qris.php':
return {
"status": "success",
"data": {
"qris_content": "Test Content",
"qris_request_date": "2024-02-27 11:13:42",
"qris_invoiceid": "413255111",
"qris_nmid": "ID1020021181745"
}
}
elif endpoint == 'checkpaid_qris.php':
return {
"status": "success",
"data": {
"qris_status": "paid",
"qris_payment_customername": "Zainal Arief",
"qris_payment_methodby": "Sakuku"
},
"qris_api_version_code": "2206091709"
}
self.main_pos_config.with_user(self.pos_user).open_ui()
with patch('odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', side_effect=_patched_make_qris_request) as patched:
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PayementScreenQRISFetchQR', login="pos_user")
self.assertEqual(patched.call_count, 1)
@freeze_time("2024-02-27 04:15:00")
def test_qris_change_amount(self):
""" Test that when user changes the amount of order after generating QRIS QR for the first time,
it should request for new QR code afterwards. Therefore, there should be 2 API calls instead"""
def _patched_make_qris_request(endpoint, params):
if endpoint == 'show_qris.php':
return {
"status": "success",
"data": {
"qris_content": "Test Content",
"qris_request_date": "2024-02-27 11:13:42",
"qris_invoiceid": "413255111",
"qris_nmid": "ID1020021181745"
}
}
self.main_pos_config.with_user(self.pos_user).open_ui()
self.main_pos_config.current_session_id.set_opening_control(0, 'notes')
with patch('odoo.addons.l10n_id.models.res_bank._l10n_id_make_qris_request', side_effect=_patched_make_qris_request) as patched:
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PayementScreenQRISChangeAmount', login="pos_user")
self.assertEqual(patched.call_count, 2)