Skip to content

Commit d816913

Browse files
committed
rtc.data_models_aec: add validation for 'cedente_rut'
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)
1 parent e34b569 commit d816913

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

cl_sii/rtc/data_models_aec.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,28 @@ def validate_last_cesion_matches_some_fields(
768768

769769
return values
770770

771+
@pydantic.root_validator(skip_on_failure=True)
772+
def validate_cesiones_rut_cedente_match_previous_rut_cesionario_or_dte_emisor(
773+
cls, values: Mapping[str, object],
774+
) -> Mapping[str, object]:
775+
dte = values['dte']
776+
cesiones = values['cesiones']
777+
778+
if isinstance(dte, dte_data_models.DteXmlData) and isinstance(cesiones, Sequence):
779+
dte_l1 = dte.as_dte_data_l1()
780+
valid_cedente_rut = dte_l1.emisor_rut
781+
for cesion in cesiones:
782+
if cesion.cedente_rut != valid_cedente_rut:
783+
raise ValueError(
784+
f"'cedente_rut' of 'cesion' must match previous 'cesionario_rut'"
785+
f" or DTE\'s 'emisor_rut' if there is no previuos 'cesion'"
786+
f" {cesion.cedente_rut!r} != {valid_cedente_rut!r}.",
787+
)
788+
789+
valid_cedente_rut = cesion.cesionario_rut
790+
791+
return values
792+
771793
# @pydantic.root_validator
772794
# def validate_signature_value_and_signature_x509_cert_der_may_only_be_none_together(
773795
# cls, values: Mapping[str, object],

tests/test_rtc_data_models_aec.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,3 +678,74 @@ def test_validate_last_cesion_matches_some_fields(self) -> None:
678678
self.assertEqual(len(validation_errors), len(expected_validation_errors))
679679
for expected_validation_error in expected_validation_errors:
680680
self.assertIn(expected_validation_error, validation_errors)
681+
682+
def test_validate_cedente_rut_matches_emisor_rut_in_cesion_seq_1(self) -> None:
683+
self._set_obj_1()
684+
685+
obj = self.obj_1
686+
687+
expected_validation_errors = [
688+
{
689+
'loc': ('__root__',),
690+
'msg':
691+
"'cedente_rut' of 'cesion' must match previous 'cesionario_rut'"
692+
" or DTE\'s 'emisor_rut' if there is no previuos 'cesion'"
693+
" Rut('76389992-6')"
694+
" !="
695+
" Rut('76354771-K').", # DTE's emisor RUT
696+
'type': 'value_error',
697+
},
698+
]
699+
700+
with self.assertRaises(pydantic.ValidationError) as assert_raises_cm:
701+
dataclasses.replace(
702+
obj,
703+
cesiones=[
704+
dataclasses.replace(
705+
obj.cesiones[0],
706+
cedente_rut=obj.cesiones[0].cesionario_rut,
707+
),
708+
obj.cesiones[1],
709+
],
710+
)
711+
712+
validation_errors = assert_raises_cm.exception.errors()
713+
self.assertEqual(len(validation_errors), len(expected_validation_errors))
714+
for expected_validation_error in expected_validation_errors:
715+
self.assertIn(expected_validation_error, validation_errors)
716+
717+
def test_validate_cedente_rut_matches_cesionario_rut_in_cesion_seq_2(self) -> None:
718+
self._set_obj_1()
719+
720+
obj = self.obj_1
721+
722+
expected_validation_errors = [
723+
{
724+
'loc': ('__root__',),
725+
'msg':
726+
"'cedente_rut' of 'cesion' must match previous 'cesionario_rut'"
727+
" or DTE\'s 'emisor_rut' if there is no previuos 'cesion'"
728+
" Rut('76598556-0')"
729+
" !="
730+
" Rut('76389992-6').", # RUT of the 'cesionario' of the 'cesion' sequence 1
731+
'type': 'value_error',
732+
},
733+
]
734+
735+
with self.assertRaises(pydantic.ValidationError) as assert_raises_cm:
736+
dataclasses.replace(
737+
obj,
738+
cedente_rut=obj.cesiones[1].cesionario_rut, # To skip previous validation
739+
cesiones=[
740+
obj.cesiones[0],
741+
dataclasses.replace(
742+
obj.cesiones[1],
743+
cedente_rut=obj.cesiones[1].cesionario_rut,
744+
),
745+
],
746+
)
747+
748+
validation_errors = assert_raises_cm.exception.errors()
749+
self.assertEqual(len(validation_errors), len(expected_validation_errors))
750+
for expected_validation_error in expected_validation_errors:
751+
self.assertIn(expected_validation_error, validation_errors)

0 commit comments

Comments
 (0)