From 6dcf334199a91b97f6c27c2ab1c72f01440213fe Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Wed, 4 Nov 2020 11:45:24 +0530 Subject: [PATCH] chore: remove unwanted fuctions --- erpnext/regional/india/e_invoice/einvoice.js | 257 ++++++------------ erpnext/regional/india/e_invoice/utils.py | 267 ------------------- 2 files changed, 87 insertions(+), 437 deletions(-) diff --git a/erpnext/regional/india/e_invoice/einvoice.js b/erpnext/regional/india/e_invoice/einvoice.js index e6fccbd7be4..e0db6c44e69 100644 --- a/erpnext/regional/india/e_invoice/einvoice.js +++ b/erpnext/regional/india/e_invoice/einvoice.js @@ -9,196 +9,113 @@ erpnext.setup_einvoice_actions = (doctype) => { const { docstatus, irn, irn_cancelled, ewaybill, eway_bill_cancelled, doctype, name, __unsaved } = frm.doc; - // if (docstatus == 0 && !irn && !__unsaved) { - // frm.add_custom_button( - // _("Generate IRN"), - // () => { - // frappe.call({ - // method: 'erpnext.regional.india.e_invoice.e_invoice_utils.generate_irn', - // args: { doctype: doctype, name: name }, - // freeze: true, - // callback: () => frm.reload_doc() - // }) - // }, - // __("E Invoicing") - // ); - // } - - // if (docstatus == 1 && irn && !irn_cancelled) { - // frm.add_custom_button( - // __("Cancel IRN"), - // () => { - // const fields = [ - // { - // "label" : "Reason", - // "fieldname": "reason", - // "fieldtype": "Select", - // "reqd": 1, - // "default": "1-Duplicate", - // "options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"] - // }, - // { - // "label": "Remark", - // "fieldname": "remark", - // "fieldtype": "Data", - // "reqd": 1 - // } - // ]; - // const d = new frappe.ui.Dialog({ - // title: __("Cancel IRN"), - // fields: fields, - // primary_action: function() { - // const data = d.get_values(); - // frappe.call({ - // method: 'erpnext.regional.india.e_invoice.e_invoice_utils.cancel_irn', - // args: { - // doctype: doctype, - // name: name, - // irn: irn, - // reason: data.reason.split('-')[0], - // remark: data.remark - // }, - // freeze: true, - // callback: () => frm.reload_doc() || d.hide(), - // error: () => d.hide() - // }); - // }, - // primary_action_label: __('Submit') - // }); - // d.show(); - // }, - // __("E Invoicing") - // ) - // } - - // if (docstatus == 1 && irn && !irn_cancelled && !eway_bill_cancelled) { - // frm.add_custom_button( - // __("Cancel E-Way Bill"), - // () => { - // const fields = [ - // { - // "label" : "Reason", - // "fieldname": "reason", - // "fieldtype": "Select", - // "reqd": 1, - // "default": "1-Duplicate", - // "options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"] - // }, - // { - // "label": "Remark", - // "fieldname": "remark", - // "fieldtype": "Data", - // "reqd": 1 - // } - // ] - // const d = new frappe.ui.Dialog({ - // title: __('Cancel E-Way Bill'), - // fields: fields, - // primary_action: function() { - // const data = d.get_values(); - // frappe.call({ - // method: 'erpnext.regional.india.e_invoice.e_invoice_utils.cancel_eway_bill', - // args: { - // doctype: doctype, - // name: name, - // eway_bill: ewaybill, - // reason: data.reason.split('-')[0], - // remark: data.remark - // }, - // freeze: true, - // callback: () => frm.reload_doc() || d.hide(), - // error: () => d.hide() - // }) - // }, - // primary_action_label: __('Submit') - // }); - // d.show(); - // }, - // __("E Invoicing") - // ); - // } - if (docstatus == 0 && !irn && !__unsaved) { frm.add_custom_button( - "Download E-Invoice", + __("Generate IRN"), () => { frappe.call({ - method: 'erpnext.regional.india.e_invoice.utils.make_einvoice', - args: { doctype, name }, + method: 'erpnext.regional.india.e_invoice.utils.generate_irn', + args: { doctype: doctype, name: name }, freeze: true, - callback: (res) => { - if (!res.exc) { - const args = { - cmd: 'erpnext.regional.india.e_invoice.utils.download_einvoice', - einvoice: JSON.stringify([res.message]), - name: name - }; - open_url_post(frappe.request.url, args); - } - } + callback: () => frm.reload_doc() }) - }, "E-Invoicing"); - frm.add_custom_button( - "Upload Signed E-Invoice", - () => { - new frappe.ui.FileUploader({ - method: 'erpnext.regional.india.e_invoice.utils.upload_einvoice', - allow_multiple: 0, - doctype: doctype, - docname: name, - on_success: (attachment, r) => { - if (!r.exc) { - frm.reload_doc(); - } - } - }); - }, "E-Invoicing"); + }, + __("E Invoicing") + ); } + if (docstatus == 1 && irn && !irn_cancelled) { frm.add_custom_button( - "Cancel IRN", + __("Cancel IRN"), () => { + const fields = [ + { + "label" : "Reason", + "fieldname": "reason", + "fieldtype": "Select", + "reqd": 1, + "default": "1-Duplicate", + "options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"] + }, + { + "label": "Remark", + "fieldname": "remark", + "fieldtype": "Data", + "reqd": 1 + } + ]; const d = new frappe.ui.Dialog({ - title: __('Cancel IRN'), - fields: [ - { - "label" : "Reason", "fieldname": "reason", - "fieldtype": "Select", "reqd": 1, "default": "1-Duplicate", - "options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"] - }, - { - "label": "Remark", "fieldname": "remark", "fieldtype": "Data", "reqd": 1 - } - ], + title: __("Cancel IRN"), + fields: fields, primary_action: function() { const data = d.get_values(); - const args = { - cmd: 'erpnext.regional.india.e_invoice.utils.download_cancel_einvoice', - irn: irn, reason: data.reason.split('-')[0], remark: data.remark, name: name - }; - open_url_post(frappe.request.url, args); - d.hide(); + frappe.call({ + method: 'erpnext.regional.india.e_invoice.utils.cancel_irn', + args: { + doctype: doctype, + name: name, + irn: irn, + reason: data.reason.split('-')[0], + remark: data.remark + }, + freeze: true, + callback: () => frm.reload_doc() || d.hide(), + error: () => d.hide() + }); }, - primary_action_label: __('Download JSON') + primary_action_label: __('Submit') }); d.show(); - }, "E-Invoicing"); - + }, + __("E Invoicing") + ) + } + + if (docstatus == 1 && irn && !irn_cancelled && !eway_bill_cancelled) { frm.add_custom_button( - "Upload Cancel JSON", + __("Cancel E-Way Bill"), () => { - new frappe.ui.FileUploader({ - method: 'erpnext.regional.india.e_invoice.utils.upload_cancel_ack', - allow_multiple: 0, - doctype: doctype, - docname: name, - on_success: (attachment, r) => { - if (!r.exc) { - frm.reload_doc(); - } + const fields = [ + { + "label" : "Reason", + "fieldname": "reason", + "fieldtype": "Select", + "reqd": 1, + "default": "1-Duplicate", + "options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"] + }, + { + "label": "Remark", + "fieldname": "remark", + "fieldtype": "Data", + "reqd": 1 } + ] + const d = new frappe.ui.Dialog({ + title: __('Cancel E-Way Bill'), + fields: fields, + primary_action: function() { + const data = d.get_values(); + frappe.call({ + method: 'erpnext.regional.india.e_invoice.utils.cancel_eway_bill', + args: { + doctype: doctype, + name: name, + eway_bill: ewaybill, + reason: data.reason.split('-')[0], + remark: data.remark + }, + freeze: true, + callback: () => frm.reload_doc() || d.hide(), + error: () => d.hide() + }) + }, + primary_action_label: __('Submit') }); - }, "E-Invoicing"); + d.show(); + }, + __("E Invoicing") + ); } } }) diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py index 7250c7e75a5..2a174202968 100644 --- a/erpnext/regional/india/e_invoice/utils.py +++ b/erpnext/regional/india/e_invoice/utils.py @@ -47,229 +47,6 @@ def validate_einvoice_fields(doc): elif doc.docstatus == 2 and doc._action == 'cancel' and not doc.irn_cancelled: frappe.throw(_('You must cancel IRN before cancelling the document.'), title=_('Cancel Not Allowed')) -def get_credentials(): - doc = frappe.get_doc('E Invoice Settings') - if not doc.enable: - frappe.throw(_("To setup E Invoicing you need to enable E Invoice Settings first."), title=_("E Invoicing Disabled")) - - if not doc.token_expiry or time_diff_in_seconds(now_datetime(), doc.token_expiry) > 5.0: - fetch_token(doc) - doc.load_from_db() - - return doc - -def rsa_encrypt(msg, key): - if not (isinstance(msg, bytes) or isinstance(msg, bytearray)): - msg = str.encode(msg) - - rsa_pub_key = RSA.import_key(key) - cipher = PKCS1_v1_5.new(rsa_pub_key) - enc_msg = cipher.encrypt(msg) - b64_enc_msg = base64.b64encode(enc_msg) - return b64_enc_msg.decode() - -def aes_decrypt(enc_msg, key): - encode_as_b64 = True - if not (isinstance(key, bytes) or isinstance(key, bytearray)): - key = base64.b64decode(key) - encode_as_b64 = False - - cipher = AES.new(key, AES.MODE_ECB) - b64_enc_msg = base64.b64decode(enc_msg) - msg_bytes = cipher.decrypt(b64_enc_msg) - msg_bytes = unpad(msg_bytes, AES.block_size) # due to ECB/PKCS5Padding - if encode_as_b64: - msg_bytes = base64.b64encode(msg_bytes) - return msg_bytes.decode() - -def aes_encrypt(msg, key): - if not (isinstance(key, bytes) or isinstance(key, bytearray)): - key = base64.b64decode(key) - - cipher = AES.new(key, AES.MODE_ECB) - bytes_msg = str.encode(msg) - padded_bytes_msg = pad(bytes_msg, AES.block_size) - enc_msg = cipher.encrypt(padded_bytes_msg) - b64_enc_msg = base64.b64encode(enc_msg) - return b64_enc_msg.decode() - -def jwt_decrypt(token): - return jwt.decode(token, verify=False) - -def get_header(creds): - headers = { 'content-type': 'application/json' } - headers.update(dict(client_id=creds.client_id, client_secret=creds.client_secret, user_name=creds.username)) - headers.update(dict(Gstin=creds.gstin, AuthToken=creds.auth_token)) - return headers - -@frappe.whitelist() -def fetch_token(credentials=None): - if not credentials: - credentials = frappe.get_doc('E Invoice Settings') - - endpoint = 'https://einv-apisandbox.nic.in/eivital/v1.03/auth' - headers = { 'content-type': 'application/json' } - headers.update(dict(client_id=credentials.client_id, client_secret=credentials.client_secret)) - payload = dict(UserName=credentials.username, ForceRefreshAccessToken=bool(credentials.auto_refresh_token)) - - appkey = bytearray(os.urandom(32)) - enc_appkey = rsa_encrypt(appkey, credentials.public_key) - - password = credentials.get_password(fieldname='password') - enc_password = rsa_encrypt(password, credentials.public_key) - - payload.update(dict(Password=enc_password, AppKey=enc_appkey)) - - res = make_post_request(endpoint, headers=headers, data=json.dumps({ 'data': payload })) - handle_err_response(res) - - auth_token, token_expiry, sek = extract_token_and_sek(res, appkey) - - credentials.auth_token = auth_token - credentials.token_expiry = get_datetime(token_expiry) - credentials.sek = sek - credentials.save() - -def extract_token_and_sek(response, appkey): - data = response.get('Data') - auth_token = data.get('AuthToken') - token_expiry = data.get('TokenExpiry') - enc_sek = data.get('Sek') - sek = aes_decrypt(enc_sek, appkey) - return auth_token, token_expiry, sek - -def attach_signed_invoice(doctype, name, data): - f = frappe.get_doc({ - 'doctype': 'File', - 'file_name': 'E-INV--{}.json'.format(name), - 'attached_to_doctype': doctype, - 'attached_to_name': name, - 'content': json.dumps(data), - 'is_private': True - }).insert() - -def get_gstin_details(gstin): - credentials = get_credentials() - - endpoint = 'https://einv-apisandbox.nic.in/eivital/v1.03/Master/gstin/{gstin}'.format(gstin=gstin) - headers = get_header(credentials) - - res = make_get_request(endpoint, headers=headers) - handle_err_response(res) - - enc_details = res.get('Data') - json_str = aes_decrypt(enc_details, credentials.sek) - details = json.loads(json_str) - - return details - -@frappe.whitelist() -def generate_irn(doctype, name): - endpoint = 'https://einv-apisandbox.nic.in/eicore/v1.03/Invoice' - credentials = get_credentials() - headers = get_header(credentials) - - einvoice = make_einvoice(doctype, name) - einvoice = json.dumps(einvoice) - - enc_einvoice_json = aes_encrypt(einvoice, credentials.sek) - payload = dict(Data=enc_einvoice_json) - - res = make_post_request(endpoint, headers=headers, data=json.dumps(payload)) - res = handle_err_response(res) - - enc_json = res.get('Data') - json_str = aes_decrypt(enc_json, credentials.sek) - - signed_einvoice = json.loads(json_str) - decrypt_irn_response(signed_einvoice) - - update_einvoice_fields(doctype, name, signed_einvoice) - - attach_qrcode_image(doctype, name) - attach_signed_invoice(doctype, name, signed_einvoice['DecryptedSignedInvoice']) - - return signed_einvoice - -def get_irn_details(irn): - credentials = get_credentials() - - endpoint = 'https://einv-apisandbox.nic.in/eicore/v1.03/Invoice/irn/{irn}'.format(irn=irn) - headers = get_header(credentials) - - res = make_get_request(endpoint, headers=headers) - handle_err_response(res) - - return res - -@frappe.whitelist() -def cancel_irn(doctype, name, irn, reason, remark=''): - credentials = get_credentials() - - endpoint = 'https://einv-apisandbox.nic.in/eicore/v1.03/Invoice/Cancel' - headers = get_header(credentials) - - cancel_einv = json.dumps(dict(Irn=irn, CnlRsn=reason, CnlRem=remark)) - enc_json = aes_encrypt(cancel_einv, credentials.sek) - payload = dict(Data=enc_json) - - res = make_post_request(endpoint, headers=headers, data=json.dumps(payload)) - handle_err_response(res) - - frappe.db.set_value(doctype, name, 'irn_cancelled', 1) - - return res - -@frappe.whitelist() -def cancel_eway_bill(doctype, name, eway_bill, reason, remark=''): - credentials = get_credentials() - endpoint = 'https://einv-apisandbox.nic.in/ewaybillapi/v1.03/ewayapi' - headers = get_header(credentials) - - cancel_eway_bill_json = json.dumps(dict(ewbNo=eway_bill, cancelRsnCode=reason, cancelRmrk=remark)) - enc_json = aes_encrypt(cancel_eway_bill_json, credentials.sek) - payload = dict(action='CANEWB', Data=enc_json) - - res = make_post_request(endpoint, headers=headers, data=json.dumps(payload)) - handle_err_response(res) - - frappe.db.set_value(doctype, name, 'ewaybill', '') - frappe.db.set_value(doctype, name, 'eway_bill_cancelled', 1) - - return res - -def decrypt_irn_response(data): - enc_signed_invoice = data['SignedInvoice'] - enc_signed_qr_code = data['SignedQRCode'] - signed_invoice = jwt_decrypt(enc_signed_invoice)['data'] - signed_qr_code = jwt_decrypt(enc_signed_qr_code)['data'] - data['DecryptedSignedInvoice'] = json.loads(signed_invoice) - data['DecryptedSignedQRCode'] = json.loads(signed_qr_code) - -def handle_err_response(response): - if response.get('Status') == 0: - err_details = response.get('ErrorDetails') - errors = [] - for d in err_details: - err_code = d.get('ErrorCode') - - if err_code == '2150': - irn = [d['Desc']['Irn'] for d in response.get('InfoDtls') if d['InfCd'] == 'DUPIRN'] - response = get_irn_details(irn[0]) - return response - - errors.append(d.get('ErrorMessage')) - - if errors: - frappe.log_error(title="E Invoice API Request Failed", message=json.dumps(errors, default=str, indent=4)) - if len(errors) > 1: - li = ['
  • '+ d +'
  • ' for d in errors] - frappe.throw(_("""""").format(''.join(li)), title=_('API Request Failed')) - else: - frappe.throw(errors[0], title=_('API Request Failed')) - - return response - def read_json(name): file_path = os.path.join(os.path.dirname(__file__), '{name}.json'.format(name=name)) with open(file_path, 'r') as f: @@ -568,50 +345,6 @@ def update_invoice(invoice, res): frappe.db.set_value(doctype, name, 'signed_invoice', dec_signed_invoice) frappe.db.set_value(doctype, name, 'signed_qr_code', res.get('SignedQRCode')) -@frappe.whitelist() -def download_einvoice(): - data = frappe._dict(frappe.local.form_dict) - einvoice = data['einvoice'] - name = data['name'] - - frappe.response['filename'] = 'E-Invoice-' + name + '.json' - frappe.response['filecontent'] = einvoice - frappe.response['content_type'] = 'application/json' - frappe.response['type'] = 'download' - -@frappe.whitelist() -def upload_einvoice(): - signed_einvoice = json.loads(frappe.local.uploaded_file) - data = frappe._dict(frappe.local.form_dict) - doctype = data['doctype'] - name = data['docname'] - - update_einvoice_fields(doctype, name, signed_einvoice) - attach_qrcode_image(doctype, name) - -@frappe.whitelist() -def download_cancel_einvoice(): - data = frappe._dict(frappe.local.form_dict) - name = data['name'] - irn = data['irn'] - reason = data['reason'] - remark = data['remark'] - - cancel_einvoice = json.dumps([dict(Irn=irn, CnlRsn=reason, CnlRem=remark)]) - - frappe.response['filename'] = 'Cancel E-Invoice ' + name + '.json' - frappe.response['filecontent'] = cancel_einvoice - frappe.response['content_type'] = 'application/json' - frappe.response['type'] = 'download' - -@frappe.whitelist() -def upload_cancel_ack(): - cancel_ack = json.loads(frappe.local.uploaded_file) - data = frappe._dict(frappe.local.form_dict) - doctype = data['doctype'] - name = data['docname'] - - frappe.db.set_value(doctype, name, 'irn_cancelled', 1) def attach_qrcode_image(doctype, name): qrcode = frappe.db.get_value(doctype, name, 'signed_qr_code')