|
|
|
|
@@ -244,8 +244,7 @@ def calculate_hra_exemption_for_period(doc):
|
|
|
|
|
return exemptions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@frappe.whitelist()
|
|
|
|
|
def generate_ewb_json(dt, dn):
|
|
|
|
|
def get_ewb_data(dt, dn):
|
|
|
|
|
if dt != 'Sales Invoice':
|
|
|
|
|
frappe.throw(_('e-Way Bill JSON can only be generated from Sales Invoice'))
|
|
|
|
|
|
|
|
|
|
@@ -254,26 +253,8 @@ def generate_ewb_json(dt, dn):
|
|
|
|
|
ewaybills = []
|
|
|
|
|
for doc_name in dn:
|
|
|
|
|
doc = frappe.get_doc(dt, doc_name)
|
|
|
|
|
if doc.docstatus != 1:
|
|
|
|
|
frappe.throw(_('e-Way Bill JSON can only be generated from submitted document'))
|
|
|
|
|
|
|
|
|
|
if doc.is_return:
|
|
|
|
|
frappe.throw(_('e-Way Bill JSON cannot be generated for Sales Return as of now'))
|
|
|
|
|
|
|
|
|
|
if doc.ewaybill:
|
|
|
|
|
frappe.throw(_('e-Way Bill already exists for this document'))
|
|
|
|
|
|
|
|
|
|
reqd_fields = ['company_gstin', 'company_address', 'customer_address',
|
|
|
|
|
'shipping_address_name', 'mode_of_transport', 'distance']
|
|
|
|
|
|
|
|
|
|
for fieldname in reqd_fields:
|
|
|
|
|
if not doc.get(fieldname):
|
|
|
|
|
frappe.throw(_('{} is required to generate e-Way Bill JSON'.format(
|
|
|
|
|
doc.meta.get_label(fieldname)
|
|
|
|
|
)))
|
|
|
|
|
|
|
|
|
|
if len(doc.company_gstin) < 15:
|
|
|
|
|
frappe.throw(_('You must be a registered supplier to generate e-Way Bill'))
|
|
|
|
|
validate_sales_invoice(doc)
|
|
|
|
|
|
|
|
|
|
data = frappe._dict({
|
|
|
|
|
"transporterId": "",
|
|
|
|
|
@@ -294,11 +275,77 @@ def generate_ewb_json(dt, dn):
|
|
|
|
|
data.docDate = frappe.utils.formatdate(doc.posting_date, 'dd/mm/yyyy')
|
|
|
|
|
|
|
|
|
|
company_address = frappe.get_doc('Address', doc.company_address)
|
|
|
|
|
billing_address = frappe.get_doc('Address', doc.customer_address)
|
|
|
|
|
|
|
|
|
|
shipping_address = frappe.get_doc('Address', doc.shipping_address_name)
|
|
|
|
|
|
|
|
|
|
data = get_address_details(data, doc, company_address, billing_address)
|
|
|
|
|
|
|
|
|
|
data.itemList = []
|
|
|
|
|
data.totalValue = doc.total
|
|
|
|
|
|
|
|
|
|
data = get_item_list(data, doc)
|
|
|
|
|
|
|
|
|
|
disable_rounded = frappe.db.get_single_value('Global Defaults', 'disable_rounded_total')
|
|
|
|
|
data.totInvValue = doc.grand_total if disable_rounded else doc.rounded_total
|
|
|
|
|
|
|
|
|
|
data = get_transport_details(data, doc)
|
|
|
|
|
|
|
|
|
|
fields = {
|
|
|
|
|
"/. -": {
|
|
|
|
|
'docNo': doc.name,
|
|
|
|
|
'fromTrdName': doc.company,
|
|
|
|
|
'toTrdName': doc.customer_name,
|
|
|
|
|
'transDocNo': doc.lr_no,
|
|
|
|
|
},
|
|
|
|
|
"@#/,&. -": {
|
|
|
|
|
'fromAddr1': company_address.address_line1,
|
|
|
|
|
'fromAddr2': company_address.address_line2,
|
|
|
|
|
'fromPlace': company_address.city,
|
|
|
|
|
'toAddr1': shipping_address.address_line1,
|
|
|
|
|
'toAddr2': shipping_address.address_line2,
|
|
|
|
|
'toPlace': shipping_address.city,
|
|
|
|
|
'transporterName': doc.transporter_name
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for allowed_chars, field_map in fields.items():
|
|
|
|
|
for key, value in field_map.items():
|
|
|
|
|
if not value:
|
|
|
|
|
data[key] = ''
|
|
|
|
|
else:
|
|
|
|
|
data[key] = re.sub(r'[^\w' + allowed_chars + ']', '', value)
|
|
|
|
|
|
|
|
|
|
ewaybills.append(data)
|
|
|
|
|
|
|
|
|
|
data = {
|
|
|
|
|
'version': '1.0.1118',
|
|
|
|
|
'billLists': ewaybills
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
@frappe.whitelist()
|
|
|
|
|
def generate_ewb_json(dt, dn):
|
|
|
|
|
|
|
|
|
|
data = get_ewb_data(dt, dn)
|
|
|
|
|
|
|
|
|
|
frappe.local.response.filecontent = json.dumps(data, indent=4, sort_keys=True)
|
|
|
|
|
frappe.local.response.type = 'download'
|
|
|
|
|
|
|
|
|
|
if len(data['billLists']) > 1:
|
|
|
|
|
doc_name = 'Bulk'
|
|
|
|
|
else:
|
|
|
|
|
doc_name = dn
|
|
|
|
|
|
|
|
|
|
frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(doc_name, frappe.utils.random_string(5))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_address_details(data, doc, company_address, billing_address):
|
|
|
|
|
data.fromPincode = validate_pincode(company_address.pincode, 'Company Address')
|
|
|
|
|
data.fromStateCode = data.actualFromStateCode = validate_state_code(
|
|
|
|
|
company_address.gst_state_number, 'Company Address')
|
|
|
|
|
|
|
|
|
|
billing_address = frappe.get_doc('Address', doc.customer_address)
|
|
|
|
|
if not doc.billing_address_gstin or len(doc.billing_address_gstin) < 15:
|
|
|
|
|
data.toGstin = 'URP'
|
|
|
|
|
set_gst_state_and_state_number(billing_address)
|
|
|
|
|
@@ -318,8 +365,9 @@ def generate_ewb_json(dt, dn):
|
|
|
|
|
data.actualToStateCode = data.toStateCode
|
|
|
|
|
shipping_address = billing_address
|
|
|
|
|
|
|
|
|
|
data.itemList = []
|
|
|
|
|
data.totalValue = doc.total
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
def get_item_list(data, doc):
|
|
|
|
|
for attr in ['cgstValue', 'sgstValue', 'igstValue', 'cessValue', 'OthValue']:
|
|
|
|
|
data[attr] = 0
|
|
|
|
|
|
|
|
|
|
@@ -354,9 +402,31 @@ def generate_ewb_json(dt, dn):
|
|
|
|
|
|
|
|
|
|
data.itemList.append(item_data)
|
|
|
|
|
|
|
|
|
|
disable_rounded = frappe.db.get_single_value('Global Defaults', 'disable_rounded_total')
|
|
|
|
|
data.totInvValue = doc.grand_total if disable_rounded else doc.rounded_total
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
def validate_sales_invoice(doc):
|
|
|
|
|
if doc.docstatus != 1:
|
|
|
|
|
frappe.throw(_('e-Way Bill JSON can only be generated from submitted document'))
|
|
|
|
|
|
|
|
|
|
if doc.is_return:
|
|
|
|
|
frappe.throw(_('e-Way Bill JSON cannot be generated for Sales Return as of now'))
|
|
|
|
|
|
|
|
|
|
if doc.ewaybill:
|
|
|
|
|
frappe.throw(_('e-Way Bill already exists for this document'))
|
|
|
|
|
|
|
|
|
|
reqd_fields = ['company_gstin', 'company_address', 'customer_address',
|
|
|
|
|
'shipping_address_name', 'mode_of_transport', 'distance']
|
|
|
|
|
|
|
|
|
|
for fieldname in reqd_fields:
|
|
|
|
|
if not doc.get(fieldname):
|
|
|
|
|
frappe.throw(_('{} is required to generate e-Way Bill JSON'.format(
|
|
|
|
|
doc.meta.get_label(fieldname)
|
|
|
|
|
)))
|
|
|
|
|
|
|
|
|
|
if len(doc.company_gstin) < 15:
|
|
|
|
|
frappe.throw(_('You must be a registered supplier to generate e-Way Bill'))
|
|
|
|
|
|
|
|
|
|
def get_transport_details(data, doc):
|
|
|
|
|
if doc.distance > 4000:
|
|
|
|
|
frappe.throw(_('Distance cannot be greater than 4000 kms'))
|
|
|
|
|
|
|
|
|
|
@@ -399,45 +469,8 @@ def generate_ewb_json(dt, dn):
|
|
|
|
|
validate_gstin_check_digit(doc.gst_transporter_id, label='GST Transporter ID')
|
|
|
|
|
data.transporterId = doc.gst_transporter_id
|
|
|
|
|
|
|
|
|
|
fields = {
|
|
|
|
|
"/. -": {
|
|
|
|
|
'docNo': doc.name,
|
|
|
|
|
'fromTrdName': doc.company,
|
|
|
|
|
'toTrdName': doc.customer_name,
|
|
|
|
|
'transDocNo': doc.lr_no,
|
|
|
|
|
},
|
|
|
|
|
"@#/,&. -": {
|
|
|
|
|
'fromAddr1': company_address.address_line1,
|
|
|
|
|
'fromAddr2': company_address.address_line2,
|
|
|
|
|
'fromPlace': company_address.city,
|
|
|
|
|
'toAddr1': shipping_address.address_line1,
|
|
|
|
|
'toAddr2': shipping_address.address_line2,
|
|
|
|
|
'toPlace': shipping_address.city,
|
|
|
|
|
'transporterName': doc.transporter_name
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
for allowed_chars, field_map in fields.items():
|
|
|
|
|
for key, value in field_map.items():
|
|
|
|
|
if not value:
|
|
|
|
|
data[key] = ''
|
|
|
|
|
else:
|
|
|
|
|
data[key] = re.sub(r'[^\w' + allowed_chars + ']', '', value)
|
|
|
|
|
|
|
|
|
|
ewaybills.append(data)
|
|
|
|
|
|
|
|
|
|
data = {
|
|
|
|
|
'version': '1.0.1118',
|
|
|
|
|
'billLists': ewaybills
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frappe.local.response.filecontent = json.dumps(data, indent=4, sort_keys=True)
|
|
|
|
|
frappe.local.response.type = 'download'
|
|
|
|
|
|
|
|
|
|
if len(ewaybills) > 1:
|
|
|
|
|
doc_name = 'Bulk'
|
|
|
|
|
|
|
|
|
|
frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(doc_name, frappe.utils.random_string(5))
|
|
|
|
|
|
|
|
|
|
def validate_pincode(pincode, address):
|
|
|
|
|
pin_not_found = "Pin Code doesn't exist for {}"
|
|
|
|
|
|