Skip to content

Commit 73b3598

Browse files
committed
Add remaining web services
1 parent 942883e commit 73b3598

File tree

7 files changed

+286
-129
lines changed

7 files changed

+286
-129
lines changed

afip/afip.py

Lines changed: 79 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,96 @@
11
import http.client
22
import json
33

4-
from .webservice import WebService
5-
from .electronicbilling import ElectronicBilling
4+
from .web_service import WebService
5+
from .electronic_billing import ElectronicBilling
6+
from .register_inscription_proof import RegisterInscriptionProof
7+
from .register_scope_ten import RegisterScopeTen
8+
from .register_scope_thirteen import RegisterScopeThirteen
69

710
class Afip:
8-
sdk_version_number = '1.0.0'
9-
10-
def __init__(self, options: dict):
11-
if not(options.get("CUIT")):
12-
raise Exception("CUIT field is required in options")
13-
14-
self.CUIT: int = options.get("CUIT")
15-
self.production: bool = options.get("production") if options.get("production") == True else False
16-
self.environment: str = "prod" if self.production == True else "dev"
17-
self.cert: str = options.get("cert")
18-
self.key: str = options.get("key")
19-
self.access_token: str = options.get("access_token")
11+
sdk_version_number = '1.0.0'
12+
13+
def __init__(self, options: dict):
14+
if not(options.get("CUIT")):
15+
raise Exception("CUIT field is required in options")
16+
17+
self.CUIT: int = options.get("CUIT")
18+
self.production: bool = options.get("production") if options.get("production") == True else False
19+
self.environment: str = "prod" if self.production == True else "dev"
20+
self.cert: str = options.get("cert")
21+
self.key: str = options.get("key")
22+
self.access_token: str = options.get("access_token")
23+
24+
self.ElectronicBilling = ElectronicBilling(self)
25+
self.RegisterInscriptionProof = RegisterInscriptionProof(self)
26+
self.RegisterScopeTen = RegisterScopeTen(self)
27+
self.RegisterScopeThirteen = RegisterScopeThirteen(self)
28+
29+
30+
# Gets token authorization for an AFIP Web Service
31+
#
32+
# If force is true it forces to create a new TA
33+
def getServiceTA(self, service: str, force: bool = False) -> dict:
34+
conn = http.client.HTTPSConnection("app.afipsdk.com")
35+
36+
payload = {
37+
"environment": self.environment,
38+
"tax_id": self.CUIT,
39+
"wsid": service,
40+
"force_create": force
41+
}
42+
43+
if self.cert: payload["cert"] = self.cert
44+
if self.key: payload["key"] = self.key
45+
46+
headers = {
47+
"Content-Type": "application/json",
48+
"sdk-version-number": self.sdk_version_number,
49+
"sdk-library": "python",
50+
"sdk-environment": self.environment
51+
}
52+
53+
if self.access_token: headers["Authorization"] = "Bearer %s" % self.access_token
54+
55+
conn.request("POST", "/api/v1/afip/auth", json.dumps(payload), headers)
56+
57+
res = conn.getresponse()
2058

21-
self.ElectronicBilling = ElectronicBilling(self)
59+
data = res.read()
2260

61+
if res.getcode() >= 400:
62+
raise Exception(data.decode("utf-8"))
2363

24-
# Gets token authorization for an AFIP Web Service
25-
#
26-
# If force is true it forces to create a new TA
27-
def getServiceTA(self, service: str, force: bool = False) -> dict:
28-
conn = http.client.HTTPSConnection("app.afipsdk.com")
64+
return json.loads(data.decode("utf-8"))
65+
66+
# Get last request and last response XML
67+
def getLastRequestXML(self) -> dict:
68+
conn = http.client.HTTPSConnection("app.afipsdk.com")
2969

30-
payload = {
31-
"environment": self.environment,
32-
"tax_id": self.CUIT,
33-
"wsid": service,
34-
"force_create": force
35-
}
70+
headers = {
71+
"Content-Type": "application/json",
72+
"sdk-version-number": self.sdk_version_number,
73+
"sdk-library": "python",
74+
"sdk-environment": self.environment
75+
}
3676

37-
if self.cert: payload["cert"] = self.cert
38-
if self.key: payload["key"] = self.key
77+
if self.access_token: headers["Authorization"] = "Bearer %s" % self.access_token
3978

40-
headers = {
41-
"Content-Type": "application/json",
42-
"sdk-version-number": self.sdk_version_number,
43-
"sdk-library": "python",
44-
"sdk-environment": self.environment
45-
}
79+
conn.request("GET", "/api/v1/afip/requests/last-xml", None, headers)
4680

