Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions src/cl_sii/rcv/data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ class OtrosImpuestos(TypedDict):
"""


class DocumentoReferencia(TypedDict):
tipo_documento_referencia: int
"""
Tipo Docto. Referencia
"""

folio_documento_referencia: int
"""
Folio Docto. Referencia
"""


@pydantic.dataclasses.dataclass(
frozen=True,
config=pydantic.ConfigDict(
Expand Down Expand Up @@ -409,14 +421,11 @@ class RvDetalleEntry(RcvDetalleEntry):
IVA fuera de plazo
"""

tipo_documento_referencia: Optional[int]
"""
Tipo Docto. Referencia
documento_referencias: Optional[Sequence[DocumentoReferencia]]
"""

folio_documento_referencia: Optional[int]
"""
Folio Docto. Referencia
List of:
- Tipo Docto. Referencia
- Folio Docto. Referencia
"""

num_ident_receptor_extranjero: Optional[str]
Expand Down
115 changes: 103 additions & 12 deletions src/cl_sii/rcv/parse_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,18 @@
import logging
from collections.abc import MutableMapping
from datetime import date, datetime
from typing import Any, Callable, Dict, Iterable, Optional, Sequence, Tuple, TypedDict, TypeVar
from typing import (
Any,
Callable,
Dict,
Iterable,
Optional,
Sequence,
Tuple,
TypedDict,
TypeVar,
Union,
)

