odoo18/addons/l10n_kh/models/res_bank.py

86 lines
4.3 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
import time
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class ResPartnerBank(models.Model):
_inherit = 'res.partner.bank'
proxy_type = fields.Selection(
selection_add=[
('bakong_id_solo', "Bakong Account ID (Solo Merchant)"),
('bakong_id_merchant', "Bakong Account ID (Corporate Merchant)"),
],
ondelete={'bakong_id_solo': 'set default', 'bakong_id_merchant': 'set default'},
)
l10n_kh_merchant_id = fields.Char("Merchant ID")
@api.constrains('proxy_type', 'proxy_value')
def _check_kh_proxy(self):
bakong_id_re = re.compile(r"^[a-zA-Z0-9_].*@[a-zA-Z0-9_].*$")
for bank in self.filtered(lambda b: b.country_code == 'KH'):
if bank.proxy_type not in ['bakong_id_solo', 'bakong_id_merchant', 'none', False]:
raise ValidationError(_("The proxy type must be Bakong Account ID"))
if bank.proxy_type in ['bakong_id_solo', 'bakong_id_merchant'] and (not bank.proxy_value or not bakong_id_re.match(bank.proxy_value) or len(bank.proxy_value) > 32):
raise ValidationError(_("Please enter a valid Bakong Account ID."))
if bank.proxy_type == 'bakong_id_merchant' and not bank.l10n_kh_merchant_id:
raise ValidationError(_("Merchant ID is missing."))
def _get_qr_code_vals_list(self, qr_method, amount, currency, debtor_partner, free_communication, structured_communication):
res = super()._get_qr_code_vals_list(qr_method, amount, currency, debtor_partner, free_communication, structured_communication)
if self.country_code == 'KH':
# Adds the timestamp. Format is {tag}{len}{str}
timestamp = str(time.time_ns() // 1000000)
# The expiry is optional and seems to be mostly for Bakong as it works without it in other bank apps.
# But it works in all tested apps with it, so we will always include it. We'll make it expire in a month, should be long enough.
expiry_timestamp = str((time.time_ns() // 1000000) + (1000 * 60 * 60 * 24 * 30))
res.append(
(99, f"00{len(timestamp)}{timestamp}01{len(expiry_timestamp)}{expiry_timestamp}"),
)
return res
def _compute_display_qr_setting(self):
bank_kh = self.filtered(lambda b: b.country_code == 'KH')
bank_kh.display_qr_setting = self.env.company.qr_code
super(ResPartnerBank, self - bank_kh)._compute_display_qr_setting()
def _get_merchant_account_info(self):
if self.country_code == 'KH':
if self.proxy_type == 'bakong_id_solo':
return 29, self._serialize(*(0, self.proxy_value))
elif self.proxy_type == 'bakong_id_merchant':
merchant_account_info = ''.join([self._serialize(*val) for val in [
(0, self.proxy_value),
(1, self.l10n_kh_merchant_id),
(2, self.bank_id.name),
]])
return 30, merchant_account_info
return super()._get_merchant_account_info()
def _get_additional_data_field(self, comment):
if self.country_code == 'KH':
return self._serialize(1, comment)
return super()._get_additional_data_field(comment)
def _get_merchant_category_code(self):
if self.country_code == 'KH':
return '0001'
return super()._get_merchant_category_code()
def _get_error_messages_for_qr(self, qr_method, debtor_partner, currency):
if qr_method == 'emv_qr' and self.country_code == 'KH':
if currency.name not in ['KHR', 'USD']:
return _("Can't generate a KHQR code with a currency other than KHR or USD.")
return None
return super()._get_error_messages_for_qr(qr_method, debtor_partner, currency)
def _check_for_qr_code_errors(self, qr_method, amount, currency, debtor_partner, free_communication, structured_communication):
if qr_method == 'emv_qr' and self.country_code == 'KH' and self.proxy_type not in ['bakong_id_solo', 'bakong_id_merchant']:
return _("The proxy type of KHQR must be a Bakong Account ID")
return super()._check_for_qr_code_errors(qr_method, amount, currency, debtor_partner, free_communication, structured_communication)