47-
if self.access_token: headers["Authorization"] = "Bearer %s" % self.access_token
48-
49-
conn.request("POST", "/api/v1/afip/auth", json.dumps(payload), headers)
50-
51-
res = conn.getresponse()
52-
53-
data = res.read()
54-
55-
if res.getcode() >= 400:
56-
raise Exception(data.decode("utf-8"))
57-
58-
return json.loads(data.decode("utf-8"))
81+
res = conn.getresponse()
5982

60-
# Get last request and last response XML
61-
def getLastRequestXML(self) -> dict:
62-
conn = http.client.HTTPSConnection("app.afipsdk.com")
63-
64-
headers = {
65-
"Content-Type": "application/json",
66-
"sdk-version-number": self.sdk_version_number,
67-
"sdk-library": "python",
68-
"sdk-environment": self.environment
69-
}
83+
data = res.read()
7084

71-
if self.access_token: headers["Authorization"] = "Bearer %s" % self.access_token
85+
if res.getcode() >= 400:
86+
raise Exception(data.decode("utf-8"))
7287

73-
conn.request("GET", "/api/v1/afip/requests/last-xml", None, headers)
74-
75-
res = conn.getresponse()
76-
77-
data = res.read()
78-
79-
if res.getcode() >= 400:
80-
raise Exception(data.decode("utf-8"))
81-
82-
return json.loads(data.decode("utf-8"))
83-
88+
return json.loads(data.decode("utf-8"))
89+
8490

85-
# Create generic Web Service
86-
def webService(self, service, options: dict = {}) -> WebService:
87-
options['service'] = service
88-
options['generic'] = True
91+
# Create generic Web Service
92+
def webService(self, service, options: dict = {}) -> WebService:
93+
options['service'] = service
94+
options['generic'] = True
8995

90-
return WebService(self, options)
96+
return WebService(self, options)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import json
33
import re
44

5-
from .webservice import WebService
5+
from .web_service import WebService
66

77
class ElectronicBilling(WebService):
88
soapv12 = True

afip/register_inscription_proof.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from .web_service import WebService
2+
3+
class RegisterInscriptionProof(WebService):
4+
soapv12 = False
5+
WSDL = "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL"
6+
URL = "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA5"
7+
WSDL_TEST = "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL"
8+
URL_TEST = "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA5"
9+
10+
def __init__(self, afip):
11+
super(RegisterInscriptionProof, self).__init__(afip, { "service": "ws_sr_constancia_inscripcion" })
12+
13+
# Asks to web service for taxpayer details
14+
def getTaxpayerDetails(self, identifier: int):
15+
# Get token and sign
16+
ta = self.getTokenAuthorization()
17+
18+
# Prepare params
19+
params = {
20+
"token": ta["token"],
21+
"sign": ta["sign"],
22+
"cuitRepresentada": self.afip.CUIT,
23+
"idPersona": identifier
24+
}
25+
26+
return self.executeRequest("getPersona_v2", params)
27+
28+
# Asks to web service for taxpayers details
29+
def getTaxpayersDetails(self, identifiers: list):
30+
# Get token and sign
31+
ta = self.getTokenAuthorization()
32+
33+
# Prepare params
34+
params = {
35+
"token": ta["token"],
36+
"sign": ta["sign"],
37+
"cuitRepresentada": self.afip.CUIT,
38+
"idPersona": identifiers
39+
}
40+
41+
return self.executeRequest("getPersonaList_v2", params)["persona"]
42+
43+
# Asks to web service for servers status
44+
def getServerStatus(self):
45+
return self.executeRequest("dummy")
46+
47+
# Send request to AFIP servers
48+
def executeRequest(self, operation, params = {}):
49+
results = super(RegisterInscriptionProof, self).executeRequest(operation, params)
50+
51+
if operation == "getPersona_v2":
52+
return results["personaReturn"]
53+
elif operation == "getPersonaList_v2":
54+
return results["personaListReturn"]
55+
else:
56+
return results["return"]

afip/register_scope_ten.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from .web_service import WebService
2+
3+
class RegisterScopeTen(WebService):
4+
soapv12 = False
5+
WSDL = "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA10?WSDL"
6+
URL = "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA10"
7+
WSDL_TEST = "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA10?WSDL"
8+
URL_TEST = "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA10"
9+
10+
def __init__(self, afip):
11+
super(RegisterScopeTen, self).__init__(afip, { "service": "ws_sr_padron_a10" })
12+
13+
# Asks to web service for taxpayer details
14+
def getTaxpayerDetails(self, identifier: int):
15+
# Get token and sign
16+
ta = self.getTokenAuthorization()
17+
18+
# Prepare params
19+
params = {
20+
"token": ta["token"],
21+
"sign": ta["sign"],
22+
"cuitRepresentada": self.afip.CUIT,
23+
"idPersona": identifier
24+
}
25+
26+
return self.executeRequest("getPersona", params)
27+
28+
# Asks to web service for servers status
29+
def getServerStatus(self):
30+
return self.executeRequest("dummy")
31+
32+
# Send request to AFIP servers
33+
def executeRequest(self, operation, params = {}):
34+
results = super(RegisterScopeTen, self).executeRequest(operation, params)
35+
36+
if operation == "getPersona":
37+
return results["personaReturn"]
38+
else:
39+
return results["return"]

