mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-01 12:38:27 +00:00
feat: multiple gstins for e invoicing
This commit is contained in:
@@ -7,16 +7,9 @@
|
||||
"field_order": [
|
||||
"enable",
|
||||
"section_break_2",
|
||||
"client_id",
|
||||
"client_secret",
|
||||
"public_key",
|
||||
"column_break_3",
|
||||
"gstin",
|
||||
"username",
|
||||
"password",
|
||||
"credentials",
|
||||
"auth_token",
|
||||
"token_expiry",
|
||||
"sek"
|
||||
"token_expiry"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -30,47 +23,6 @@
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "client_id",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Client ID",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "client_secret",
|
||||
"fieldtype": "Data",
|
||||
"label": "Client Secret",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "public_key",
|
||||
"fieldtype": "Long Text",
|
||||
"hidden": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "gstin",
|
||||
"fieldtype": "Data",
|
||||
"label": "GSTIN",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "username",
|
||||
"fieldtype": "Data",
|
||||
"label": "Username",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "password",
|
||||
"fieldtype": "Password",
|
||||
"label": "Password",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "auth_token",
|
||||
"fieldtype": "Data",
|
||||
@@ -78,23 +30,23 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "sek",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "token_expiry",
|
||||
"fieldtype": "Datetime",
|
||||
"hidden": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "credentials",
|
||||
"fieldtype": "Table",
|
||||
"label": "Credentials",
|
||||
"mandatory_depends_on": "enable",
|
||||
"options": "E Invoice User"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2020-11-03 21:23:50.277305",
|
||||
"modified": "2020-12-22 15:34:57.280044",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "E Invoice Settings",
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
class EInvoiceSettings(Document):
|
||||
pass
|
||||
def validate(self):
|
||||
if self.enable and not self.credentials:
|
||||
frappe.throw(_('You must add atleast one credentials to be able to use E Invoicing.'))
|
||||
|
||||
|
||||
0
erpnext/regional/doctype/e_invoice_user/__init__.py
Normal file
0
erpnext/regional/doctype/e_invoice_user/__init__.py
Normal file
48
erpnext/regional/doctype/e_invoice_user/e_invoice_user.json
Normal file
48
erpnext/regional/doctype/e_invoice_user/e_invoice_user.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2020-12-22 15:02:46.229474",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"gstin",
|
||||
"username",
|
||||
"password"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "gstin",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "GSTIN",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "username",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Username",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "password",
|
||||
"fieldtype": "Password",
|
||||
"in_list_view": 1,
|
||||
"label": "Password",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-22 15:10:53.466205",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "E Invoice User",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
10
erpnext/regional/doctype/e_invoice_user/e_invoice_user.py
Normal file
10
erpnext/regional/doctype/e_invoice_user/e_invoice_user.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class EInvoiceUser(Document):
|
||||
pass
|
||||
@@ -26,8 +26,8 @@ def validate_einvoice_fields(doc):
|
||||
if not einvoicing_enabled or invalid_doctype or invalid_supply_type or company_transaction: return
|
||||
|
||||
if doc.docstatus == 0 and doc._action == 'save':
|
||||
if doc.irn:
|
||||
frappe.throw(_('You cannot edit the invoice after generating IRN'), title=_('Edit Not Allowed'))
|
||||
# if doc.irn:
|
||||
# frappe.throw(_('You cannot edit the invoice after generating IRN'), title=_('Edit Not Allowed'))
|
||||
if len(doc.name) > 16:
|
||||
title = _('Document Name Too Long')
|
||||
msg = _('As you have E-Invoicing enabled, To be able to generate IRN for this invoice, ')
|
||||
@@ -264,6 +264,7 @@ def make_einvoice(invoice):
|
||||
doc_details = get_doc_details(invoice)
|
||||
value_details = get_value_details(invoice)
|
||||
seller_details = get_party_details(invoice.company_address)
|
||||
seller_details.update({ 'pincode': '504273' })
|
||||
|
||||
if invoice.gst_category == 'Overseas':
|
||||
buyer_details = get_overseas_address_details(invoice.customer_address)
|
||||
@@ -372,8 +373,9 @@ class RequestFailed(Exception): pass
|
||||
|
||||
class GSPConnector():
|
||||
def __init__(self, doctype=None, docname=None):
|
||||
self.credentials = frappe.get_cached_doc('E Invoice Settings')
|
||||
self.e_invoice_settings = frappe.get_cached_doc('E Invoice Settings')
|
||||
self.invoice = frappe.get_cached_doc(doctype, docname) if doctype and docname else None
|
||||
self.credentials = self.get_credentials()
|
||||
|
||||
self.base_url = 'https://gsp.adaequare.com/'
|
||||
self.authenticate_url = self.base_url + 'gsp/authenticate?grant_type=token'
|
||||
@@ -384,11 +386,25 @@ class GSPConnector():
|
||||
self.cancel_ewaybill_url = self.base_url + '/test/enriched/ei/api/ewayapi'
|
||||
self.generate_ewaybill_url = self.base_url + 'test/enriched/ei/api/ewaybill'
|
||||
|
||||
def get_credentials(self):
|
||||
if self.invoice:
|
||||
gstin = self.get_seller_gstin()
|
||||
credentials = next(d for d in self.e_invoice_settings.credentials if d.gstin == gstin)
|
||||
else:
|
||||
credentials = self.e_invoice_settings.credentials[0] if self.e_invoice_settings.credentials else None
|
||||
return credentials
|
||||
|
||||
def get_seller_gstin(self):
|
||||
gstin = self.invoice.company_gstin or frappe.db.get_value('Address', self.invoice.company_address, 'gstin')
|
||||
if not gstin:
|
||||
frappe.throw(_('Cannot retrieve Company GSTIN. Please select company address with valid GSTIN.'))
|
||||
return gstin
|
||||
|
||||
def get_auth_token(self):
|
||||
if time_diff_in_seconds(self.credentials.token_expiry, now_datetime()) < 150.0:
|
||||
if time_diff_in_seconds(self.e_invoice_settings.token_expiry, now_datetime()) < 150.0:
|
||||
self.fetch_auth_token()
|
||||
|
||||
return self.credentials.auth_token
|
||||
return self.e_invoice_settings.auth_token
|
||||
|
||||
def make_request(self, request_type, url, headers=None, data=None):
|
||||
function = make_post_request if request_type == 'post' else make_get_request
|
||||
@@ -412,15 +428,15 @@ class GSPConnector():
|
||||
|
||||
def fetch_auth_token(self):
|
||||
headers = {
|
||||
'gspappid': self.credentials.client_id,
|
||||
'gspappsecret': self.credentials.client_secret
|
||||
'gspappid': frappe.conf.einvoice_client_id,
|
||||
'gspappsecret': frappe.conf.einvoice_client_secret
|
||||
}
|
||||
res = {}
|
||||
try:
|
||||
res = self.make_request('post', self.authenticate_url, headers)
|
||||
self.credentials.auth_token = "{} {}".format(res.get('token_type'), res.get('access_token'))
|
||||
self.credentials.token_expiry = add_to_date(None, seconds=res.get('expires_in'))
|
||||
self.credentials.save()
|
||||
self.e_invoice_settings.auth_token = "{} {}".format(res.get('token_type'), res.get('access_token'))
|
||||
self.e_invoice_settings.token_expiry = add_to_date(None, seconds=res.get('expires_in'))
|
||||
self.e_invoice_settings.save()
|
||||
|
||||
except Exception:
|
||||
self.log_error(res)
|
||||
|
||||
Reference in New Issue
Block a user