Skip to content

Commit

Permalink
feat(india): generate qrcode button for e-invoice (frappe#30939)
Browse files Browse the repository at this point in the history
  • Loading branch information
nextchamp-saqib authored and hrwX committed May 10, 2022
1 parent 69e7a1f commit 51ae70c
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2648,6 +2648,7 @@ def test_einvoice_submission_without_irn(self):
# reset
einvoice_settings = frappe.get_doc("E Invoice Settings")
einvoice_settings.enable = 0
einvoice_settings.save()
frappe.flags.country = country

def test_einvoice_json(self):
Expand Down
23 changes: 23 additions & 0 deletions erpnext/regional/india/e_invoice/einvoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,29 @@ erpnext.setup_einvoice_actions = (doctype) => {
};
add_custom_button(__("Cancel E-Way Bill"), action);
}

if (irn && !irn_cancelled) {
const action = () => {
const dialog = frappe.msgprint({
title: __("Generate QRCode"),
message: __("Generate and attach QR Code using IRN?"),
primary_action: {
action: function() {
frappe.call({
method: 'erpnext.regional.india.e_invoice.utils.generate_qrcode',
args: { doctype, docname: name },
freeze: true,
callback: () => frm.reload_doc() || dialog.hide(),
error: () => dialog.hide()
});
}
},
primary_action_label: __('Yes')
});
dialog.show();
};
add_custom_button(__("Generate QRCode"), action);
}
}
});
};
Expand Down
57 changes: 49 additions & 8 deletions erpnext/regional/india/e_invoice/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,7 @@ def __init__(self, doctype=None, docname=None):
self.gstin_details_url = self.base_url + "/enriched/ei/api/master/gstin"
self.cancel_ewaybill_url = self.base_url + "/enriched/ei/api/ewayapi"
self.generate_ewaybill_url = self.base_url + "/enriched/ei/api/ewaybill"
self.get_qrcode_url = self.base_url + "/enriched/ei/others/qr/image"

def set_invoice(self):
self.invoice = None
Expand Down Expand Up @@ -857,8 +858,8 @@ def make_request(self, request_type, url, headers=None, data=None):
return res

def auto_refresh_token(self):
self.fetch_auth_token()
self.token_auto_refreshed = True
self.fetch_auth_token()

def log_request(self, url, headers, data, res):
headers.update({"password": self.credentials.password})
Expand Down Expand Up @@ -998,6 +999,37 @@ def bulk_generate_irn(invoices):

return failed

def fetch_and_attach_qrcode_from_irn(self):
qrcode = self.get_qrcode_from_irn(self.invoice.irn)
if qrcode:
qrcode_file = self.create_qr_code_file(qrcode)
frappe.db.set_value("Sales Invoice", self.invoice.name, "qrcode_image", qrcode_file.file_url)
frappe.msgprint(_("QR Code attached to the invoice"), alert=True)
else:
frappe.msgprint(_("QR Code not found for the IRN"), alert=True)

def get_qrcode_from_irn(self, irn):
import requests

headers = self.get_headers()
headers.update({"width": "215", "height": "215", "imgtype": "jpg", "irn": irn})

try:
# using requests.get instead of make_request to avoid parsing the response
res = requests.get(self.get_qrcode_url, headers=headers)
self.log_request(self.get_qrcode_url, headers, None, None)
if res.status_code == 200:
return res.content
else:
raise RequestFailed(str(res.content, "utf-8"))

except RequestFailed as e:
self.raise_error(errors=str(e))

except Exception:
log_error()
self.raise_error()

def get_irn_details(self, irn):
headers = self.get_headers()

Expand Down Expand Up @@ -1198,8 +1230,6 @@ def sanitize_error_message(self, message):
return errors

def raise_error(self, raise_exception=False, errors=None):
if errors is None:
errors = []
title = _("E Invoice Request Failed")
if errors:
frappe.throw(errors, title=title, as_list=1)
Expand Down Expand Up @@ -1240,13 +1270,18 @@ def set_einvoice_data(self, res):

def attach_qrcode_image(self):
qrcode = self.invoice.signed_qr_code
doctype = self.invoice.doctype
docname = self.invoice.name
filename = "QRCode_{}.png".format(docname).replace(os.path.sep, "__")

qr_image = io.BytesIO()
url = qrcreate(qrcode, error="L")
url.png(qr_image, scale=2, quiet_zone=1)
qrcode_file = self.create_qr_code_file(qr_image.getvalue())
self.invoice.qrcode_image = qrcode_file.file_url

def create_qr_code_file(self, qr_image):
doctype = self.invoice.doctype
docname = self.invoice.name
filename = "QRCode_{}.png".format(docname).replace(os.path.sep, "__")

_file = frappe.get_doc(
{
"doctype": "File",
Expand All @@ -1255,12 +1290,12 @@ def attach_qrcode_image(self):
"attached_to_name": docname,
"attached_to_field": "qrcode_image",
"is_private": 0,
"content": qr_image.getvalue(),
"content": qr_image,
}
)
_file.save()
frappe.db.commit()
self.invoice.qrcode_image = _file.file_url
return _file

def update_invoice(self):
self.invoice.flags.ignore_validate_update_after_submit = True
Expand Down Expand Up @@ -1305,6 +1340,12 @@ def cancel_irn(doctype, docname, irn, reason, remark):
gsp_connector.cancel_irn(irn, reason, remark)


@frappe.whitelist()
def generate_qrcode(doctype, docname):
gsp_connector = GSPConnector(doctype, docname)
gsp_connector.fetch_and_attach_qrcode_from_irn()


@frappe.whitelist()
def generate_eway_bill(doctype, docname, **kwargs):
gsp_connector = GSPConnector(doctype, docname)
Expand Down

0 comments on commit 51ae70c

Please sign in to comment.