Merge pull request #28605 from deepeshgarg007/ksa-e-invoice-new

refactor(KSA VAT): QR Code as per ZATKA specification
This commit is contained in:
Deepesh Garg 2021-11-29 16:46:14 +05:30 committed by GitHub
commit 2bed4140f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 15 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,10 @@
import io import io
import os import os
from base64 import b64encode
import frappe import frappe
from frappe import _
from frappe.utils.data import add_to_date, get_time, getdate
from pyqrcode import create as qr_create from pyqrcode import create as qr_create
from erpnext import get_region from erpnext import get_region
@ -28,24 +31,74 @@ def create_qr_code(doc, method):
for field in meta.get_image_fields(): for field in meta.get_image_fields():
if field.fieldname == 'qr_code': if field.fieldname == 'qr_code':
from urllib.parse import urlencode ''' TLV conversion for
1. Seller's Name
2. VAT Number
3. Time Stamp
4. Invoice Amount
5. VAT Amount
'''
tlv_array = []
# Sellers Name
# Creating public url to print format seller_name = frappe.db.get_value(
default_print_format = frappe.db.get_value('Property Setter', dict(property='default_print_format', doc_type=doc.doctype), "value") 'Company',
doc.company,
'company_name_in_arabic')
# System Language if not seller_name:
language = frappe.get_system_settings('language') frappe.throw(_('Arabic name missing for {} in the company document').format(doc.company))
params = urlencode({ tag = bytes([1]).hex()
'format': default_print_format or 'Standard', length = bytes([len(seller_name.encode('utf-8'))]).hex()
'_lang': language, value = seller_name.encode('utf-8').hex()
'key': doc.get_signature() tlv_array.append(''.join([tag, length, value]))
})
# VAT Number
tax_id = frappe.db.get_value('Company', doc.company, 'tax_id')
if not tax_id:
frappe.throw(_('Tax ID missing for {} in the company document').format(doc.company))
tag = bytes([2]).hex()
length = bytes([len(tax_id)]).hex()
value = tax_id.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value]))
# Time Stamp
posting_date = getdate(doc.posting_date)
time = get_time(doc.posting_time)
seconds = time.hour * 60 * 60 + time.minute * 60 + time.second
time_stamp = add_to_date(posting_date, seconds=seconds)
time_stamp = time_stamp.strftime('%Y-%m-%dT%H:%M:%SZ')
tag = bytes([3]).hex()
length = bytes([len(time_stamp)]).hex()
value = time_stamp.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value]))
# Invoice Amount
invoice_amount = str(doc.total)
tag = bytes([4]).hex()
length = bytes([len(invoice_amount)]).hex()
value = invoice_amount.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value]))
# VAT Amount
vat_amount = str(doc.total_taxes_and_charges)
tag = bytes([5]).hex()
length = bytes([len(vat_amount)]).hex()
value = vat_amount.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value]))
# Joining bytes into one
tlv_buff = ''.join(tlv_array)
# base64 conversion for QR Code
base64_string = b64encode(bytes.fromhex(tlv_buff)).decode()
# creating qr code for the url
url = f"{ frappe.utils.get_url() }/{ doc.doctype }/{ doc.name }?{ params }"
qr_image = io.BytesIO() qr_image = io.BytesIO()
url = qr_create(url, error='L') url = qr_create(base64_string, error='L')
url.png(qr_image, scale=2, quiet_zone=1) url.png(qr_image, scale=2, quiet_zone=1)
# making file # making file