feat: generate IRN
This commit is contained in:
committed by
Deepesh Garg
parent
e43a50357b
commit
1bbdc504bf
@@ -0,0 +1,838 @@
|
||||
{
|
||||
"Version": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 6
|
||||
},
|
||||
"Irn": {
|
||||
"type": "string",
|
||||
"minLength": 64,
|
||||
"maxLength": 64
|
||||
},
|
||||
"TranDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"TaxSch": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 10,
|
||||
"enum": ["GST"]
|
||||
},
|
||||
"SupTyp": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 10,
|
||||
"enum": ["B2B", "SEZWP", "SEZWOP", "EXPWP", "EXPWOP", "DEXP"]
|
||||
},
|
||||
"RegRev": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 1,
|
||||
"enum": ["Y", "N"]
|
||||
},
|
||||
"EcmGstin": {
|
||||
"type": "string",
|
||||
"minLength": 15,
|
||||
"maxLength": 15,
|
||||
"pattern": "([0-9]{2}[0-9A-Z]{13})"
|
||||
},
|
||||
"IgstOnIntra": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 1,
|
||||
"enum": ["Y", "N"]
|
||||
}
|
||||
},
|
||||
"required": ["TaxSch", "SupTyp"]
|
||||
},
|
||||
"DocDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Typ": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 3,
|
||||
"enum": ["INV", "CRN", "DBN"]
|
||||
},
|
||||
"No": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 16,
|
||||
"pattern": "^([A-Z1-9]{1}[A-Z0-9/-]{0,15})$"
|
||||
},
|
||||
"Dt": {
|
||||
"type": "string",
|
||||
"minLength": 10,
|
||||
"maxLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
}
|
||||
},
|
||||
"required": ["Typ", "No", "Dt"]
|
||||
},
|
||||
"SellerDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Gstin": {
|
||||
"type": "string",
|
||||
"minLength": 15,
|
||||
"maxLength": 15,
|
||||
"pattern": "([0-9]{2}[0-9A-Z]{13})"
|
||||
},
|
||||
"LglNm": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"TrdNm": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Addr1": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Addr2": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Loc": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 50
|
||||
},
|
||||
"Pin": {
|
||||
"type": "number",
|
||||
"minimum": 100000,
|
||||
"maximum": 999999
|
||||
},
|
||||
"Stcd": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2
|
||||
},
|
||||
"Ph": {
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 12
|
||||
},
|
||||
"Em": {
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 100
|
||||
}
|
||||
},
|
||||
"required": ["Gstin", "LglNm", "Addr1", "Loc", "Pin", "Stcd"]
|
||||
},
|
||||
"BuyerDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Gstin": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 15,
|
||||
"pattern": "^(([0-9]{2}[0-9A-Z]{13})|URP)$"
|
||||
},
|
||||
"LglNm": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"TrdNm": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Pos": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2
|
||||
},
|
||||
"Addr1": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Addr2": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Loc": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Pin": {
|
||||
"type": "number",
|
||||
"minimum": 100000,
|
||||
"maximum": 999999
|
||||
},
|
||||
"Stcd": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2
|
||||
},
|
||||
"Ph": {
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 12
|
||||
},
|
||||
"Em": {
|
||||
"type": "string",
|
||||
"minLength": 6,
|
||||
"maxLength": 100
|
||||
}
|
||||
},
|
||||
"required": ["Gstin", "LglNm", "Pos", "Addr1", "Loc", "Stcd"]
|
||||
},
|
||||
"DispDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Nm": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Addr1": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Addr2": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Loc": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Pin": {
|
||||
"type": "number",
|
||||
"minimum": 100000,
|
||||
"maximum": 999999
|
||||
},
|
||||
"Stcd": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2
|
||||
}
|
||||
},
|
||||
"required": ["Nm", "Addr1", "Loc", "Pin", "Stcd"]
|
||||
},
|
||||
"ShipDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Gstin": {
|
||||
"type": "string",
|
||||
"maxLength": 15,
|
||||
"minLength": 3,
|
||||
"pattern": "^(([0-9]{2}[0-9A-Z]{13})|URP)$"
|
||||
},
|
||||
"LglNm": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"TrdNm": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Addr1": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Addr2": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Loc": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Pin": {
|
||||
"type": "number",
|
||||
"minimum": 100000,
|
||||
"maximum": 999999
|
||||
},
|
||||
"Stcd": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2
|
||||
}
|
||||
},
|
||||
"required": ["LglNm", "Addr1", "Loc", "Pin", "Stcd"]
|
||||
},
|
||||
"ItemList": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"SlNo": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 6
|
||||
},
|
||||
"PrdDesc": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 300
|
||||
},
|
||||
"IsServc": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 1,
|
||||
"enum": ["Y", "N"]
|
||||
},
|
||||
"HsnCd": {
|
||||
"type": "string",
|
||||
"minLength": 4,
|
||||
"maxLength": 8
|
||||
},
|
||||
"Barcde": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 30
|
||||
},
|
||||
"Qty": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 9999999999.999
|
||||
},
|
||||
"FreeQty": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 9999999999.999
|
||||
},
|
||||
"Unit": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 8
|
||||
},
|
||||
"UnitPrice": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.999
|
||||
},
|
||||
"TotAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"Discount": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"PreTaxVal": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"AssAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"GstRt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999.999
|
||||
},
|
||||
"IgstAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"CgstAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"SgstAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"CesRt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999.999
|
||||
},
|
||||
"CesAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"CesNonAdvlAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"StateCesRt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999.999
|
||||
},
|
||||
"StateCesAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"StateCesNonAdvlAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"OthChrg": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"TotItemVal": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
},
|
||||
"OrdLineRef": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 50
|
||||
},
|
||||
"OrgCntry": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 2
|
||||
},
|
||||
"PrdSlNo": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20
|
||||
},
|
||||
"BchDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Nm": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 20
|
||||
},
|
||||
"ExpDt": {
|
||||
"type": "string",
|
||||
"maxLength": 10,
|
||||
"minLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
},
|
||||
"WrDt": {
|
||||
"type": "string",
|
||||
"maxLength": 10,
|
||||
"minLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
}
|
||||
},
|
||||
"required": ["Nm"]
|
||||
},
|
||||
"AttribDtls": {
|
||||
"type": "Array",
|
||||
"Attribute": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Nm": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Val": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"SlNo",
|
||||
"IsServc",
|
||||
"HsnCd",
|
||||
"UnitPrice",
|
||||
"TotAmt",
|
||||
"AssAmt",
|
||||
"GstRt",
|
||||
"TotItemVal"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ValDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"AssVal": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"CgstVal": {
|
||||
"type": "number",
|
||||
"maximum": 99999999999999.99,
|
||||
"minimum": 0
|
||||
},
|
||||
"SgstVal": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"IgstVal": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"CesVal": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"StCesVal": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"Discount": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"OthChrg": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"RndOffAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99.99
|
||||
},
|
||||
"TotInvVal": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"TotInvValFc": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
}
|
||||
},
|
||||
"required": ["AssVal", "TotInvVal"]
|
||||
},
|
||||
"PayDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Nm": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 100
|
||||
},
|
||||
"AccDet": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 18
|
||||
},
|
||||
"Mode": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 18
|
||||
},
|
||||
"FinInsBr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 11
|
||||
},
|
||||
"PayTerm": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 100
|
||||
},
|
||||
"PayInstr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 100
|
||||
},
|
||||
"CrTrn": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 100
|
||||
},
|
||||
"DirDr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 100
|
||||
},
|
||||
"CrDay": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 9999
|
||||
},
|
||||
"PaidAmt": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
},
|
||||
"PaymtDue": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 99999999999999.99
|
||||
}
|
||||
}
|
||||
},
|
||||
"RefDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"InvRm": {
|
||||
"type": "string",
|
||||
"maxLength": 100,
|
||||
"minLength": 3,
|
||||
"pattern": "^[0-9A-Za-z/-]{3,100}$"
|
||||
},
|
||||
"DocPerdDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"InvStDt": {
|
||||
"type": "string",
|
||||
"maxLength": 10,
|
||||
"minLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
},
|
||||
"InvEndDt": {
|
||||
"type": "string",
|
||||
"maxLength": 10,
|
||||
"minLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
}
|
||||
},
|
||||
"required": ["InvStDt", "InvEndDt"]
|
||||
},
|
||||
"PrecDocDtls": {
|
||||
"type": "Array",
|
||||
"PrecDocument": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"InvNo": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 16,
|
||||
"pattern": "^[1-9A-Z]{1}[0-9A-Z/-]{1,15}$"
|
||||
},
|
||||
"InvDt": {
|
||||
"type": "string",
|
||||
"maxLength": 10,
|
||||
"minLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
},
|
||||
"OthRefNo": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"required": ["InvNo", "InvDt"]
|
||||
},
|
||||
"ContrDtls": {
|
||||
"type": "Array",
|
||||
"Contract": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"RecAdvRefr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20,
|
||||
"pattern": "^([0-9A-Za-z/-]){1,20}$"
|
||||
},
|
||||
"RecAdvDt": {
|
||||
"type": "string",
|
||||
"minLength": 10,
|
||||
"maxLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
},
|
||||
"TendRefr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20,
|
||||
"pattern": "^([0-9A-Za-z/-]){1,20}$"
|
||||
},
|
||||
"ContrRefr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20,
|
||||
"pattern": "^([0-9A-Za-z/-]){1,20}$"
|
||||
},
|
||||
"ExtRefr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20,
|
||||
"pattern": "^([0-9A-Za-z/-]){1,20}$"
|
||||
},
|
||||
"ProjRefr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20,
|
||||
"pattern": "^([0-9A-Za-z/-]){1,20}$"
|
||||
},
|
||||
"PORefr": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 16,
|
||||
"pattern": "^([0-9A-Za-z/-]){1,16}$"
|
||||
},
|
||||
"PORefDt": {
|
||||
"type": "string",
|
||||
"minLength": 10,
|
||||
"maxLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["InvStDt", "InvEndDt"]
|
||||
},
|
||||
"AddlDocDtls": {
|
||||
"type": "Array",
|
||||
"AddlDocument": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Url": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"Docs": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 1000
|
||||
},
|
||||
"Info": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ExpDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ShipBNo": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 20
|
||||
},
|
||||
"ShipBDt": {
|
||||
"type": "string",
|
||||
"minLength": 10,
|
||||
"maxLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
},
|
||||
"Port": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 10,
|
||||
"pattern": "^[0-9A-Za-z]{2,10}$"
|
||||
},
|
||||
"RefClm": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 1
|
||||
},
|
||||
"ForCur": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 16
|
||||
},
|
||||
"CntCode": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 2
|
||||
},
|
||||
"ExpDuty": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 999999999999.99
|
||||
}
|
||||
}
|
||||
},
|
||||
"EwbDtls": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"TransId": {
|
||||
"type": "string",
|
||||
"minLength": 15,
|
||||
"maxLength": 15
|
||||
},
|
||||
"TransName": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 100
|
||||
},
|
||||
"TransMode": {
|
||||
"type": "string",
|
||||
"maxLength": 1,
|
||||
"minLength": 1,
|
||||
"enum": ["1", 2, 3, 4]
|
||||
},
|
||||
"Distance": {
|
||||
"type": "number",
|
||||
"minimum": 1,
|
||||
"maximum": 9999
|
||||
},
|
||||
"TransDocNo": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 15,
|
||||
"pattern": "^([0-9A-Z/-]){1,15}$"
|
||||
},
|
||||
"TransDocDt": {
|
||||
"type": "string",
|
||||
"minLength": 10,
|
||||
"maxLength": 10,
|
||||
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]"
|
||||
},
|
||||
"VehNo": {
|
||||
"type": "string",
|
||||
"minLength": 4,
|
||||
"maxLength": 20
|
||||
},
|
||||
"VehType": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 1,
|
||||
"enum": ["O", "R"]
|
||||
}
|
||||
},
|
||||
"required": ["Distance"]
|
||||
},
|
||||
"required": [
|
||||
"Version",
|
||||
"TranDtls",
|
||||
"DocDtls",
|
||||
"SellerDtls",
|
||||
"BuyerDtls",
|
||||
"ItemList",
|
||||
"ValDtls"
|
||||
]
|
||||
}
|
||||
@@ -16,6 +16,19 @@ frappe.ui.form.on('E Invoice Settings', {
|
||||
callback: (res) => console.log(res)
|
||||
});
|
||||
});
|
||||
|
||||
frm.add_custom_button(__("Generate IRN"),
|
||||
() => {
|
||||
frm.call({
|
||||
doc: frm.doc,
|
||||
method: 'generate_irn',
|
||||
args: {
|
||||
'invoice': 'SINV-20-21-0044'
|
||||
},
|
||||
freeze: true,
|
||||
callback: (res) => console.log(res)
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
show_fetch_token_btn(frm) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import base64
|
||||
import frappe
|
||||
@@ -13,8 +14,8 @@ from Crypto.Cipher import PKCS1_v1_5, AES
|
||||
from Crypto.Util.Padding import pad, unpad
|
||||
from frappe.model.document import Document
|
||||
from frappe import _, get_module_path, scrub
|
||||
from frappe.utils.data import get_datetime, cstr
|
||||
from erpnext.regional.india.utils import get_gst_accounts
|
||||
from frappe.utils.data import get_datetime, cstr, cint, format_date
|
||||
from frappe.integrations.utils import make_post_request, make_get_request
|
||||
|
||||
class EInvoiceSettings(Document):
|
||||
@@ -53,6 +54,17 @@ class EInvoiceSettings(Document):
|
||||
if encode_as_b64:
|
||||
msg_bytes = base64.b64encode(msg_bytes)
|
||||
return msg_bytes.decode()
|
||||
|
||||
def aes_encrypt(self, msg, key):
|
||||
if not (isinstance(key, bytes) or isinstance(key, bytearray)):
|
||||
key = base64.b64decode(key)
|
||||
|
||||
cipher = AES.new(key, AES.MODE_ECB)
|
||||
bytes_msg = str.encode(msg)
|
||||
padded_bytes_msg = pad(bytes_msg, AES.block_size)
|
||||
enc_msg = cipher.encrypt(padded_bytes_msg)
|
||||
b64_enc_msg = base64.b64encode(enc_msg)
|
||||
return b64_enc_msg.decode()
|
||||
|
||||
def make_authentication_request(self):
|
||||
endpoint = 'https://einv-apisandbox.nic.in/eivital/v1.03/auth'
|
||||
@@ -85,12 +97,44 @@ class EInvoiceSettings(Document):
|
||||
self.sek = sek
|
||||
self.save()
|
||||
|
||||
def get_gstin_details(self, gstin):
|
||||
endpoint = 'https://einv-apisandbox.nic.in/eivital/v1.03/Master/gstin/{gstin}'.format(gstin=gstin)
|
||||
def get_header(self):
|
||||
headers = { 'content-type': 'application/json' }
|
||||
headers.update(dict(client_id=self.client_id, client_secret=self.client_secret, user_name=self.username))
|
||||
headers.update(dict(Gstin=self.gstin, AuthToken=self.auth_token))
|
||||
|
||||
return headers
|
||||
|
||||
def get_gstin_details(self, gstin):
|
||||
endpoint = 'https://einv-apisandbox.nic.in/eivital/v1.03/Master/gstin/{gstin}'.format(gstin=gstin)
|
||||
headers = self.get_header()
|
||||
|
||||
res = make_get_request(endpoint, headers=headers)
|
||||
self.handle_err_response(res)
|
||||
|
||||
enc_json = res.get('Data')
|
||||
json_str = self.aes_decrypt(enc_json, self.sek)
|
||||
data = json.loads(json_str)
|
||||
|
||||
return data
|
||||
|
||||
def generate_irn(self, invoice):
|
||||
endpoint = 'https://einv-apisandbox.nic.in/eicore/v1.03/Invoice'
|
||||
headers = self.get_header()
|
||||
|
||||
invoice = frappe.get_doc("Sales Invoice", invoice)
|
||||
e_invoice = self.make_e_invoice(invoice)
|
||||
enc_e_invoice_json = self.aes_encrypt(e_invoice, self.sek)
|
||||
payload = dict(Data=enc_e_invoice_json)
|
||||
|
||||
res = make_post_request(endpoint, headers=headers, data=json.dumps(payload))
|
||||
self.handle_err_response(res)
|
||||
|
||||
return res
|
||||
|
||||
def get_irn_detials(self, irn):
|
||||
endpoint = 'https://einv-apisandbox.nic.in/eicore/v1.03/Invoice/irn/{irn}'.format(irn=irn)
|
||||
headers = self.get_header()
|
||||
|
||||
res = make_get_request(endpoint, headers=headers)
|
||||
self.handle_err_response(res)
|
||||
|
||||
@@ -102,12 +146,13 @@ class EInvoiceSettings(Document):
|
||||
|
||||
def handle_err_response(self, response):
|
||||
if response.get('Status') == 0:
|
||||
print(response)
|
||||
err_msg = response.get('ErrorDetails')[0].get('ErrorMessage')
|
||||
frappe.throw(_(err_msg), title=_('API Request Failed'))
|
||||
|
||||
def get_schema(self, name):
|
||||
schema_path = os.path.join(os.path.dirname(__file__), "{name}_schema.json".format(name=name))
|
||||
with open(schema_path, 'r') as f:
|
||||
def read_json(self, name):
|
||||
file_path = os.path.join(os.path.dirname(__file__), "{name}.json".format(name=name))
|
||||
with open(file_path, 'r') as f:
|
||||
return cstr(f.read())
|
||||
|
||||
def get_trans_details(self, invoice):
|
||||
@@ -127,7 +172,7 @@ class EInvoiceSettings(Document):
|
||||
def get_doc_details(self, invoice):
|
||||
invoice_type = 'CRN' if invoice.is_return else 'INV'
|
||||
invoice_name = invoice.name
|
||||
invoice_date = invoice.posting_date
|
||||
invoice_date = format_date(invoice.posting_date, 'dd/mm/yyyy')
|
||||
|
||||
return frappe._dict(dict(
|
||||
invoice_type=invoice_type, invoice_name=invoice_name, invoice_date=invoice_date
|
||||
@@ -142,7 +187,7 @@ class EInvoiceSettings(Document):
|
||||
trade_name = gstin_details.get('TradeName')
|
||||
location = gstin_details.get('AddrLoc')
|
||||
state_code = gstin_details.get('StateCode')
|
||||
pincode = gstin_details.get('AddrPncd')
|
||||
pincode = cint(gstin_details.get('AddrPncd'))
|
||||
|
||||
return frappe._dict(dict(
|
||||
gstin=gstin, legal_name=legal_name, trade_name=trade_name, location=location,
|
||||
@@ -156,13 +201,14 @@ class EInvoiceSettings(Document):
|
||||
gst_accounts_list = [d for accounts in gst_accounts.values() for d in accounts if d]
|
||||
|
||||
for d in invoice.items:
|
||||
item_schema = self.get_schema("e_inv_item")
|
||||
item_schema = self.read_json("e_inv_item_schema")
|
||||
item = frappe._dict(dict())
|
||||
item.update(d.as_dict())
|
||||
item.sr_no = d.idx
|
||||
item.description = d.item_name
|
||||
item.is_service_item = "N" if frappe.db.get_value("Item", d.item_code, "is_stock_item") else "Y"
|
||||
item.batch_expiry_date = frappe.db.get_value("Batch", d.batch_no, "expiry_date") if d.batch_no else None
|
||||
item.batch_expiry_date = format_date(item.batch_expiry_date, 'dd/mm/yyyy') if item.batch_expiry_date else None
|
||||
item.tax_rate = 0
|
||||
item.igst_amount = 0
|
||||
item.cgst_amount = 0
|
||||
@@ -219,7 +265,9 @@ class EInvoiceSettings(Document):
|
||||
return value_details
|
||||
|
||||
def make_e_invoice(self, invoice):
|
||||
schema = self.get_schema("e_inv")
|
||||
schema = self.read_json("e_inv_schema")
|
||||
validations = self.read_json("e_inv_validation")
|
||||
validations = json.loads(validations)
|
||||
|
||||
trans_details = self.get_trans_details(invoice)
|
||||
doc_details = self.get_doc_details(invoice)
|
||||
@@ -236,5 +284,55 @@ class EInvoiceSettings(Document):
|
||||
seller_details=seller_details, buyer_details=buyer_details,
|
||||
item_list=item_list, value_details=value_details
|
||||
)
|
||||
e_invoice = json.loads(e_invoice)
|
||||
|
||||
return json.loads(e_invoice)
|
||||
self.run_e_invoice_validations(validations, e_invoice)
|
||||
|
||||
return json.dumps(e_invoice)
|
||||
|
||||
def run_e_invoice_validations(self, validations, e_invoice):
|
||||
type_map = {
|
||||
"string": cstr,
|
||||
"number": cint,
|
||||
"object": dict,
|
||||
"array": list
|
||||
}
|
||||
# validate root mandatory keys
|
||||
mandatory_fields = validations.get('required')
|
||||
if mandatory_fields and not set(mandatory_fields).issubset(set(e_invoice.keys())):
|
||||
print("Mandatory condition failed")
|
||||
|
||||
for field, value in validations.items():
|
||||
if isinstance(value, list): value = value[0]
|
||||
|
||||
invoice_value = e_invoice.get(field)
|
||||
if not invoice_value:
|
||||
print(field, "Value undefined")
|
||||
continue
|
||||
|
||||
should_be_of_type = type_map[value.get('type').lower()]
|
||||
if should_be_of_type == dict:
|
||||
properties = value.get('properties')
|
||||
|
||||
if isinstance(invoice_value, list):
|
||||
for d in invoice_value:
|
||||
self.run_e_invoice_validations(properties, d)
|
||||
else:
|
||||
self.run_e_invoice_validations(properties, invoice_value)
|
||||
continue
|
||||
|
||||
e_invoice[field] = None if invoice_value == "None" else invoice_value
|
||||
e_invoice[field] = should_be_of_type(invoice_value) if e_invoice[field] else e_invoice[field]
|
||||
|
||||
should_be_of_len = value.get('maxLength')
|
||||
should_be_greater_than = value.get('minimum')
|
||||
should_be_less_than = value.get('maximum')
|
||||
pattern_str = value.get('pattern')
|
||||
pattern = re.compile(pattern_str or "")
|
||||
|
||||
if should_be_of_type == 'string' and not len(invoice_value) <= should_be_of_len:
|
||||
print("Max Length Exceeded", field, invoice_value)
|
||||
if should_be_of_type == 'number' and not (should_be_greater_than <= invoice_value <= should_be_of_len):
|
||||
print("Value too large", field, invoice_value)
|
||||
if pattern_str and not pattern.match(invoice_value):
|
||||
print("Pattern Mismatch", field, invoice_value)
|
||||
|
||||
Reference in New Issue
Block a user