E Invoicing GST Validation Error

I am making progress. Now I have this Error while generating IRN:

The field POS must match the regular expression ‘^([0-9]{1,2})$’.

@nextchamp.saqib: Any idea how to overcome this error?

Thanks

Jay

The full error from the console is here:

Traceback (most recent call last):
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 580, in generate_irn
raise RequestFailed
erpnext.regional.india.e_invoice.utils.RequestFailed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/app.py”, line 67, in application
response = frappe.api.handle()
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/api.py”, line 59, in handle
return frappe.handler.handle()
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/handler.py”, line 24, in handle
data = execute_cmd(cmd)
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/handler.py”, line 64, in execute_cmd
return frappe.call(method, **frappe.form_dict)
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/init.py”, line 1074, in call
return fn(*args, **newargs)
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 818, in generate_irn
gsp_connector.generate_irn()
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 584, in generate_irn
self.raise_error(errors=errors)
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 755, in raise_error
throw_error_list(errors, title)
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 381, in throw_error_list
frappe.throw(errors[0], title=title)
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/init.py”, line 380, in throw
msgprint(msg, raise_exception=exc, title=title, indicator=‘red’, is_minimizable=is_minimizable)
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/init.py”, line 359, in msgprint
_raise_exception()
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/init.py”, line 319, in _raise_exception
raise raise_exception(msg)
frappe.exceptions.ValidationError: The field POS must match the regular expression ‘^([0-9]{1,2})$’.

I am reproducing a part of the JSON content:

“BuyerDtls”: {
“Gstin”: “XXXXXXXXXXXXXXX”,
“LglNm”: “ABC COMPANY PVT LTD”,
“Addr1”: “PLOT NO 3 INDL AREA”,
“Addr2”: “INDUSTRIAL AREA”,
“Loc”: “AMB”,
“Pin”: 177201,
“Stcd”: “2”,
“Pos”: “2-”

The “Pos”: “2-” should be 2 right? Is that the problem?

Thanks

Jay

I have good news. When the Place of Supply is >=10 it’s going through fine. I am getting the IRN. When the Place of Supply is <10, the JSON is picking up the Hyphen - after the State Code and that’s running into errors either at the GSP or at the GST Portal.

Can this be fixed please?

Thanks

Jay

1 Like

Hello,
IS GSTIN mandatory for shipping address to process E-Invoice?

Yes. This needs to be fixed. I’ll send one right now.

Yes. Shipping address is used to fetch the Customer’s GSTIN.

@JayRam Fixed. Please update and try again.

Ok.

But we had one case in that billing address have GSTIN but the shipping address not have GSTIN because we billed directly to the distributor and ship goods to the end customer.

Do you have any suggestions to handle this case?

I have tested adaequare APIS and that accepting shipping address without GSTIN number.

Request

Result

Apologies, I misread your question, I thought you were asking if the billing address GSTIN is mandatory.

Yes, shipping address GSTIN could be optional. I’ll make the change.

Ok.

I sent PR for that please check that.

https://github.com/frappe/erpnext/pull/25133

1 Like

Saqib,

I am implementing this for a client on Ver 12:

ERPNext: v12.19.0 (version-12)

Frappe Framework: v12.16.3 (version-12)

I pulled, cleared cache, restarted web and I still have this error:

The field POS must match the regular expression ‘^([0-9]{1,2})$’.

Can you please make these changes for the version-12 code too?

Thanks

Jay

I expected you were testing locally. For production, I guess we might have to take a minor release. Not sure if we can do it today but I’ll update if we decide a date to take one.

Or if you have access to the code, you can manually edit the file

apps/erpnext/erpnext/regional/india/e_invoice/utils.py

You just have to delete line no. 337 & 338 and replace it with

place_of_supply = get_place_of_supply(invoice, invoice.doctype)
if place_of_supply:
	place_of_supply = place_of_supply.split('-')[0]
else:
	place_of_supply = sanitize_for_json(invoice.billing_address_gstin)[:2]

Hi Saqib,

337 and 338 seems to be a different code. At least on my clients instance:

if invoice.gst_category == ‘Overseas’:
shipping_details = get_overseas_address_details(invoice.shipping_address_name)

The relevant part seems to be line 331 & 332:

     place_of_supply = get_place_of_supply(invoice, invoice.doctype) or invoice.billing_address_gstin
            place_of_supply = place_of_supply[:2]

Should I go ahead and replace lines 331 & 332 with the Code you have provided?

Thanks

Jay

Yes. These 2 lines needs to be replaced.

I did that and it seems the error has moved someplace else. Here’s the error from the console:

Traceback (most recent call last):
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 583, in generate_irn
raise RequestFailed
erpnext.regional.india.e_invoice.utils.RequestFailed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/app.py”, line 67, in application
response = frappe.api.handle()
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/api.py”, line 59, in handle
return frappe.handler.handle()
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/handler.py”, line 24, in handle
data = execute_cmd(cmd)
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/handler.py”, line 64, in execute_cmd
return frappe.call(method, **frappe.form_dict)
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/init.py”, line 1074, in call
return fn(*args, **newargs)
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 821, in generate_irn
gsp_connector.generate_irn()
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 587, in generate_irn
self.raise_error(errors=errors)
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 758, in raise_error
throw_error_list(errors, title)
File “/home/mmpy27/frappe-bench/apps/erpnext/erpnext/regional/india/e_invoice/utils.py”, line 384, in throw_error_list
frappe.throw(errors[0], title=title)
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/init.py”, line 380, in throw
msgprint(msg, raise_exception=exc, title=title, indicator=‘red’, is_minimizable=is_minimizable)
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/init.py”, line 359, in msgprint
_raise_exception()
File “/home/mmpy27/frappe-bench/apps/frappe/frappe/init.py”, line 319, in _raise_exception
raise raise_exception(msg)
frappe.exceptions.ValidationError: The POS field is required.

Thanks

Jay

Can you confirm if the customer & company address have proper GST State set? Since place of supply is derived from it.

Also, just confirming, in v13, the place of supply for <10 is also working using the older code.

Hi Saqib,

Yes it has the GSTIN Number and State all set correctly. Both for the Company and for the Customer.

Thanks

Jay

Hi Saqib,

The relevant lines of code I replaced and a few lines prior and after is reproduced below. Did I mess up some way?

    if invoice.gst_category == 'Overseas':
            buyer_details = get_overseas_address_details(invoice.customer_address)
    else:
            buyer_details = get_party_details(invoice.customer_address)
            place_of_supply = get_place_of_supply(invoice, invoice.doctype)
    if place_of_supply:
            place_of_supply = place_of_supply.split('-')[0]
    else:
            place_of_supply = sanitize_for_json(invoice.billing_address_gstin)[:2]
            buyer_details.update(dict(place_of_supply=place_of_supply))

Thanks

Jay

Formatting is off, copy & paste the below code.

	if invoice.gst_category == 'Overseas':
		buyer_details = get_overseas_address_details(invoice.customer_address)
	else:
		buyer_details = get_party_details(invoice.customer_address)
		place_of_supply = get_place_of_supply(invoice, invoice.doctype)
		if place_of_supply:
			place_of_supply = place_of_supply.split('-')[0]
		else:
			place_of_supply = invoice.billing_address_gstin[:2]
		buyer_details.update(dict(place_of_supply=place_of_supply))