feat: create QR Code field if not existing

This commit is contained in:
Dany Robert 2021-12-07 12:11:43 +05:30 committed by GitHub
parent ef53eb7fcd
commit 276bf73974
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,140 +1,142 @@
import io import io
import os import os
from base64 import b64encode from base64 import b64encode
from pyqrcode import create as qr_create
import frappe import frappe
from frappe import _ from frappe import _
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from frappe.utils.data import add_to_date, get_time, getdate from frappe.utils.data import add_to_date, get_time, getdate
from pyqrcode import create as qr_create
from erpnext import get_region from erpnext import get_region
def create_qr_code(doc, method): def create_qr_code(doc, method):
"""Create QR Code after inserting Sales Inv
"""
region = get_region(doc.company) region = get_region(doc.company)
if region not in ['Saudi Arabia']: if region not in ['Saudi Arabia']:
return return
# if QR Code field not present, do nothing # if QR Code field not present, create it. Invoices without QR are invalid as per law.
if not hasattr(doc, 'qr_code'): if not hasattr(doc, 'ksa_einv_qr'):
return create_custom_fields({
'Sales Invoice': [
dict(
fieldname='ksa_einv_qr',
label='QR Code',
fieldtype='Attach Image',
read_only=1, no_copy=1, hidden=1
)
]
})
# Don't create QR Code if it already exists # Don't create QR Code if it already exists
qr_code = doc.get("qr_code") qr_code = doc.get("ksa_einv_qr")
if qr_code and frappe.db.exists({"doctype": "File", "file_url": qr_code}): if qr_code and frappe.db.exists({"doctype": "File", "file_url": qr_code}):
return return
meta = frappe.get_meta('Sales Invoice') meta = frappe.get_meta(doc.doctype)
for field in meta.get_image_fields(): if "ksa_einv_qr" in [d.fieldname for d in meta.get_image_fields()]:
if field.fieldname == 'qr_code': ''' TLV conversion for
''' TLV conversion for 1. Seller's Name
1. Seller's Name 2. VAT Number
2. VAT Number 3. Time Stamp
3. Time Stamp 4. Invoice Amount
4. Invoice Amount 5. VAT Amount
5. VAT Amount '''
''' tlv_array = []
tlv_array = [] # Sellers Name
# Sellers Name
seller_name = frappe.db.get_value( seller_name = frappe.db.get_value(
'Company', 'Company',
doc.company, doc.company,
'company_name_in_arabic') 'company_name_in_arabic')
if not seller_name: if not seller_name:
frappe.throw(_('Arabic name missing for {} in the company document').format(doc.company)) frappe.throw(_('Arabic name missing for {} in the company document').format(doc.company))
tag = bytes([1]).hex() tag = bytes([1]).hex()
length = bytes([len(seller_name.encode('utf-8'))]).hex() length = bytes([len(seller_name.encode('utf-8'))]).hex()
value = seller_name.encode('utf-8').hex() value = seller_name.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value])) tlv_array.append(''.join([tag, length, value]))
# VAT Number # VAT Number
tax_id = frappe.db.get_value('Company', doc.company, 'tax_id') tax_id = frappe.db.get_value('Company', doc.company, 'tax_id')
if not tax_id: if not tax_id:
frappe.throw(_('Tax ID missing for {} in the company document').format(doc.company)) frappe.throw(_('Tax ID missing for {} in the company document').format(doc.company))
tag = bytes([2]).hex() tag = bytes([2]).hex()
length = bytes([len(tax_id)]).hex() length = bytes([len(tax_id)]).hex()
value = tax_id.encode('utf-8').hex() value = tax_id.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value])) tlv_array.append(''.join([tag, length, value]))
# Time Stamp # Time Stamp
posting_date = getdate(doc.posting_date) posting_date = getdate(doc.posting_date)
time = get_time(doc.posting_time) time = get_time(doc.posting_time)
seconds = time.hour * 60 * 60 + time.minute * 60 + time.second seconds = time.hour * 60 * 60 + time.minute * 60 + time.second
time_stamp = add_to_date(posting_date, seconds=seconds) time_stamp = add_to_date(posting_date, seconds=seconds)
time_stamp = time_stamp.strftime('%Y-%m-%dT%H:%M:%SZ') time_stamp = time_stamp.strftime('%Y-%m-%dT%H:%M:%SZ')
tag = bytes([3]).hex() tag = bytes([3]).hex()
length = bytes([len(time_stamp)]).hex() length = bytes([len(time_stamp)]).hex()
value = time_stamp.encode('utf-8').hex() value = time_stamp.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value])) tlv_array.append(''.join([tag, length, value]))
# Invoice Amount # Invoice Amount
invoice_amount = str(doc.grand_total) invoice_amount = str(doc.grand_total)
tag = bytes([4]).hex() tag = bytes([4]).hex()
length = bytes([len(invoice_amount)]).hex() length = bytes([len(invoice_amount)]).hex()
value = invoice_amount.encode('utf-8').hex() value = invoice_amount.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value])) tlv_array.append(''.join([tag, length, value]))
# VAT Amount # VAT Amount
vat_amount = str(doc.total_taxes_and_charges) vat_amount = str(doc.total_taxes_and_charges)
tag = bytes([5]).hex() tag = bytes([5]).hex()
length = bytes([len(vat_amount)]).hex() length = bytes([len(vat_amount)]).hex()
value = vat_amount.encode('utf-8').hex() value = vat_amount.encode('utf-8').hex()
tlv_array.append(''.join([tag, length, value])) tlv_array.append(''.join([tag, length, value]))
# Joining bytes into one # Joining bytes into one
tlv_buff = ''.join(tlv_array) tlv_buff = ''.join(tlv_array)
# base64 conversion for QR Code # base64 conversion for QR Code
base64_string = b64encode(bytes.fromhex(tlv_buff)).decode() base64_string = b64encode(bytes.fromhex(tlv_buff)).decode()
qr_image = io.BytesIO() qr_image = io.BytesIO()
url = qr_create(base64_string, 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)
name = frappe.generate_hash(doc.name, 5) name = frappe.generate_hash(doc.name, 5)
# making file # making file
filename = f"QRCode-{name}.png".replace(os.path.sep, "__") filename = f"QRCode-{name}.png".replace(os.path.sep, "__")
_file = frappe.get_doc({ _file = frappe.get_doc({
"doctype": "File", "doctype": "File",
"file_name": filename, "file_name": filename,
"is_private": 0, "is_private": 0,
"content": qr_image.getvalue(), "content": qr_image.getvalue(),
"attached_to_doctype": doc.get("doctype"), "attached_to_doctype": doc.get("doctype"),
"attached_to_name": doc.get("name"), "attached_to_name": doc.get("name"),
"attached_to_field": "qr_code" "attached_to_field": "ksa_einv_qr"
}) })
_file.save() _file.save()
# assigning to document # assigning to document
doc.db_set('qr_code', _file.file_url) doc.db_set('ksa_einv_qr', _file.file_url)
doc.notify_update() doc.notify_update()
break
def delete_qr_code_file(doc, method): def delete_qr_code_file(doc, method=None):
"""Delete QR Code on deleted sales invoice"""
region = get_region(doc.company) region = get_region(doc.company)
if region not in ['Saudi Arabia']: if region not in ['Saudi Arabia']:
return return
if hasattr(doc, 'qr_code'): if hasattr(doc, 'ksa_einv_qr'):
if doc.get('qr_code'): if doc.get('ksa_einv_qr'):
file_doc = frappe.get_list('File', { file_doc = frappe.get_list('File', {
'file_url': doc.get('qr_code') 'file_url': doc.get('ksa_einv_qr')
}) })
if len(file_doc): if len(file_doc):
frappe.delete_doc('File', file_doc[0].name) frappe.delete_doc('File', file_doc[0].name)
@ -143,5 +145,6 @@ def delete_vat_settings_for_company(doc, method):
if doc.country != 'Saudi Arabia': if doc.country != 'Saudi Arabia':
return return
settings_doc = frappe.get_doc('KSA VAT Setting', {'company': doc.name}) settings_doc = frappe.get_all('KSA VAT Setting', filters={'company': doc.name}, pluck='name')
settings_doc.delete() for settings in settings_doc:
frappe.delete_doc('KSA VAT Setting', settings)