Skip to content

Commit 490fc71

Browse files
committed
rtc.data_models: validate 'fecha_ultimo_vencimiento' is consistent with dte
Validate 'fecha_ultimo_vencimiento' of the "cesión" is after or equal to 'fecha_emision' of the DTE. Source: (https://www.sii.cl/factura_electronica/ins_tecnico.pdf)
1 parent 1ec38a0 commit 490fc71

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed

cl_sii/rtc/data_models.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ def validate_cesion_and_dte_montos(cesion_value: int, dte_value: int) -> None:
9797
raise ValueError('Value of "cesión" must be <= value of DTE.', cesion_value, dte_value)
9898

9999

100+
def validate_cesion_fecha_ultimo_vencimiento_is_consistent_with_dte(
101+
cesion_value: date, dte_value: date
102+
) -> None:
103+
"""
104+
Validate 'fecha_ultimo_vencimiento' of the "cesión" is after or equal
105+
to 'fecha_emision' of the DTE.
106+
107+
:raises ValueError:
108+
"""
109+
if not (cesion_value >= dte_value):
110+
raise ValueError('Value of "cesión" must be >= value of DTE.', cesion_value, dte_value)
111+
112+
100113
@pydantic.dataclasses.dataclass(
101114
frozen=True,
102115
config=type('Config', (), dict(
@@ -531,6 +544,20 @@ def validate_monto_cedido_does_not_exceed_dte_monto_total(
531544

532545
return values
533546

547+
@pydantic.root_validator(skip_on_failure=True)
548+
def validate_fecha_ultimo_vencimiento_is_consistent_with_dte(
549+
cls, values: Mapping[str, object],
550+
) -> Mapping[str, object]:
551+
fecha_ultimo_vencimiento = values['fecha_ultimo_vencimiento']
552+
dte_fecha_emision = values['dte_fecha_emision']
553+
554+
if isinstance(fecha_ultimo_vencimiento, date) and isinstance(dte_fecha_emision, date):
555+
validate_cesion_fecha_ultimo_vencimiento_is_consistent_with_dte(
556+
cesion_value=fecha_ultimo_vencimiento, dte_value=dte_fecha_emision
557+
)
558+
559+
return values
560+
534561

535562
@pydantic.dataclasses.dataclass(
536563
frozen=True,
@@ -694,8 +721,6 @@ def as_dte_data_l2(self) -> dte_data_models.DteDataL2:
694721

695722
# TODO: Validate value of 'fecha_firma_dt' in relation to the DTE data.
696723

697-
# TODO: Validate value of 'fecha_ultimo_vencimiento' in relation to the DTE data.
698-
699724
@pydantic.validator('fecha_cesion_dt')
700725
def validate_fecha_cesion_dt(cls, v: object) -> object:
701726
if isinstance(v, datetime):
@@ -739,3 +764,17 @@ def validate_dte_data_l2(cls, values: Mapping[str, Any]) -> Mapping[str, object]
739764
raise
740765

741766
return values
767+
768+
@pydantic.root_validator(skip_on_failure=True)
769+
def validate_fecha_ultimo_vencimiento_is_consistent_with_dte(
770+
cls, values: Mapping[str, object],
771+
) -> Mapping[str, object]:
772+
fecha_ultimo_vencimiento = values['fecha_ultimo_vencimiento']
773+
dte_fecha_emision = values['dte_fecha_emision']
774+
775+
if isinstance(fecha_ultimo_vencimiento, date) and isinstance(dte_fecha_emision, date):
776+
validate_cesion_fecha_ultimo_vencimiento_is_consistent_with_dte(
777+
cesion_value=fecha_ultimo_vencimiento, dte_value=dte_fecha_emision
778+
)
779+
780+
return values

cl_sii/rtc/data_models_aec.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,9 @@ def validate_fecha_ultimo_vencimiento_is_consistent_with_dte(
367367
isinstance(fecha_ultimo_vencimiento, date)
368368
and isinstance(dte, dte_data_models.DteDataL1)
369369
):
370-
pass # TODO: Validate value of 'fecha_ultimo_vencimiento' in relation to the DTE data.
370+
data_models.validate_cesion_fecha_ultimo_vencimiento_is_consistent_with_dte(
371+
cesion_value=fecha_ultimo_vencimiento, dte_value=dte.fecha_emision_date
372+
)
371373

372374
return values
373375

tests/test_rtc_data_models.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,32 @@ def test_validate_monto_cedido_does_not_exceed_dte_monto_total(self) -> None:
725725
for expected_validation_error in expected_validation_errors:
726726
self.assertIn(expected_validation_error, validation_errors)
727727

728+
def test_validate_fecha_ultimo_vencimiento_is_not_before_dte_fecha_emision(self) -> None:
729+
self._set_obj_1()
730+
731+
obj = self.obj_1
732+
expected_validation_errors = [
733+
{
734+
'loc': ('__root__',),
735+
'msg':
736+
"""('Value of "cesión" must be >= value of DTE.',"""
737+
" datetime.date(2019, 5, 1), datetime.date(2019, 5, 2))",
738+
'type': 'value_error',
739+
},
740+
]
741+
742+
with self.assertRaises(pydantic.ValidationError) as assert_raises_cm:
743+
dataclasses.replace(
744+
obj,
745+
fecha_ultimo_vencimiento=date(2019, 5, 1),
746+
dte_fecha_emision=date(2019, 5, 2),
747+
)
748+
749+
validation_errors = assert_raises_cm.exception.errors()
750+
self.assertEqual(len(validation_errors), len(expected_validation_errors))
751+
for expected_validation_error in expected_validation_errors:
752+
self.assertIn(expected_validation_error, validation_errors)
753+
728754

729755
class CesionL2Test(CesionL1Test):
730756
"""

0 commit comments

Comments
 (0)