Skip to content

Commit f132946

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 5334980 commit f132946

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
@@ -99,6 +99,19 @@ def validate_cesion_and_dte_montos(cesion_value: int, dte_value: int) -> None:
9999
raise ValueError('Value of "cesión" must be <= value of DTE.', cesion_value, dte_value)
100100

101101

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

538551
return values
539552

553+
@pydantic.root_validator(skip_on_failure=True)
554+
def validate_fecha_ultimo_vencimiento_is_consistent_with_dte(
555+
cls, values: Mapping[str, object],
556+
) -> Mapping[str, object]:
557+
fecha_ultimo_vencimiento = values['fecha_ultimo_vencimiento']
558+
dte_fecha_emision = values['dte_fecha_emision']
559+
560+
if isinstance(fecha_ultimo_vencimiento, date) and isinstance(dte_fecha_emision, date):
561+
validate_cesion_fecha_ultimo_vencimiento_is_consistent_with_dte(
562+
cesion_value=fecha_ultimo_vencimiento, dte_value=dte_fecha_emision
563+
)
564+
565+
return values
566+
540567

541568
@pydantic.dataclasses.dataclass(
542569
frozen=True,
@@ -700,8 +727,6 @@ def as_dte_data_l2(self) -> dte_data_models.DteDataL2:
700727

701728
# TODO: Validate value of 'fecha_firma_dt' in relation to the DTE data.
702729

703-
# TODO: Validate value of 'fecha_ultimo_vencimiento' in relation to the DTE data.
704-
705730
@pydantic.validator('fecha_cesion_dt')
706731
def validate_fecha_cesion_dt(cls, v: object) -> object:
707732
if isinstance(v, datetime):
@@ -745,3 +770,17 @@ def validate_dte_data_l2(cls, values: Mapping[str, Any]) -> Mapping[str, object]
745770
raise
746771

747772
return values
773+
774+
@pydantic.root_validator(skip_on_failure=True)
775+
def validate_fecha_ultimo_vencimiento_is_consistent_with_dte(
776+
cls, values: Mapping[str, object],
777+
) -> Mapping[str, object]:
778+
fecha_ultimo_vencimiento = values['fecha_ultimo_vencimiento']
779+
dte_fecha_emision = values['dte_fecha_emision']
780+
781+
if isinstance(fecha_ultimo_vencimiento, date) and isinstance(dte_fecha_emision, date):
782+
validate_cesion_fecha_ultimo_vencimiento_is_consistent_with_dte(
783+
cesion_value=fecha_ultimo_vencimiento, dte_value=dte_fecha_emision
784+
)
785+
786+
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
@@ -730,6 +730,32 @@ def test_validate_monto_cedido_does_not_exceed_dte_monto_total(self) -> None:
730730
for expected_validation_error in expected_validation_errors:
731731
self.assertIn(expected_validation_error, validation_errors)
732732

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

734760
class CesionL2Test(CesionL1Test):
735761
"""

0 commit comments

Comments
 (0)