Skip to content

Commit 6856033

Browse files
fix: Code cleanup and fixes
1 parent 4dacb89 commit 6856033

5 files changed

Lines changed: 152 additions & 119 deletions

File tree

erpnext/accounts/doctype/sales_invoice/regional/india.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ frappe.ui.form.on("Sales Invoice", {
3232
if (!w) {
3333
frappe.msgprint(__("Please enable pop-ups")); return;
3434
}
35-
});
35+
}, __("Make"));
3636
}
3737
}
3838
});

erpnext/patches.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ execute:frappe.delete_doc_if_exists("Page", "sales-analytics")
571571
execute:frappe.delete_doc_if_exists("Page", "purchase-analytics")
572572
execute:frappe.delete_doc_if_exists("Page", "stock-analytics")
573573
execute:frappe.delete_doc_if_exists("Page", "production-analytics")
574-
erpnext.patches.v11_0.ewaybill_fields_gst_india #2018-11-13 #2019-01-09 #2019-04-01
574+
erpnext.patches.v11_0.ewaybill_fields_gst_india #2018-11-13 #2019-01-09 #2019-04-01 #2019-05-03
575575
erpnext.patches.v11_0.drop_column_max_days_allowed
576576
erpnext.patches.v11_0.change_healthcare_desktop_icons
577577
erpnext.patches.v10_0.update_user_image_in_employee

erpnext/regional/india/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ def make_custom_fields(update=True):
432432
]
433433
}
434434

435-
create_custom_fields(custom_fields, ignore_validate = frappe.flags.in_patch, update=update)
435+
create_custom_fields(custom_fields, update=update)
436436

437437
def make_fixtures(company=None):
438438
docs = []

erpnext/regional/india/utils.py

Lines changed: 148 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,7 @@ def calculate_hra_exemption_for_period(doc):
244244
return exemptions
245245

246246

247-
@frappe.whitelist()
248-
def generate_ewb_json(dt, dn):
247+
def get_ewb_data(dt, dn):
249248
if dt != 'Sales Invoice':
250249
frappe.throw(_('e-Way Bill JSON can only be generated from Sales Invoice'))
251250

@@ -254,26 +253,8 @@ def generate_ewb_json(dt, dn):
254253
ewaybills = []
255254
for doc_name in dn:
256255
doc = frappe.get_doc(dt, doc_name)
257-
if doc.docstatus != 1:
258-
frappe.throw(_('e-Way Bill JSON can only be generated from submitted document'))
259-
260-
if doc.is_return:
261-
frappe.throw(_('e-Way Bill JSON cannot be generated for Sales Return as of now'))
262-
263-
if doc.ewaybill:
264-
frappe.throw(_('e-Way Bill already exists for this document'))
265256

266-
reqd_fields = ['company_gstin', 'company_address', 'customer_address',
267-
'shipping_address_name', 'mode_of_transport', 'distance']
268-
269-
for fieldname in reqd_fields:
270-
if not doc.get(fieldname):
271-
frappe.throw(_('{} is required to generate e-Way Bill JSON'.format(
272-
doc.meta.get_label(fieldname)
273-
)))
274-
275-
if len(doc.company_gstin) < 15:
276-
frappe.throw(_('You must be a registered supplier to generate e-Way Bill'))
257+
validate_sales_invoice(doc)
277258