import marshmallow
import marshmallow.experimental.context
Expand Down Expand Up @@ -584,15 +595,17 @@ class RcvVentaCsvRowSchema(_RcvCsvRowSchemaBase):
required=True,
data_key='IVA fuera de plazo',
)
tipo_documento_referencia = marshmallow.fields.Integer(
required=False,
allow_none=True,
data_key='Tipo Docto. Referencia',
)
folio_documento_referencia = marshmallow.fields.Integer(
documento_referencias = marshmallow.fields.List(
required=False,
allow_none=True,
data_key='Folio Docto. Referencia',
data_key='Documento Referencias',
cls_or_instance=marshmallow.fields.Dict(
keys=marshmallow.fields.String(),
values=marshmallow.fields.Raw(
required=True,
allow_none=True,
),
),
)
num_ident_receptor_extranjero = marshmallow.fields.String(
required=False,
Expand Down Expand Up @@ -808,8 +821,7 @@ def to_detalle_entry(self, data: dict) -> RvDetalleEntry:
exento_comision_liquidacion_factura = data['exento_comision_liquidacion_factura']
iva_comision_liquidacion_factura = data['iva_comision_liquidacion_factura']
iva_fuera_de_plazo = data['iva_fuera_de_plazo']
tipo_documento_referencia = data['tipo_documento_referencia']
folio_documento_referencia = data['folio_documento_referencia']
documento_referencias = data.get('documento_referencias', None)
num_ident_receptor_extranjero = data['num_ident_receptor_extranjero']
nacionalidad_receptor_extranjero = data['nacionalidad_receptor_extranjero']
credito_empresa_constructora = data['credito_empresa_constructora']
Expand Down Expand Up @@ -854,8 +866,7 @@ def to_detalle_entry(self, data: dict) -> RvDetalleEntry:
exento_comision_liquidacion_factura=exento_comision_liquidacion_factura,
iva_comision_liquidacion_factura=iva_comision_liquidacion_factura,
iva_fuera_de_plazo=iva_fuera_de_plazo,
tipo_documento_referencia=tipo_documento_referencia,
folio_documento_referencia=folio_documento_referencia,
documento_referencias=documento_referencias,
num_ident_receptor_extranjero=num_ident_receptor_extranjero,
nacionalidad_receptor_extranjero=nacionalidad_receptor_extranjero,
credito_empresa_constructora=credito_empresa_constructora,
Expand Down Expand Up @@ -1629,6 +1640,16 @@ def _parse_rcv_csv_file(
tipo_docto = row_data.get('Tipo Doc')
rut = row_data.get(rut_key)

if isinstance(input_csv_row_schema, RcvVentaCsvRowSchema):
tipo_docto_referencia = row_data.pop('Tipo Docto. Referencia')
folio_docto_referencia = row_data.pop('Folio Docto. Referencia')

documento_referencias = _parse_rv_documento_referencias(
tipo_documento_referencia=tipo_docto_referencia,
folio_documento_referencia=folio_docto_referencia,
)
row_data['Documento Referencias'] = documento_referencias

# Concatenate folio, tipo_docto, and rut to create unique entry key
entry_key = f"{folio}_{tipo_docto}_{rut}"

Expand Down Expand Up @@ -1712,3 +1733,73 @@ def _parse_rcv_csv_file(
row_errors['conversion_errors'] = conversion_error

yield entry, row_ix, row_data, row_errors


def _parse_rv_documento_referencias(
tipo_documento_referencia: Union[str, int, None], folio_documento_referencia: Optional[str]
) -> Optional[Sequence[MutableMapping[str, Any]]]:
"""
Parse RvDocumentoReferencia from tipo and folio values.
Parameters
----------
tipo_documento_referencia : Optional[str]
Document type. Accepts string or integer. Empty values: None, "", "0".
folio_documento_referencia : Optional[str]
Folio number(s). Single folio ("10370") or hyphen-separated multiple
folios ("10370-10371"). Empty values: None, "", "0".
Returns
-------
Optional[Sequence[MutableMapping[str, Any]]]
None if both parameters are empty. Otherwise, list of mappings with
'tipo_documento_referencia' and 'folio_documento_referencia' keys.
Raises
------
ValueError
If only one parameter is provided or folio contains non-numeric parts.
"""
documento_referencias = []

if tipo_documento_referencia in (None, '', '0') and folio_documento_referencia in (
None,
'',
'0',
):
return None

if tipo_documento_referencia in (None, '', '0') or folio_documento_referencia in (
None,
'',
'0',
):
raise ValueError(
f"Both 'tipo_documento_referencia' ({tipo_documento_referencia}) "
f"and 'folio_documento_referencia' ({folio_documento_referencia}) must be provided."
)

if isinstance(tipo_documento_referencia, str):
tipo_documento_referencia = int(tipo_documento_referencia)

if isinstance(folio_documento_referencia, str):
folios = folio_documento_referencia.split('-')
for folio in folios:
if not folio.isdigit():
raise ValueError(
f"Invalid 'folio_documento_referencia': {folio_documento_referencia}."
)
documento_referencias.append(
{
'tipo_documento_referencia': tipo_documento_referencia,
'folio_documento_referencia': int(folio),
}
)
else:
documento_referencias.append(
{
'tipo_documento_referencia': tipo_documento_referencia,
'folio_documento_referencia': folio_documento_referencia,
}
)
return documento_referencias
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Nro;Tipo Doc;Tipo Venta;Rut cliente;Razon Social;Folio;Fecha Docto;Fecha Recepcion;Fecha Acuse Recibo;Fecha Reclamo;Monto Exento;Monto Neto;Monto IVA;Monto total;IVA Retenido Total;IVA Retenido Parcial;IVA no retenido;IVA propio;IVA Terceros;RUT Emisor Liquid. Factura;Neto Comision Liquid. Factura;Exento Comision Liquid. Factura;IVA Comision Liquid. Factura;IVA fuera de plazo;Tipo Docto. Referencia;Folio Docto. Referencia;Num. Ident. Receptor Extranjero;Nacionalidad Receptor Extranjero;Credito empresa constructora;Impto. Zona Franca (Ley 18211);Garantia Dep. Envases;Indicador Venta sin Costo;Indicador Servicio Periodico;Monto No facturable;Total Monto Periodo;Venta Pasajes Transporte Nacional;Venta Pasajes Transporte Internacional;Numero Interno;Codigo Sucursal;NCE o NDE sobre Fact. de Compra;Codigo Otro Imp.;Valor Otro Imp.;Tasa Otro Imp.
1;33;Del Giro;12345678-5;Fake Company S.A. ;506;04/06/2019;18/06/2019 17:01:06;;;0;1750181;332534;2082715;0;0;0;0;0;-;0;0;0;0;;;;;0;;0;2;0;0;0;;;;0;;;;;
2;33;Del Giro;77697060-3;DIRECT LTDA;14239;09/12/2025;09/12/2025 08:50:45;10/12/2025 13:14:17;;0;553180;105104;658284;0;0;0;0;0;-;0;0;0;0;52;10370-10371;;;0;;0;2;0;0;0;;;;0;;;;;
3;33;Del Giro;54213736-3;THE COMPANY SPA;3210;01/09/2025;01/09/2025 10:58:51;08/09/2025 14:15:23;;0;9999;3899347;30471437;0;0;0;0;0;-;0;0;0;0;33;200-300-400;;;0;;0;2;0;0;0;;;;12354;;24;6049210;31.5;
;33;Del Giro;54213736-3;THE COMPANY SPA;3210;01/09/2025;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;271;701395;18;;;;;;
3 changes: 1 addition & 2 deletions src/tests/test_rcv_data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,7 @@ def setUp(self) -> None:
exento_comision_liquidacion_factura=0,
iva_comision_liquidacion_factura=0,
iva_fuera_de_plazo=0,
tipo_documento_referencia=None,
folio_documento_referencia=None,
documento_referencias=None,
num_ident_receptor_extranjero=None,
nacionalidad_receptor_extranjero=None,
credito_empresa_constructora=0,
Expand Down
Loading
Loading