Skip to content

Commit

Permalink
rtc.data_models_aec: add validation for 'cedente_rut'
Browse files Browse the repository at this point in the history
The 'cedente_rut' should be the DTE's 'emisor_rut' or the
last 'cesionario_rut' when the sequence is greater than 2
Condition sourced from document "Instructivo Técnico
Registro Público Electrónico de Transferencia de Crédito"
Source: (https://www.sii.cl/factura_electronica/ins_tecnico.pdf)
  • Loading branch information
ycouce-cdd committed Mar 4, 2021
1 parent e34b569 commit d816913
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
22 changes: 22 additions & 0 deletions cl_sii/rtc/data_models_aec.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,28 @@ def validate_last_cesion_matches_some_fields(

return values

@pydantic.root_validator(skip_on_failure=True)
def validate_cesiones_rut_cedente_match_previous_rut_cesionario_or_dte_emisor(
cls, values: Mapping[str, object],
) -> Mapping[str, object]:
dte = values['dte']
cesiones = values['cesiones']

if isinstance(dte, dte_data_models.DteXmlData) and isinstance(cesiones, Sequence):
dte_l1 = dte.as_dte_data_l1()
valid_cedente_rut = dte_l1.emisor_rut
for cesion in cesiones:
if cesion.cedente_rut != valid_cedente_rut:
raise ValueError(
f"'cedente_rut' of 'cesion' must match previous 'cesionario_rut'"
f" or DTE\'s 'emisor_rut' if there is no previuos 'cesion'"
f" {cesion.cedente_rut!r} != {valid_cedente_rut!r}.",
)

valid_cedente_rut = cesion.cesionario_rut

return values

# @pydantic.root_validator
# def validate_signature_value_and_signature_x509_cert_der_may_only_be_none_together(
# cls, values: Mapping[str, object],
Expand Down
71 changes: 71 additions & 0 deletions tests/test_rtc_data_models_aec.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,74 @@ def test_validate_last_cesion_matches_some_fields(self) -> None:
self.assertEqual(len(validation_errors), len(expected_validation_errors))
for expected_validation_error in expected_validation_errors:
self.assertIn(expected_validation_error, validation_errors)

def test_validate_cedente_rut_matches_emisor_rut_in_cesion_seq_1(self) -> None:
self._set_obj_1()

obj = self.obj_1

expected_validation_errors = [
{
'loc': ('__root__',),
'msg':
"'cedente_rut' of 'cesion' must match previous 'cesionario_rut'"
" or DTE\'s 'emisor_rut' if there is no previuos 'cesion'"
" Rut('76389992-6')"
" !="
" Rut('76354771-K').", # DTE's emisor RUT
'type': 'value_error',
},
]

with self.assertRaises(pydantic.ValidationError) as assert_raises_cm:
dataclasses.replace(
obj,
cesiones=[
dataclasses.replace(
obj.cesiones[0],
cedente_rut=obj.cesiones[0].cesionario_rut,
),
obj.cesiones[1],
],
)

validation_errors = assert_raises_cm.exception.errors()
self.assertEqual(len(validation_errors), len(expected_validation_errors))
for expected_validation_error in expected_validation_errors:
self.assertIn(expected_validation_error, validation_errors)

def test_validate_cedente_rut_matches_cesionario_rut_in_cesion_seq_2(self) -> None:
self._set_obj_1()

obj = self.obj_1

expected_validation_errors = [
{
'loc': ('__root__',),
'msg':
"'cedente_rut' of 'cesion' must match previous 'cesionario_rut'"
" or DTE\'s 'emisor_rut' if there is no previuos 'cesion'"
" Rut('76598556-0')"
" !="
" Rut('76389992-6').", # RUT of the 'cesionario' of the 'cesion' sequence 1
'type': 'value_error',
},
]

with self.assertRaises(pydantic.ValidationError) as assert_raises_cm:
dataclasses.replace(
obj,
cedente_rut=obj.cesiones[1].cesionario_rut, # To skip previous validation
cesiones=[
obj.cesiones[0],
dataclasses.replace(
obj.cesiones[1],
cedente_rut=obj.cesiones[1].cesionario_rut,
),
],
)

validation_errors = assert_raises_cm.exception.errors()
self.assertEqual(len(validation_errors), len(expected_validation_errors))
for expected_validation_error in expected_validation_errors:
self.assertIn(expected_validation_error, validation_errors)

0 comments on commit d816913

Please sign in to comment.