feat(india): generate qrcode button for e-invoice (#30939)
This commit is contained in:
parent
51fcbe5826
commit
cf13a20438
@ -2648,6 +2648,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
# reset
|
# reset
|
||||||
einvoice_settings = frappe.get_doc("E Invoice Settings")
|
einvoice_settings = frappe.get_doc("E Invoice Settings")
|
||||||
einvoice_settings.enable = 0
|
einvoice_settings.enable = 0
|
||||||
|
einvoice_settings.save()
|
||||||
frappe.flags.country = country
|
frappe.flags.country = country
|
||||||
|
|
||||||
def test_einvoice_json(self):
|
def test_einvoice_json(self):
|
||||||
|
@ -204,6 +204,29 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
};
|
};
|
||||||
add_custom_button(__("Cancel E-Way Bill"), action);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -794,6 +794,7 @@ class GSPConnector:
|
|||||||
self.gstin_details_url = self.base_url + "/enriched/ei/api/master/gstin"
|
self.gstin_details_url = self.base_url + "/enriched/ei/api/master/gstin"
|
||||||
self.cancel_ewaybill_url = self.base_url + "/enriched/ei/api/ewayapi"
|
self.cancel_ewaybill_url = self.base_url + "/enriched/ei/api/ewayapi"
|
||||||
self.generate_ewaybill_url = self.base_url + "/enriched/ei/api/ewaybill"
|
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):
|
def set_invoice(self):
|
||||||
self.invoice = None
|
self.invoice = None
|
||||||
@ -857,8 +858,8 @@ class GSPConnector:
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
def auto_refresh_token(self):
|
def auto_refresh_token(self):
|
||||||
self.fetch_auth_token()
|
|
||||||
self.token_auto_refreshed = True
|
self.token_auto_refreshed = True
|
||||||
|
self.fetch_auth_token()
|
||||||
|
|
||||||
def log_request(self, url, headers, data, res):
|
def log_request(self, url, headers, data, res):
|
||||||
headers.update({"password": self.credentials.password})
|
headers.update({"password": self.credentials.password})
|
||||||
@ -998,6 +999,37 @@ class GSPConnector:
|
|||||||
|
|
||||||
return failed
|
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):
|
def get_irn_details(self, irn):
|
||||||
headers = self.get_headers()
|
headers = self.get_headers()
|
||||||
|
|
||||||
@ -1198,8 +1230,6 @@ class GSPConnector:
|
|||||||
return errors
|
return errors
|
||||||
|
|
||||||
def raise_error(self, raise_exception=False, errors=None):
|
def raise_error(self, raise_exception=False, errors=None):
|
||||||
if errors is None:
|
|
||||||
errors = []
|
|
||||||
title = _("E Invoice Request Failed")
|
title = _("E Invoice Request Failed")
|
||||||
if errors:
|
if errors:
|
||||||
frappe.throw(errors, title=title, as_list=1)
|
frappe.throw(errors, title=title, as_list=1)
|
||||||
@ -1240,13 +1270,18 @@ class GSPConnector:
|
|||||||
|
|
||||||
def attach_qrcode_image(self):
|
def attach_qrcode_image(self):
|
||||||
qrcode = self.invoice.signed_qr_code
|
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()
|
qr_image = io.BytesIO()
|
||||||
url = qrcreate(qrcode, error="L")
|
url = qrcreate(qrcode, error="L")
|
||||||
url.png(qr_image, scale=2, quiet_zone=1)
|
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(
|
_file = frappe.get_doc(
|
||||||
{
|
{
|
||||||
"doctype": "File",
|
"doctype": "File",
|
||||||
@ -1255,12 +1290,12 @@ class GSPConnector:
|
|||||||
"attached_to_name": docname,
|
"attached_to_name": docname,
|
||||||
"attached_to_field": "qrcode_image",
|
"attached_to_field": "qrcode_image",
|
||||||
"is_private": 0,
|
"is_private": 0,
|
||||||
"content": qr_image.getvalue(),
|
"content": qr_image,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
_file.save()
|
_file.save()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
self.invoice.qrcode_image = _file.file_url
|
return _file
|
||||||
|
|
||||||
def update_invoice(self):
|
def update_invoice(self):
|
||||||
self.invoice.flags.ignore_validate_update_after_submit = True
|
self.invoice.flags.ignore_validate_update_after_submit = True
|
||||||
@ -1305,6 +1340,12 @@ def cancel_irn(doctype, docname, irn, reason, remark):
|
|||||||
gsp_connector.cancel_irn(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()
|
@frappe.whitelist()
|
||||||
def generate_eway_bill(doctype, docname, **kwargs):
|
def generate_eway_bill(doctype, docname, **kwargs):
|
||||||
gsp_connector = GSPConnector(doctype, docname)
|
gsp_connector = GSPConnector(doctype, docname)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user