mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-21 22:19:18 +00:00
feat: update timeline on einvoice actions
This commit is contained in:
@@ -33,3 +33,4 @@ def execute():
|
|||||||
|
|
||||||
frappe.db.set_value('Custom Field', { 'fieldname': 'mode_of_transport' }, 'default', '')
|
frappe.db.set_value('Custom Field', { 'fieldname': 'mode_of_transport' }, 'default', '')
|
||||||
frappe.db.set_value('Custom Field', { 'fieldname': 'vehicle_no' }, 'depends_on', 'eval:doc.mode_of_transport == "Road"')
|
frappe.db.set_value('Custom Field', { 'fieldname': 'vehicle_no' }, 'depends_on', 'eval:doc.mode_of_transport == "Road"')
|
||||||
|
frappe.db.set_value('Custom Field', { 'fieldname': 'ewaybill' }, 'depends_on', 'eval:((doc.docstatus === 1 || doc.ewaybill) && doc.eway_bill_cancelled === 0)')
|
||||||
@@ -7,7 +7,13 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
|
|
||||||
if (!einvoicing_enabled || !valid_supply_type) return;
|
if (!einvoicing_enabled || !valid_supply_type) return;
|
||||||
|
|
||||||
const { docstatus, irn, irn_cancelled, ewaybill, eway_bill_cancelled, name, __unsaved } = frm.doc;
|
const { doctype, docstatus, irn, irn_cancelled, ewaybill, eway_bill_cancelled, name, __unsaved } = frm.doc;
|
||||||
|
|
||||||
|
const add_custom_button = (label, action) => {
|
||||||
|
if (!frm.custom_buttons[label]) {
|
||||||
|
frm.add_custom_button(label, action, __('E Invoicing'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ewaybill && irn) {
|
if (ewaybill && irn) {
|
||||||
frm.set_df_property('ewaybill', 'read_only', 1);
|
frm.set_df_property('ewaybill', 'read_only', 1);
|
||||||
@@ -17,13 +23,13 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
const action = () => {
|
const action = () => {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'erpnext.regional.india.e_invoice.utils.generate_irn',
|
method: 'erpnext.regional.india.e_invoice.utils.generate_irn',
|
||||||
args: { docname: name },
|
args: { doctype, docname: name },
|
||||||
freeze: true,
|
freeze: true,
|
||||||
callback: () => frm.reload_doc()
|
callback: () => frm.reload_doc()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
frm.add_custom_button(__("Generate IRN"), action, __('E Invoicing'));
|
add_custom_button(__("Generate IRN"), action);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (docstatus == 1 && irn && !irn_cancelled && !ewaybill) {
|
if (docstatus == 1 && irn && !irn_cancelled && !ewaybill) {
|
||||||
@@ -52,6 +58,7 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'erpnext.regional.india.e_invoice.utils.cancel_irn',
|
method: 'erpnext.regional.india.e_invoice.utils.cancel_irn',
|
||||||
args: {
|
args: {
|
||||||
|
doctype,
|
||||||
docname: name,
|
docname: name,
|
||||||
irn: irn,
|
irn: irn,
|
||||||
reason: data.reason.split('-')[0],
|
reason: data.reason.split('-')[0],
|
||||||
@@ -66,105 +73,23 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
});
|
});
|
||||||
d.show();
|
d.show();
|
||||||
};
|
};
|
||||||
frm.add_custom_button(__("Cancel IRN"), action, __("E Invoicing"));
|
add_custom_button(__("Cancel IRN"), action);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irn && !irn_cancelled && !ewaybill) {
|
if (irn && !irn_cancelled && !ewaybill) {
|
||||||
const fields = [
|
|
||||||
{
|
|
||||||
'fieldname': 'transporter',
|
|
||||||
'label': 'Transporter',
|
|
||||||
'fieldtype': 'Link',
|
|
||||||
'options': 'Supplier',
|
|
||||||
'default': frm.doc.transporter
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'gst_transporter_id',
|
|
||||||
'label': 'GST Transporter ID',
|
|
||||||
'fieldtype': 'Data',
|
|
||||||
'fetch_from': 'transporter.gst_transporter_id',
|
|
||||||
'default': frm.doc.gst_transporter_id
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'driver',
|
|
||||||
'label': 'Driver',
|
|
||||||
'fieldtype': 'Link',
|
|
||||||
'options': 'Driver',
|
|
||||||
'default': frm.doc.driver
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'lr_no',
|
|
||||||
'label': 'Transport Receipt No',
|
|
||||||
'fieldtype': 'Data',
|
|
||||||
'default': frm.doc.lr_no
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'vehicle_no',
|
|
||||||
'label': 'Vehicle No',
|
|
||||||
'fieldtype': 'Data',
|
|
||||||
'depends_on': 'eval:(doc.mode_of_transport === "Road")',
|
|
||||||
'default': frm.doc.vehicle_no
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'distance',
|
|
||||||
'label': 'Distance (in km)',
|
|
||||||
'fieldtype': 'Float',
|
|
||||||
'default': frm.doc.distance
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'transporter_col_break',
|
|
||||||
'fieldtype': 'Column Break',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'transporter_name',
|
|
||||||
'label': 'Transporter Name',
|
|
||||||
'fieldtype': 'Data',
|
|
||||||
'fetch_from': 'transporter.name',
|
|
||||||
'read_only': 1,
|
|
||||||
'default': frm.doc.transporter_name
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'mode_of_transport',
|
|
||||||
'label': 'Mode of Transport',
|
|
||||||
'fieldtype': 'Select',
|
|
||||||
'options': `\nRoad\nAir\nRail\nShip`,
|
|
||||||
'default': frm.doc.mode_of_transport
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'driver_name',
|
|
||||||
'label': 'Driver Name',
|
|
||||||
'fieldtype': 'Data',
|
|
||||||
'fetch_from': 'driver.full_name',
|
|
||||||
'read_only': 1,
|
|
||||||
'default': frm.doc.driver_name
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'lr_date',
|
|
||||||
'label': 'Transport Receipt Date',
|
|
||||||
'fieldtype': 'Date',
|
|
||||||
'default': frm.doc.lr_date
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'fieldname': 'gst_vehicle_type',
|
|
||||||
'label': 'GST Vehicle Type',
|
|
||||||
'fieldtype': 'Select',
|
|
||||||
'options': `Regular\nOver Dimensional Cargo (ODC)`,
|
|
||||||
'depends_on': 'eval:(doc.mode_of_transport === "Road")',
|
|
||||||
'default': frm.doc.gst_vehicle_type
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const action = () => {
|
const action = () => {
|
||||||
const d = new frappe.ui.Dialog({
|
const d = new frappe.ui.Dialog({
|
||||||
title: __('Generate E-Way Bill'),
|
title: __('Generate E-Way Bill'),
|
||||||
wide: 1,
|
wide: 1,
|
||||||
fields: fields,
|
fields: get_ewaybill_fields(frm),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
const data = d.get_values();
|
const data = d.get_values();
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'erpnext.regional.india.e_invoice.utils.generate_eway_bill',
|
method: 'erpnext.regional.india.e_invoice.utils.generate_eway_bill',
|
||||||
args: {
|
args: {
|
||||||
docname: name, irn,
|
doctype,
|
||||||
|
docname: name,
|
||||||
|
irn,
|
||||||
...data
|
...data
|
||||||
},
|
},
|
||||||
freeze: true,
|
freeze: true,
|
||||||
@@ -177,7 +102,7 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
d.show();
|
d.show();
|
||||||
};
|
};
|
||||||
|
|
||||||
frm.add_custom_button(__("Generate E-Way Bill"), action, __("E Invoicing"));
|
add_custom_button(__("Generate E-Way Bill"), action);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (docstatus == 1 && irn && ewaybill && !irn_cancelled && !eway_bill_cancelled) {
|
if (docstatus == 1 && irn && ewaybill && !irn_cancelled && !eway_bill_cancelled) {
|
||||||
@@ -206,6 +131,7 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'erpnext.regional.india.e_invoice.utils.cancel_eway_bill',
|
method: 'erpnext.regional.india.e_invoice.utils.cancel_eway_bill',
|
||||||
args: {
|
args: {
|
||||||
|
doctype,
|
||||||
docname: name,
|
docname: name,
|
||||||
eway_bill: ewaybill,
|
eway_bill: ewaybill,
|
||||||
reason: data.reason.split('-')[0],
|
reason: data.reason.split('-')[0],
|
||||||
@@ -220,8 +146,94 @@ erpnext.setup_einvoice_actions = (doctype) => {
|
|||||||
});
|
});
|
||||||
d.show();
|
d.show();
|
||||||
};
|
};
|
||||||
frm.add_custom_button(__("Cancel E-Way Bill"), action, __("E Invoicing"));
|
add_custom_button(__("Cancel E-Way Bill"), action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const get_ewaybill_fields = (frm) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'fieldname': 'transporter',
|
||||||
|
'label': 'Transporter',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Supplier',
|
||||||
|
'default': frm.doc.transporter
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'gst_transporter_id',
|
||||||
|
'label': 'GST Transporter ID',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'fetch_from': 'transporter.gst_transporter_id',
|
||||||
|
'default': frm.doc.gst_transporter_id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'driver',
|
||||||
|
'label': 'Driver',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Driver',
|
||||||
|
'default': frm.doc.driver
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'lr_no',
|
||||||
|
'label': 'Transport Receipt No',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'default': frm.doc.lr_no
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'vehicle_no',
|
||||||
|
'label': 'Vehicle No',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'depends_on': 'eval:(doc.mode_of_transport === "Road")',
|
||||||
|
'default': frm.doc.vehicle_no
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'distance',
|
||||||
|
'label': 'Distance (in km)',
|
||||||
|
'fieldtype': 'Float',
|
||||||
|
'default': frm.doc.distance
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'transporter_col_break',
|
||||||
|
'fieldtype': 'Column Break',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'transporter_name',
|
||||||
|
'label': 'Transporter Name',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'fetch_from': 'transporter.name',
|
||||||
|
'read_only': 1,
|
||||||
|
'default': frm.doc.transporter_name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'mode_of_transport',
|
||||||
|
'label': 'Mode of Transport',
|
||||||
|
'fieldtype': 'Select',
|
||||||
|
'options': `\nRoad\nAir\nRail\nShip`,
|
||||||
|
'default': frm.doc.mode_of_transport
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'driver_name',
|
||||||
|
'label': 'Driver Name',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'fetch_from': 'driver.full_name',
|
||||||
|
'read_only': 1,
|
||||||
|
'default': frm.doc.driver_name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'lr_date',
|
||||||
|
'label': 'Transport Receipt Date',
|
||||||
|
'fieldtype': 'Date',
|
||||||
|
'default': frm.doc.lr_date
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'gst_vehicle_type',
|
||||||
|
'label': 'GST Vehicle Type',
|
||||||
|
'fieldtype': 'Select',
|
||||||
|
'options': `Regular\nOver Dimensional Cargo (ODC)`,
|
||||||
|
'depends_on': 'eval:(doc.mode_of_transport === "Road")',
|
||||||
|
'default': frm.doc.gst_vehicle_type
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -240,9 +240,7 @@ def get_eway_bill_details(invoice):
|
|||||||
vehicle_type=vehicle_type[invoice.gst_vehicle_type]
|
vehicle_type=vehicle_type[invoice.gst_vehicle_type]
|
||||||
))
|
))
|
||||||
|
|
||||||
@frappe.whitelist()
|
def make_einvoice(invoice):
|
||||||
def make_einvoice(doctype, name):
|
|
||||||
invoice = frappe.get_doc(doctype, name)
|
|
||||||
schema = read_json('einv_template')
|
schema = read_json('einv_template')
|
||||||
|
|
||||||
trans_details = get_trans_details(invoice)
|
trans_details = get_trans_details(invoice)
|
||||||
@@ -255,7 +253,7 @@ def make_einvoice(doctype, name):
|
|||||||
buyer_details = get_overseas_address_details(invoice.customer_address)
|
buyer_details = get_overseas_address_details(invoice.customer_address)
|
||||||
else:
|
else:
|
||||||
buyer_details = get_party_details(invoice.customer_address)
|
buyer_details = get_party_details(invoice.customer_address)
|
||||||
place_of_supply = get_place_of_supply(invoice, doctype) or invoice.billing_address_gstin
|
place_of_supply = get_place_of_supply(invoice, invoice.doctype) or invoice.billing_address_gstin
|
||||||
place_of_supply = place_of_supply[:2]
|
place_of_supply = place_of_supply[:2]
|
||||||
buyer_details.update(dict(place_of_supply=place_of_supply))
|
buyer_details.update(dict(place_of_supply=place_of_supply))
|
||||||
|
|
||||||
@@ -351,42 +349,10 @@ def validate_einvoice(validations, einvoice, errors=[]):
|
|||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
def update_invoice(doctype, docname, res):
|
|
||||||
enc_signed_invoice = res.get('SignedInvoice')
|
|
||||||
dec_signed_invoice = jwt.decode(enc_signed_invoice, verify=False)['data']
|
|
||||||
|
|
||||||
frappe.db.set_value(doctype, docname, 'irn', res.get('Irn'))
|
|
||||||
frappe.db.set_value(doctype, docname, 'ewaybill', res.get('EwbNo'))
|
|
||||||
frappe.db.set_value(doctype, docname, 'signed_einvoice', dec_signed_invoice)
|
|
||||||
|
|
||||||
signed_qr_code = res.get('SignedQRCode')
|
|
||||||
frappe.db.set_value(doctype, docname, 'signed_qr_code', signed_qr_code)
|
|
||||||
|
|
||||||
attach_qrcode_image(doctype, docname, signed_qr_code)
|
|
||||||
|
|
||||||
def attach_qrcode_image(doctype, docname, qrcode):
|
|
||||||
if not qrcode: return
|
|
||||||
|
|
||||||
_file = frappe.new_doc('File')
|
|
||||||
_file.update({
|
|
||||||
'file_name': f'QRCode_{docname}.png',
|
|
||||||
'attached_to_doctype': doctype,
|
|
||||||
'attached_to_name': docname,
|
|
||||||
'content': 'qrcode',
|
|
||||||
'is_private': 1
|
|
||||||
})
|
|
||||||
_file.insert()
|
|
||||||
frappe.db.commit()
|
|
||||||
url = qrcreate(qrcode)
|
|
||||||
abs_file_path = os.path.abspath(_file.get_full_path())
|
|
||||||
url.png(abs_file_path, scale=2)
|
|
||||||
|
|
||||||
frappe.db.set_value(doctype, docname, 'qrcode_image', _file.file_url)
|
|
||||||
|
|
||||||
class ResponseFailure(Exception): pass
|
class ResponseFailure(Exception): pass
|
||||||
|
|
||||||
class GSPConnector():
|
class GSPConnector():
|
||||||
def __init__(self):
|
def __init__(self, doctype, docname):
|
||||||
self.credentials = frappe.get_cached_doc('E Invoice Settings')
|
self.credentials = frappe.get_cached_doc('E Invoice Settings')
|
||||||
|
|
||||||
self.base_url = 'https://gsp.adaequare.com/'
|
self.base_url = 'https://gsp.adaequare.com/'
|
||||||
@@ -398,6 +364,8 @@ class GSPConnector():
|
|||||||
self.cancel_ewaybill_url = self.base_url + '/test/enriched/ei/api/ewayapi'
|
self.cancel_ewaybill_url = self.base_url + '/test/enriched/ei/api/ewayapi'
|
||||||
self.generate_ewaybill_url = self.base_url + 'test/enriched/ei/api/ewaybill'
|
self.generate_ewaybill_url = self.base_url + 'test/enriched/ei/api/ewaybill'
|
||||||
|
|
||||||
|
self.invoice = frappe.get_cached_doc(doctype, docname)
|
||||||
|
|
||||||
def get_auth_token(self):
|
def get_auth_token(self):
|
||||||
if time_diff_in_seconds(self.credentials.token_expiry, now_datetime()) < 150.0:
|
if time_diff_in_seconds(self.credentials.token_expiry, now_datetime()) < 150.0:
|
||||||
self.fetch_auth_token()
|
self.fetch_auth_token()
|
||||||
@@ -473,23 +441,22 @@ class GSPConnector():
|
|||||||
frappe.cache().hset('gstin_cache', key, details)
|
frappe.cache().hset('gstin_cache', key, details)
|
||||||
return details
|
return details
|
||||||
|
|
||||||
def generate_irn(self, docname):
|
def generate_irn(self):
|
||||||
headers = self.get_headers()
|
headers = self.get_headers()
|
||||||
doctype = 'Sales Invoice'
|
einvoice = make_einvoice(self.invoice)
|
||||||
einvoice = make_einvoice(doctype, docname)
|
|
||||||
data = json.dumps(einvoice)
|
data = json.dumps(einvoice)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = make_post_request(self.generate_irn_url, headers=headers, data=data)
|
res = make_post_request(self.generate_irn_url, headers=headers, data=data)
|
||||||
if res.get('success'):
|
if res.get('success'):
|
||||||
update_invoice(doctype, docname, res.get('result'))
|
self.set_einvoice_data(res.get('result'))
|
||||||
|
|
||||||
elif '2150' in res.get('message'):
|
elif '2150' in res.get('message'):
|
||||||
# IRN already generated
|
# IRN already generated
|
||||||
irn = res.get('result')[0].get('Desc').get('Irn')
|
irn = res.get('result')[0].get('Desc').get('Irn')
|
||||||
irn_details = self.get_irn_details(irn)
|
irn_details = self.get_irn_details(irn)
|
||||||
if irn_details:
|
if irn_details:
|
||||||
update_invoice(doctype, docname, irn_details)
|
self.set_einvoice_data(irn_details)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.log_error(res)
|
self.log_error(res)
|
||||||
@@ -521,9 +488,8 @@ class GSPConnector():
|
|||||||
self.log_error()
|
self.log_error()
|
||||||
self.raise_error(True)
|
self.raise_error(True)
|
||||||
|
|
||||||
def cancel_irn(self, docname, irn, reason, remark):
|
def cancel_irn(self, irn, reason, remark):
|
||||||
headers = self.get_headers()
|
headers = self.get_headers()
|
||||||
doctype = 'Sales Invoice'
|
|
||||||
data = json.dumps({
|
data = json.dumps({
|
||||||
'Irn': irn,
|
'Irn': irn,
|
||||||
'Cnlrsn': reason,
|
'Cnlrsn': reason,
|
||||||
@@ -533,8 +499,14 @@ class GSPConnector():
|
|||||||
try:
|
try:
|
||||||
res = make_post_request(self.cancel_irn_url, headers=headers, data=data)
|
res = make_post_request(self.cancel_irn_url, headers=headers, data=data)
|
||||||
if res.get('success'):
|
if res.get('success'):
|
||||||
frappe.db.set_value(doctype, docname, 'irn_cancelled', 1)
|
self.invoice.irn_cancelled = 1
|
||||||
# frappe.db.set_value(doctype, docname, 'cancelled_on', res.get('CancelDate'))
|
self.invoice.flags.updater_reference = {
|
||||||
|
'doctype': self.invoice.doctype,
|
||||||
|
'docname': self.invoice.name,
|
||||||
|
'label': _('IRN Cancelled - {}').format(remark)
|
||||||
|
}
|
||||||
|
self.update_invoice()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.log_error(res)
|
self.log_error(res)
|
||||||
raise ResponseFailure
|
raise ResponseFailure
|
||||||
@@ -550,8 +522,6 @@ class GSPConnector():
|
|||||||
args = frappe._dict(kwargs)
|
args = frappe._dict(kwargs)
|
||||||
|
|
||||||
headers = self.get_headers()
|
headers = self.get_headers()
|
||||||
doctype = 'Sales Invoice'
|
|
||||||
docname = args.docname
|
|
||||||
eway_bill_details = get_eway_bill_details(args)
|
eway_bill_details = get_eway_bill_details(args)
|
||||||
data = json.dumps({
|
data = json.dumps({
|
||||||
'Irn': args.irn,
|
'Irn': args.irn,
|
||||||
@@ -568,12 +538,16 @@ class GSPConnector():
|
|||||||
try:
|
try:
|
||||||
res = make_post_request(self.generate_ewaybill_url, headers=headers, data=data)
|
res = make_post_request(self.generate_ewaybill_url, headers=headers, data=data)
|
||||||
if res.get('success'):
|
if res.get('success'):
|
||||||
frappe.db.set_value(doctype, docname, 'ewaybill', res.get('result').get('EwbNo'))
|
self.invoice.ewaybill = res.get('result').get('EwbNo')
|
||||||
frappe.db.set_value(doctype, docname, 'eway_bill_cancelled', 0)
|
self.invoice.eway_bill_cancelled = 0
|
||||||
for d in args:
|
self.invoice.update(args)
|
||||||
if d in ['docname', 'cmd']: continue
|
self.invoice.flags.updater_reference = {
|
||||||
# update eway bill details in sales invoice
|
'doctype': self.invoice.doctype,
|
||||||
frappe.db.set_value(doctype, docname, d, args[d])
|
'docname': self.invoice.name,
|
||||||
|
'label': _('E-Way Bill Generated')
|
||||||
|
}
|
||||||
|
self.update_invoice()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.log_error(res)
|
self.log_error(res)
|
||||||
raise ResponseFailure
|
raise ResponseFailure
|
||||||
@@ -585,7 +559,7 @@ class GSPConnector():
|
|||||||
self.log_error(data)
|
self.log_error(data)
|
||||||
self.raise_error(True)
|
self.raise_error(True)
|
||||||
|
|
||||||
def cancel_eway_bill(self, docname, eway_bill, reason, remark):
|
def cancel_eway_bill(self, eway_bill, reason, remark):
|
||||||
headers = self.get_headers()
|
headers = self.get_headers()
|
||||||
doctype = 'Sales Invoice'
|
doctype = 'Sales Invoice'
|
||||||
data = json.dumps({
|
data = json.dumps({
|
||||||
@@ -597,8 +571,15 @@ class GSPConnector():
|
|||||||
try:
|
try:
|
||||||
res = make_post_request(self.cancel_ewaybill_url, headers=headers, data=data)
|
res = make_post_request(self.cancel_ewaybill_url, headers=headers, data=data)
|
||||||
if res.get('success'):
|
if res.get('success'):
|
||||||
frappe.db.set_value(doctype, docname, 'ewaybill', '')
|
self.invoice.ewaybill = ''
|
||||||
frappe.db.set_value(doctype, docname, 'eway_bill_cancelled', 1)
|
self.invoice.eway_bill_cancelled = 1
|
||||||
|
self.invoice.flags.updater_reference = {
|
||||||
|
'doctype': self.invoice.doctype,
|
||||||
|
'docname': self.invoice.name,
|
||||||
|
'label': _('E-Way Bill Cancelled - {}').format(remark)
|
||||||
|
}
|
||||||
|
self.update_invoice()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.log_error(res)
|
self.log_error(res)
|
||||||
raise ResponseFailure
|
raise ResponseFailure
|
||||||
@@ -626,22 +607,66 @@ class GSPConnector():
|
|||||||
indicator='red'
|
indicator='red'
|
||||||
)
|
)
|
||||||
|
|
||||||
@frappe.whitelist()
|
def set_einvoice_data(self, res):
|
||||||
def generate_irn(docname):
|
enc_signed_invoice = res.get('SignedInvoice')
|
||||||
gsp_connector = GSPConnector()
|
dec_signed_invoice = jwt.decode(enc_signed_invoice, verify=False)['data']
|
||||||
gsp_connector.generate_irn(docname)
|
|
||||||
|
self.invoice.irn = res.get('Irn')
|
||||||
|
self.invoice.ewaybill = res.get('EwbNo')
|
||||||
|
self.invoice.signed_einvoice = dec_signed_invoice
|
||||||
|
self.invoice.signed_qr_code = res.get('SignedQRCode')
|
||||||
|
|
||||||
|
self.attach_qrcode_image()
|
||||||
|
|
||||||
|
self.invoice.flags.updater_reference = {
|
||||||
|
'doctype': self.invoice.doctype,
|
||||||
|
'docname': self.invoice.name,
|
||||||
|
'label': _('IRN Generated')
|
||||||
|
}
|
||||||
|
self.update_invoice()
|
||||||
|
|
||||||
|
def attach_qrcode_image(self):
|
||||||
|
qrcode = self.invoice.signed_qr_code
|
||||||
|
doctype = self.invoice.doctype
|
||||||
|
docname = self.invoice.name
|
||||||
|
|
||||||
|
_file = frappe.new_doc('File')
|
||||||
|
_file.update({
|
||||||
|
'file_name': f'QRCode_{docname}.png',
|
||||||
|
'attached_to_doctype': doctype,
|
||||||
|
'attached_to_name': docname,
|
||||||
|
'content': 'qrcode',
|
||||||
|
'is_private': 1
|
||||||
|
})
|
||||||
|
_file.insert()
|
||||||
|
frappe.db.commit()
|
||||||
|
url = qrcreate(qrcode)
|
||||||
|
abs_file_path = os.path.abspath(_file.get_full_path())
|
||||||
|
url.png(abs_file_path, scale=2)
|
||||||
|
|
||||||
|
self.invoice.qrcode_image = _file.file_url
|
||||||
|
|
||||||
|
def update_invoice(self):
|
||||||
|
self.invoice.flags.ignore_validate_update_after_submit = True
|
||||||
|
self.invoice.flags.ignore_validate = True
|
||||||
|
self.invoice.save()
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def cancel_irn(docname, irn, reason, remark):
|
def generate_irn(doctype, docname):
|
||||||
gsp_connector = GSPConnector()
|
gsp_connector = GSPConnector(doctype, docname)
|
||||||
gsp_connector.cancel_irn(docname, irn, reason, remark)
|
gsp_connector.generate_irn()
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def generate_eway_bill(**kwargs):
|
def cancel_irn(doctype, docname, irn, reason, remark):
|
||||||
gsp_connector = GSPConnector()
|
gsp_connector = GSPConnector(doctype, docname)
|
||||||
|
gsp_connector.cancel_irn(irn, reason, remark)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def generate_eway_bill(doctype, docname, **kwargs):
|
||||||
|
gsp_connector = GSPConnector(doctype, docname)
|
||||||
gsp_connector.generate_eway_bill(**kwargs)
|
gsp_connector.generate_eway_bill(**kwargs)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def cancel_eway_bill(docname, eway_bill, reason, remark):
|
def cancel_eway_bill(doctype, docname, eway_bill, reason, remark):
|
||||||
gsp_connector = GSPConnector()
|
gsp_connector = GSPConnector(doctype, docname)
|
||||||
gsp_connector.cancel_eway_bill(docname, eway_bill, reason, remark)
|
gsp_connector.cancel_eway_bill(eway_bill, reason, remark)
|
||||||
Reference in New Issue
Block a user