afip/register_scope_thirteen.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from .web_service import WebService
2+
3+
class RegisterScopeThirteen(WebService):
4+
soapv12 = False
5+
WSDL = "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA13?WSDL"
6+
URL = "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA13"
7+
WSDL_TEST = "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA13?WSDL"
8+
URL_TEST = "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA13"
9+
10+
def __init__(self, afip):
11+
super(RegisterScopeThirteen, self).__init__(afip, { "service": "ws_sr_padron_a13" })
12+
13+
# Asks to web service for taxpayer details
14+
def getTaxpayerDetails(self, identifier: int):
15+
# Get token and sign
16+
ta = self.getTokenAuthorization()
17+
18+
# Prepare params
19+
params = {
20+
"token": ta["token"],
21+
"sign": ta["sign"],
22+
"cuitRepresentada": self.afip.CUIT,
23+
"idPersona": identifier
24+
}
25+
26+
return self.executeRequest("getPersona", params)
27+
28+
# Asks to web service for tax id by document number
29+
def getTaxIDByDocument(self, document_number: int):
30+
# Get token and sign
31+
ta = self.getTokenAuthorization()
32+
33+
# Prepare params
34+
params = {
35+
"token": ta["token"],
36+
"sign": ta["sign"],
37+
"cuitRepresentada": self.afip.CUIT,
38+
"documento": document_number
39+
}
40+
41+
return self.executeRequest("getIdPersonaListByDocumento", params)["idPersona"]
42+
43+
# Asks to web service for servers status
44+
def getServerStatus(self):
45+
return self.executeRequest("dummy")
46+
47+
# Send request to AFIP servers
48+
def executeRequest(self, operation, params = {}):
49+
results = super(RegisterScopeThirteen, self).executeRequest(operation, params)
50+
51+
if operation == "getPersona":
52+
return results["personaReturn"]
53+
elif operation == "getIdPersonaListByDocumento":
54+
return results["idPersonaListReturn"]
55+
else:
56+
return results["return"]

afip/web_service.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import http.client
2+
import json
3+
4+
class WebService:
5+
def __init__(self, afip, options: dict = {}):
6+
self.afip = afip
7+
self.options = options
8+
self.WSDL = options.get('WSDL')
9+
self.URL = options.get('URL')
10+
self.WSDL_TEST = options.get('WSDL_TEST')
11+
self.URL_TEST = options.get('URL_TEST')
12+
self.soapv12 = options.get('soapV1_2')
13+
14+
if not(options.get('service')):
15+
raise Exception("service field is required in options")
16+
17+
# Gets token authorization for an AFIP Web Service
18+
#
19+
# If force is true it forces to create a new TA
20+
def getTokenAuthorization(self, force = False) -> dict:
21+
return self.afip.getServiceTA(self.options.get('service'), force)
22+
23+
# Sends request to AFIP servers
24+
def executeRequest(self, method, params = {}) -> dict:
25+
conn = http.client.HTTPSConnection("app.afipsdk.com")
26+
27+
payload = {
28+
"method": method,
29+
"params": params,
30+
"environment": self.afip.environment,
31+
"wsid": self.options.get('service'),
32+
"url": self.URL if self.afip.production else self.URL_TEST,
33+
"wsdl": self.WSDL if self.afip.production else self.WSDL_TEST,
34+
"soap_v_1_2": self.soapv12
35+
}
36+
37+
headers = {
38+
"Content-Type": "application/json",
39+
"sdk-version-number": self.afip.sdk_version_number,
40+
"sdk-library": "python",
41+
"sdk-environment": self.afip.environment
42+
}
43+
44+
if self.afip.access_token: headers["Authorization"] = "Bearer %s" % self.afip.access_token
45+
46+
conn.request("POST", "/api/v1/afip/requests", json.dumps(payload), headers)
47+
48+
res = conn.getresponse()
49+
50+
data = res.read()
51+
52+
if res.getcode() >= 400:
53+
raise Exception(data.decode("utf-8"))
54+
55+
return json.loads(data.decode("utf-8"))

0 commit comments

Comments
 (0)