86 lines
4.3 KiB
Python
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)
|