[ADD] account_qr_code_emv
- This is a bridge module to provide support for EMV Merchant-Presented QR-code generation for Payment System. - Other accounting localisation module will override _get_merchant_account_info method to construct the qr code parameters. This module will help creating the crc16 check sum to append in the qr code vals. Part-of: odoo/odoo#120050
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -0,0 +1,13 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'account_qr_code_emv',
|
||||
'category': 'Accounting/Payment',
|
||||
'version': '1.0',
|
||||
'description': """
|
||||
Bridge module addings support for EMV Merchant-Presented QR-code generation for Payment System.
|
||||
""",
|
||||
'author': 'Odoo SA',
|
||||
'depends': ['account'],
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
CURRENCY_MAPPING = {
|
||||
'ARS': '032',
|
||||
'AUD': '036',
|
||||
'BHD': '048',
|
||||
'KHR': '116',
|
||||
'CAD': '124',
|
||||
'LKR': '144',
|
||||
'CNY': '156',
|
||||
'HRK': '191',
|
||||
'CZK': '203',
|
||||
'DKK': '208',
|
||||
'HKD': '344',
|
||||
'HUF': '348',
|
||||
'ISK': '352',
|
||||
'INR': '356',
|
||||
'ILS': '376',
|
||||
'JPY': '392',
|
||||
'KRW': '410',
|
||||
'KWD': '414',
|
||||
'MYR': '458',
|
||||
'MUR': '480',
|
||||
'MXN': '484',
|
||||
'NPR': '524',
|
||||
'NZD': '554',
|
||||
'NOK': '578',
|
||||
'QAR': '634',
|
||||
'RUB': '643',
|
||||
'SAR': '682',
|
||||
'SGD': '702',
|
||||
'ZAR': '710',
|
||||
'SEK': '752',
|
||||
'CHF': '756',
|
||||
'THB': '764',
|
||||
'AED': '784',
|
||||
'TND': '788',
|
||||
'GBP': '826',
|
||||
'USD': '840',
|
||||
'TWD': '901',
|
||||
'RSD': '941',
|
||||
'RON': '946',
|
||||
'TRY': '949',
|
||||
'XOF': '952',
|
||||
'XPF': '953',
|
||||
'BGN': '975',
|
||||
'EUR': '978',
|
||||
'UAH': '980',
|
||||
'PLN': '985',
|
||||
'BRL': '986',
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import res_bank
|
||||
@@ -0,0 +1,73 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import _, api, models
|
||||
|
||||
from odoo.addons.account_qr_code_emv.const import CURRENCY_MAPPING
|
||||
|
||||
|
||||
class ResPartnerBank(models.Model):
|
||||
_inherit = 'res.partner.bank'
|
||||
|
||||
# CRC16 calculation with polynomial 0x1021 and initial value 0xFFFF
|
||||
def _get_crc16(self, data, poly=0x1021, init=0xFFFF):
|
||||
crc = init
|
||||
for byte in data:
|
||||
crc = crc ^ (byte << 8)
|
||||
for __ in range(8):
|
||||
if crc & 0x8000:
|
||||
crc = (crc << 1) ^ poly
|
||||
else:
|
||||
crc = crc << 1
|
||||
return crc & 0xFFFF
|
||||
|
||||
def _get_merchant_account_info(self):
|
||||
return False
|
||||
|
||||
def _get_qr_vals(self, qr_method, amount, currency, debtor_partner, free_communication, structured_communication):
|
||||
if qr_method == 'emv_qr':
|
||||
merchant_account_info = self._get_merchant_account_info()
|
||||
currency_code = CURRENCY_MAPPING[currency.name]
|
||||
merchant_name = self.partner_id.name and self.partner_id.name[:25] or 'NA'
|
||||
merchant_city = self.partner_id.city and self.partner_id.city[:15] or ''
|
||||
|
||||
qr_code_vals = [
|
||||
'000201', # Payload Format Indicator
|
||||
'010212', # Dynamic QR Codes
|
||||
f'26{len(merchant_account_info):02}{merchant_account_info}', # Merchant Account Information
|
||||
'52040000', # Merchant Category Code
|
||||
f'5303{currency_code}', # Transaction Currency
|
||||
f'54{len(str(amount)):02}{amount}', # Transaction Amount
|
||||
f'5802{self.partner_id.country_code}', # Country Code
|
||||
f'59{len(merchant_name):02}{merchant_name}', # Merchant Name
|
||||
f'60{len(merchant_city):02}{merchant_city}', # Merchant City
|
||||
'6304', # CRC16
|
||||
]
|
||||
crc = self._get_crc16(bytes(''.join(qr_code_vals), 'utf-8'))
|
||||
qr_code_vals.append(format(crc, '04x').upper())
|
||||
return qr_code_vals
|
||||
return super()._get_qr_vals(qr_method, amount, currency, debtor_partner, free_communication, structured_communication)
|
||||
|
||||
def _get_qr_code_generation_params(self, qr_method, amount, currency, debtor_partner, free_communication, structured_communication):
|
||||
if qr_method == 'emv_qr':
|
||||
return {
|
||||
'barcode_type': 'QR',
|
||||
'width': 128,
|
||||
'height': 128,
|
||||
'humanreadable': 1,
|
||||
'value': ''.join(self._get_qr_vals(qr_method, amount, currency, debtor_partner, free_communication, structured_communication)),
|
||||
}
|
||||
return super()._get_qr_code_generation_params(qr_method, amount, currency, debtor_partner, free_communication, structured_communication)
|
||||
|
||||
def _check_for_qr_code_errors(self, qr_method, amount, currency, debtor_partner, free_communication, structured_communication):
|
||||
if qr_method == 'emv_qr':
|
||||
if not self._get_merchant_account_info():
|
||||
return _("Missing Merchant Account Information.")
|
||||
if not self.partner_id.city:
|
||||
return _("Missing Merchant City.")
|
||||
return super()._check_for_qr_code_errors(qr_method, amount, currency, debtor_partner, free_communication, structured_communication)
|
||||
|
||||
@api.model
|
||||
def _get_available_qr_methods(self):
|
||||
rslt = super()._get_available_qr_methods()
|
||||
rslt.append(('emv_qr', _("EMV Merchant-Presented QR-code"), 30))
|
||||
return rslt
|
||||
Reference in New Issue
Block a user