mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-31 10:49:09 +00:00
chore: remove unwanted fuctions
This commit is contained in:
@@ -9,196 +9,113 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
|
|
||||||
const { docstatus, irn, irn_cancelled, ewaybill, eway_bill_cancelled, doctype, name, __unsaved } = frm.doc;
|
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) {
|
if (docstatus == 0 && !irn && !__unsaved) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(
|
||||||
"Download E-Invoice",
|
__("Generate IRN"),
|
||||||
() => {
|
() => {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'erpnext.regional.india.e_invoice.utils.make_einvoice',
|
method: 'erpnext.regional.india.e_invoice.utils.generate_irn',
|
||||||
args: { doctype, name },
|
args: { doctype: doctype, name: name },
|
||||||
freeze: true,
|
freeze: true,
|
||||||
callback: (res) => {
|
callback: () => frm.reload_doc()
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}, "E-Invoicing");
|
},
|
||||||
frm.add_custom_button(
|
__("E Invoicing")
|
||||||
"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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (docstatus == 1 && irn && !irn_cancelled) {
|
if (docstatus == 1 && irn && !irn_cancelled) {
|
||||||
frm.add_custom_button(
|
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({
|
const d = new frappe.ui.Dialog({
|
||||||
title: __('Cancel IRN'),
|
title: __("Cancel IRN"),
|
||||||
fields: [
|
fields: 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
|
|
||||||
}
|
|
||||||
],
|
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
const data = d.get_values();
|
const data = d.get_values();
|
||||||
const args = {
|
frappe.call({
|
||||||
cmd: 'erpnext.regional.india.e_invoice.utils.download_cancel_einvoice',
|
method: 'erpnext.regional.india.e_invoice.utils.cancel_irn',
|
||||||
irn: irn, reason: data.reason.split('-')[0], remark: data.remark, name: name
|
args: {
|
||||||
};
|
doctype: doctype,
|
||||||
open_url_post(frappe.request.url, args);
|
name: name,
|
||||||
d.hide();
|
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();
|
d.show();
|
||||||
}, "E-Invoicing");
|
},
|
||||||
|
__("E Invoicing")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (docstatus == 1 && irn && !irn_cancelled && !eway_bill_cancelled) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(
|
||||||
"Upload Cancel JSON",
|
__("Cancel E-Way Bill"),
|
||||||
() => {
|
() => {
|
||||||
new frappe.ui.FileUploader({
|
const fields = [
|
||||||
method: 'erpnext.regional.india.e_invoice.utils.upload_cancel_ack',
|
{
|
||||||
allow_multiple: 0,
|
"label" : "Reason",
|
||||||
doctype: doctype,
|
"fieldname": "reason",
|
||||||
docname: name,
|
"fieldtype": "Select",
|
||||||
on_success: (attachment, r) => {
|
"reqd": 1,
|
||||||
if (!r.exc) {
|
"default": "1-Duplicate",
|
||||||
frm.reload_doc();
|
"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")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,229 +47,6 @@ def validate_einvoice_fields(doc):
|
|||||||
elif doc.docstatus == 2 and doc._action == 'cancel' and not doc.irn_cancelled:
|
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'))
|
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 = ['<li>'+ d +'</li>' for d in errors]
|
|
||||||
frappe.throw(_("""<ul style='padding-left: 20px'>{}</ul>""").format(''.join(li)), title=_('API Request Failed'))
|
|
||||||
else:
|
|
||||||
frappe.throw(errors[0], title=_('API Request Failed'))
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
def read_json(name):
|
def read_json(name):
|
||||||
file_path = os.path.join(os.path.dirname(__file__), '{name}.json'.format(name=name))
|
file_path = os.path.join(os.path.dirname(__file__), '{name}.json'.format(name=name))
|
||||||
with open(file_path, 'r') as f:
|
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_invoice', dec_signed_invoice)
|
||||||
frappe.db.set_value(doctype, name, 'signed_qr_code', res.get('SignedQRCode'))
|
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):
|
def attach_qrcode_image(doctype, name):
|
||||||
qrcode = frappe.db.get_value(doctype, name, 'signed_qr_code')
|
qrcode = frappe.db.get_value(doctype, name, 'signed_qr_code')
|
||||||
|
|||||||
Reference in New Issue
Block a user