8000 Add ENCF validation support for Dominican Republic NCF · Dzikpol/python-stdnum@2b452b6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2b452b6

Browse files
crisogarthurdejong
authored andcommitted
Add ENCF validation support for Dominican Republic NCF
Closes arthurdejong#248
1 parent eeaf665 commit 2b452b6

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

stdnum/do/ncf.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,21 +140,30 @@ def _convert_result(result): # pragma: no cover
140140
'Estado': 'status',
141141
'Tipo de comprobante': 'type',
142142
u'Válido hasta': 'valid_until',
143+
u'Código de Seguridad': 'security_code',
144+
'Rnc Emisor': 'issuing_rnc',
145+
'Rnc Comprador': 'buyer_rnc',
146+
'Monto Total': 'total',
147+
'Total de ITBIS': 'total_itbis',
148+
'Fecha Emisi&oacuten': 'issuing_date',
149+
u'Fecha Emisión': 'issuing_date',
150+
u'Fecha de Firma': 'signature_date',
151+
'e-NCF': 'ncf',
143152
}
144153
return dict(
145154
(translation.get(key, key), value)
146155
for key, value in result.items())
147156

148157

149-
def check_dgii(rnc, ncf, timeout=30): # pragma: no cover
158+
def check_dgii(rnc, ncf, buyer_rnc=None, security_code=None, timeout=30): # pragma: no cover
150159
"""Validate the RNC, NCF combination on using the DGII online web service.
151160
152161
This uses the validation service run by the the Dirección General de
153162
Impuestos Internos, the Dominican Republic tax department to check
154163
whether the combination of RNC and NCF is valid. The timeout is in
155164
seconds.
156165
157-
Returns a dict with the following structure::
166+
Returns a dict with the following structure for a NCF::
158167
159168
{
160169
'name': 'The registered name',
@@ -165,12 +174,29 @@ def check_dgii(rnc, ncf, timeout=30): # pragma: no cover
165174
'validation_message': 'El NCF digitado es válido.',
166175
}
167176
177+
For an ECNF::
178+
179+
{
180+
'status': 'Aceptado',
181+
'issuing_rnc': '1234567890123',
182+
'buyer_rnc': '123456789',
183+
'ncf': 'E300000000000',
184+
'security_code': '1+2kP3',
185+
'issuing_date': '2020-03-25',
186+
'signature_date': '2020-03-22',
187+
'total': '2203.50',
188+
'total_itbis': '305.10',
189+
'validation_message': 'Aceptado',
190+
}
191+
168192
Will return None if the number is invalid or unknown."""
169193
import lxml.html
170194
import requests
171195
from stdnum.do.rnc import compact as rnc_compact # noqa: I003
172196
rnc = rnc_compact(rnc)
173197
ncf = compact(ncf)
198+
if buyer_rnc:
199+
buyer_rnc = rnc_compact(buyer_rnc)
174200
url = 'https://dgii.gov.do/app/WebApps/ConsultasWeb2/ConsultasWeb/consultas/ncf.aspx'
175201
session = requests.Session()
176202
session.headers.update({
@@ -188,13 +214,18 @@ def check_dgii(rnc, ncf, timeout=30): # pragma: no cover
188214
'ctl00$cphMain$txtNCF': ncf,
189215
'ctl00$cphMain$txtRNC': rnc,
190216
}
217+
if ncf[0] == 'E':
218+
data['ctl00$cphMain$txtRncComprador'] = buyer_rnc
219+
data['ctl00$cphMain$txtCodigoSeg'] = security_code
191220
# Do the actual request
192221
document = lxml.html.fromstring(
193222
session.post(url, data=data, timeout=timeout).text)
194-
result = document.find('.//div[@id="cphMain_pResultado"]')
223+
result_path = './/div[@id="cphMain_PResultadoFE"]' if ncf[0] == 'E' else './/div[@id="cphMain_pResultado"]'
224+
result = document.find(result_path)
195225
if result is not None:
226+
lbl_path = './/*[@id="cphMain_lblEstadoFe"]' if ncf[0] == 'E' else './/*[@id="cphMain_lblInformacion"]'
196227
data = {
197-
'validation_message': document.findtext('.//*[@id="cphMain_lblInformacion"]').strip(),
228+
'validation_message': document.findtext(lbl_path).strip(),
198229
}
199230
data.update(zip(
200231
[x.text.strip() for x in result.findall('.//th')],

tests/test_do_ncf.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,16 @@ def test_check_dgii(self):
6464
self.assertIn('validation_message', result.keys())
6565
self.assertEqual(result['rnc'], '130546312')
6666
self.assertEqual(result['ncf'], 'B0100000005')
67+
# Test the ENCF
68+
result = ncf.check_dgii('101010632', 'E310049533639',
69+
buyer_rnc='22400559690', security_code='hnI63Q')
70+
self.assertTrue(result)
71+
self.assertIn('status', result.keys())
72+
self.assertEqual(result['issuing_rnc'], '101010632')
73+
self.assertEqual(result['buyer_rnc'], '22400559690')
74+
self.assertEqual(result['ncf'], 'E310049533639')
75+
self.assertIn('issuing_date', result.keys())
76+
self.assertIn('signature_date', result.keys())
77+
self.assertIn('total', result.keys())
78+
self.assertIn('total_itbis', result.keys())
79+
self.assertIn('validation_message', result.keys())

0 commit comments

Comments
 (0)
0