278259
data = frappe._dict({
279260
"transporterId": "",
@@ -294,110 +275,21 @@ def generate_ewb_json(dt, dn):
294275
data.docDate = frappe.utils.formatdate(doc.posting_date, 'dd/mm/yyyy')
295276

296277
company_address = frappe.get_doc('Address', doc.company_address)
297-
data.fromPincode = validate_pincode(company_address.pincode, 'Company Address')
298-
data.fromStateCode = data.actualFromStateCode = validate_state_code(
299-
company_address.gst_state_number, 'Company Address')
300-
301278
billing_address = frappe.get_doc('Address', doc.customer_address)
302-
if not doc.billing_address_gstin or len(doc.billing_address_gstin) < 15:
303-
data.toGstin = 'URP'
304-
set_gst_state_and_state_number(billing_address)
305-
else:
306-
data.toGstin = doc.billing_address_gstin
307279

308-
data.toPincode = validate_pincode(billing_address.pincode, 'Customer Address')
309-
data.toStateCode = validate_state_code(billing_address.gst_state_number, 'Customer Address')
280+
shipping_address = frappe.get_doc('Address', doc.shipping_address_name)
310281

311-
if doc.customer_address != doc.shipping_address_name:
312-
data.transType = 2
313-
shipping_address = frappe.get_doc('Address', doc.shipping_address_name)
314-
set_gst_state_and_state_number(shipping_address)
315-
data.actualToStateCode = validate_state_code(shipping_address.gst_state_number, 'Shipping Address')
316-
else:
317-
data.transType = 1
318-
data.actualToStateCode = data.toStateCode
319-
shipping_address = billing_address
282+
data = get_address_details(data, doc, company_address, billing_address)
320283

321284
data.itemList = []
322285
data.totalValue = doc.total
323-
for attr in ['cgstValue', 'sgstValue', 'igstValue', 'cessValue', 'OthValue']:
324-
data[attr] = 0
325-
326-
gst_accounts = get_gst_accounts(doc.company, account_wise=True)
327-
tax_map = {
328-
'sgst_account': ['sgstRate', 'sgstValue'],
329-
'cgst_account': ['cgstRate', 'cgstValue'],
330-
'igst_account': ['igstRate', 'igstValue'],
331-
'cess_account': ['cessRate', 'cessValue']
332-
}
333-
item_data_attrs = ['sgstRate', 'cgstRate', 'igstRate', 'cessRate', 'cessNonAdvol']
334-
hsn_wise_charges, hsn_taxable_amount = get_itemised_tax_breakup_data(doc, account_wise=True)
335-
for hsn_code, taxable_amount in hsn_taxable_amount.items():
336-
item_data = frappe._dict()
337-
if not hsn_code:
338-
frappe.throw(_('GST HSN Code does not exist for one or more items'))
339-
item_data.hsnCode = int(hsn_code)
340-
item_data.taxableAmount = taxable_amount
341-
item_data.qtyUnit = ""
342-
for attr in item_data_attrs:
343-
item_data[attr] = 0
344-
345-
for account, tax_detail in hsn_wise_charges.get(hsn_code, {}).items():
346-
account_type = gst_accounts.get(account, '')
347-
for tax_acc, attrs in tax_map.items():
348-
if account_type == tax_acc:
349-
item_data[attrs[0]] = tax_detail.get('tax_rate')
350-
data[attrs[1]] += tax_detail.get('tax_amount')
351-
break
352-
else:
353-
data.OthValue += tax_detail.get('tax_amount')
354286

355-
data.itemList.append(item_data)
287+
data = get_item_list(data, doc)
356288

357289
disable_rounded = frappe.db.get_single_value('Global Defaults', 'disable_rounded_total')
358290
data.totInvValue = doc.grand_total if disable_rounded else doc.rounded_total
359291

360-
if doc.distance > 4000:
361-
frappe.throw(_('Distance cannot be greater than 4000 kms'))
362-
363-
data.transDistance = round(doc.distance)
364-
365-
transport_modes = {
366-
'Road': 1,
367-
'Rail': 2,
368-
'Air': 3,
369-
'Ship': 4
370-
}
371-
372-
vehicle_types = {
373-
'Regular': 'R',
374-
'Over Dimensional Cargo (ODC)': 'O'
375-
}
376-
377-
data.transMode = transport_modes.get(doc.mode_of_transport)
378-
379-
if doc.mode_of_transport == 'Road':
380-
if not doc.gst_transporter_id and not doc.vehicle_no:
381-
frappe.throw(_('Either GST Transporter ID or Vehicle No is required if Mode of Transport is Road'))
382-
if doc.vehicle_no:
383-
data.vehicleNo = doc.vehicle_no.replace(' ', '')
384-
if not doc.gst_vehicle_type:
385-
frappe.throw(_('Vehicle Type is required if Mode of Transport is Road'))
386-
else:
387-
data.vehicleType = vehicle_types.get(doc.gst_vehicle_type)
388-
else:
389-
if not doc.lr_no or not doc.lr_date:
390-
frappe.throw(_('Transport Receipt No and Date are mandatory for your chosen Mode of Transport'))
391-
392-
if doc.lr_no:
393-
data.transDocNo = doc.lr_no
394-
395-
if doc.lr_date:
396-
data.transDocDate = frappe.utils.formatdate(doc.lr_date, 'dd/mm/yyyy')
397-
398-
if doc.gst_transporter_id:
399-
validate_gstin_check_digit(doc.gst_transporter_id, label='GST Transporter ID')
400-
data.transporterId = doc.gst_transporter_id
292+
data = get_transport_details(data, doc)
401293

402294
fields = {
403295
"/. -": {
@@ -431,14 +323,155 @@ def generate_ewb_json(dt, dn):
431323
'billLists': ewaybills
432324
}
433325

326+
return data
327+
328+
@frappe.whitelist()
329+
def generate_ewb_json(dt, dn):
330+
331+
data = get_ewb_data(dt, dn)
332+
434333
frappe.local.response.filecontent = json.dumps(data, indent=4, sort_keys=True)
435334
frappe.local.response.type = 'download'
436335

437-
if len(ewaybills) > 1:
336+
if len(data['billLists']) > 1:
438337
doc_name = 'Bulk'
338+
else:
339+
doc_name = dn
439340

440341
frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(doc_name, frappe.utils.random_string(5))
441342

343+
344+
def get_address_details(data, doc, company_address, billing_address):
345+
data.fromPincode = validate_pincode(company_address.pincode, 'Company Address')
346+
data.fromStateCode = data.actualFromStateCode = validate_state_code(
347+
company_address.gst_state_number, 'Company Address')
348+
349+
if not doc.billing_address_gstin or len(doc.billing_address_gstin) < 15:
350+
data.toGstin = 'URP'
351+
set_gst_state_and_state_number(billing_address)
352+
else:
353+
data.toGstin = doc.billing_address_gstin
354+
355+
data.toPincode = validate_pincode(billing_address.pincode, 'Customer Address')
356+
data.toStateCode = validate_state_code(billing_address.gst_state_number, 'Customer Address')
357+
358+
if doc.customer_address != doc.shipping_address_name:
359+
data.transType = 2
360+
shipping_address = frappe.get_doc('Address', doc.shipping_address_name)
361+
set_gst_state_and_state_number(shipping_address)
362+
data.actualToStateCode = validate_state_code(shipping_address.gst_state_number, 'Shipping Address')
363+
else:
364+
data.transType = 1
365+
data.actualToStateCode = data.toStateCode
366+
shipping_address = billing_address
367+
368+
return data
369+
370+
def get_item_list(data, doc):
371+
for attr in ['cgstValue', 'sgstValue', 'igstValue', 'cessValue', 'OthValue']:
372+
data[attr] = 0
373+
374+
gst_accounts = get_gst_accounts(doc.company, account_wise=True)
375+
tax_map = {
376+
'sgst_account': ['sgstRate', 'sgstValue'],
377+
'cgst_account': ['cgstRate', 'cgstValue'],
378+
'igst_account': ['igstRate', 'igstValue'],
379+
'cess_account': ['cessRate', 'cessValue']
380+
}
381+
item_data_attrs = ['sgstRate', 'cgstRate', 'igstRate', 'cessRate', 'cessNonAdvol']
382+
hsn_wise_charges, hsn_taxable_amount = get_itemised_tax_breakup_data(doc, account_wise=True)
383+
for hsn_code, taxable_amount in hsn_taxable_amount.items():
384+
item_data = frappe._dict()
385+
if not hsn_code:
386+
frappe.throw(_('GST HSN Code does not exist for one or more items'))
387+
item_data.hsnCode = int(hsn_code)
388+
item_data.taxableAmount = taxable_amount
389+
item_data.qtyUnit = ""
390+
for attr in item_data_attrs:
391+
item_data[attr] = 0
392+
393+
for account, tax_detail in hsn_wise_charges.get(hsn_code, {}).items():
394+
account_type = gst_accounts.get(account, '')
395+
for tax_acc, attrs in tax_map.items():
396+
if account_type == tax_acc:
397+
item_data[attrs[0]] = tax_detail.get('tax_rate')
398+
data[attrs[1]] += tax_detail.get('tax_amount')
399+
break
400+
else:
401+
data.OthValue += tax_detail.get('tax_amount')
402+
403+
data.itemList.append(item_data)
404+
405+
return data
406+
407+
def validate_sales_invoice(doc):
408+
if doc.docstatus != 1:
409+
frappe.throw(_('e-Way Bill JSON can only be generated from submitted document'))
410+
411+
if doc.is_return:
412+
frappe.throw(_('e-Way Bill JSON cannot be generated for Sales Return as of now'))
413+
414+
if doc.ewaybill:
415+
frappe.throw(_('e-Way Bill already exists for this document'))
416+
417+
reqd_fields = ['company_gstin', 'company_address', 'customer_address',
418+
'shipping_address_name', 'mode_of_transport', 'distance']
419+
420+
for fieldname in reqd_fields:
421+
if not doc.get(fieldname):
422+
frappe.throw(_('{} is required to generate e-Way Bill JSON'.format(
423+
doc.meta.get_label(fieldname)
424+
)))
425+
426+
if len(doc.company_gstin) < 15:
427+
frappe.throw(_('You must be a registered supplier to generate e-Way Bill'))
428+
429+
def get_transport_details(data, doc):
430+
if doc.distance > 4000:
431+
frappe.throw(_('Distance cannot be greater than 4000 kms'))
432+
433+
data.transDistance = round(doc.distance)
434+
435+
transport_modes = {
436+
'Road': 1,
437+
'Rail': 2,
438+
'Air': 3,
439+
'Ship': 4
440+
}
441+
442+
vehicle_types = {
443+
'Regular': 'R',
444+
'Over Dimensional Cargo (ODC)': 'O'
445+
}
446+
447+
data.transMode = transport_modes.get(doc.mode_of_transport)
448+
449+
if doc.mode_of_transport == 'Road':
450+
if not doc.gst_transporter_id and not doc.vehicle_no:
451+
frappe.throw(_('Either GST Transporter ID or Vehicle No is required if Mode of Transport is Road'))
452+
if doc.vehicle_no:
453+
data.vehicleNo = doc.vehicle_no.replace(' ', '')
454+
if not doc.gst_vehicle_type:
455+
frappe.throw(_('Vehicle Type is required if Mode of Transport is Road'))
456+
else:
457+
data.vehicleType = vehicle_types.get(doc.gst_vehicle_type)
458+
else:
459+
if not doc.lr_no or not doc.lr_date:
460+
frappe.throw(_('Transport Receipt No and Date are mandatory for your chosen Mode of Transport'))
461+
462+
if doc.lr_no:
463+
data.transDocNo = doc.lr_no
464+
465+
if doc.lr_date:
466+
data.transDocDate = frappe.utils.formatdate(doc.lr_date, 'dd/mm/yyyy')
467+
468+
if doc.gst_transporter_id:
469+
validate_gstin_check_digit(doc.gst_transporter_id, label='GST Transporter ID')
470+
data.transporterId = doc.gst_transporter_id
471+
472+
return data
473+
474+
442475
def validate_pincode(pincode, address):
443476
pin_not_found = "Pin Code doesn't exist for {}"
444477
incorrect_pin = "Pin Code for {} is incorrecty formatted. It must be 6 digits (without spaces)"

erpnext/regional/report/gstr_1/gstr_1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def get_data(self):
6161
for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
6262
invoice_details = self.invoices.get(inv)
6363
for rate, items in items_based_on_rate.items():
64-
row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
64+
row = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
6565

6666
if self.filters.get("type_of_business") == "CDNR":
6767
row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N")

0 commit comments

Comments
 (0)