libredte-lib-sdk 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- libredte_lib_sdk-0.4.0/.claude/scheduled_tasks.lock +1 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/PKG-INFO +3 -3
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/README.rst +2 -2
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/book/loader.py +2 -2
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/book/models.py +9 -9
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/examples.py +1 -1
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/models.py +13 -13
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/models.py +3 -3
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/ownership_transfer/models.py +3 -3
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/trading_parties/models.py +7 -7
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/pyproject.toml +1 -1
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_certificate_loader.py +5 -5
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_examples.py +8 -8
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/test_models.py +2 -2
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/test_services.py +15 -15
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/.github/workflows/ci.yml +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/.github/workflows/docs.yml +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/.gitignore +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/.readthedocs.yaml +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/CLAUDE.md +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/LICENSE +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/Makefile +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/docs/Makefile +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/docs/conf.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/docs/index.rst +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/book/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/book/builder.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/book/validator.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/common.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/builder.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/dispatcher.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/loader.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/renderer.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/validator.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/enums.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/exchange/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/exchange/document_response.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/exchange/models.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/caf_faker.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/caf_loader.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/caf_validator.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/models.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/sii_dte.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/sii_rcv.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/sii_rtc.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/ownership_transfer/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/ownership_transfer/aec.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/trading_parties/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/trading_parties/mandatario_manager.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/client.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/exceptions.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/human_resources/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/human_resources/integration/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/human_resources/integration/previred_provider.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/human_resources/payroll/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/human_resources/payroll/calculator.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/human_resources/payroll/renderer.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/py.typed +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/sdk.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/certificate/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/certificate/loader.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/repository/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/repository/catalog.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/conftest.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/__init__.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/conftest.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_book.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_caf.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_document_loader.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_document_rendering.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_document_validation.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_exchange.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_human_resources.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_operation_not_found.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_ownership_transfer.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_repository.py +0 -0
- {libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/test_client.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"sessionId":"64edfb1a-a3db-44cc-af25-6c7405269fdf","pid":73057,"procStart":"Mon Sep 7 03:13:55 2026","acquiredAt":1789224889985}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: libredte-lib-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: SDK Python para la API de LibreDTE Lib (facturacion electronica de Chile).
|
|
5
5
|
Project-URL: Homepage, https://www.libredte.cl
|
|
6
6
|
Project-URL: Source, https://github.com/libredte/libredte-lib-sdk-python
|
|
@@ -220,7 +220,7 @@ necesita para poblar sus propios datos, no operaciones de facturación.
|
|
|
220
220
|
ejemplos = b.document.examples.list() # [ExampleSummary(id=..., category=..., case=...), ...]
|
|
221
221
|
ejemplo = b.document.examples.get(ejemplos[0].id)
|
|
222
222
|
documento = b.document.builder.build_signed(
|
|
223
|
-
ejemplo.
|
|
223
|
+
ejemplo.example, caf_xml=caf.xml_base64, certificate=certificate,
|
|
224
224
|
)
|
|
225
225
|
|
|
226
226
|
# Catálogos/repositorios reales (comunas, tipos de documento, etc.)
|
|
@@ -238,7 +238,7 @@ necesita para poblar sus propios datos, no operaciones de facturación.
|
|
|
238
238
|
# ya extraídos en una sola llamada — mismo `Certificate` que usan
|
|
239
239
|
# build_signed()/dispatcher.create(), ya con todos los datos.
|
|
240
240
|
certificate = s.certificate.loader.load(datos_del_archivo_pfx, 'contraseña')
|
|
241
|
-
print(certificate.
|
|
241
|
+
print(certificate.id, certificate.name, certificate.email)
|
|
242
242
|
|
|
243
243
|
Errores
|
|
244
244
|
-------
|
|
@@ -176,7 +176,7 @@ necesita para poblar sus propios datos, no operaciones de facturación.
|
|
|
176
176
|
ejemplos = b.document.examples.list() # [ExampleSummary(id=..., category=..., case=...), ...]
|
|
177
177
|
ejemplo = b.document.examples.get(ejemplos[0].id)
|
|
178
178
|
documento = b.document.builder.build_signed(
|
|
179
|
-
ejemplo.
|
|
179
|
+
ejemplo.example, caf_xml=caf.xml_base64, certificate=certificate,
|
|
180
180
|
)
|
|
181
181
|
|
|
182
182
|
# Catálogos/repositorios reales (comunas, tipos de documento, etc.)
|
|
@@ -194,7 +194,7 @@ necesita para poblar sus propios datos, no operaciones de facturación.
|
|
|
194
194
|
# ya extraídos en una sola llamada — mismo `Certificate` que usan
|
|
195
195
|
# build_signed()/dispatcher.create(), ya con todos los datos.
|
|
196
196
|
certificate = s.certificate.loader.load(datos_del_archivo_pfx, 'contraseña')
|
|
197
|
-
print(certificate.
|
|
197
|
+
print(certificate.id, certificate.name, certificate.email)
|
|
198
198
|
|
|
199
199
|
Errores
|
|
200
200
|
-------
|
|
@@ -31,8 +31,8 @@ class BookLoaderService:
|
|
|
31
31
|
Normaliza `caratula`/`detalle` de `bag` en un `BookBag`.
|
|
32
32
|
|
|
33
33
|
`bag` trae `tipo`/`caratula`/`detalle`/`emisor`, tal cual el
|
|
34
|
-
formato SII. `BookBag.
|
|
35
|
-
el libro); `BookBag.
|
|
34
|
+
formato SII. `BookBag.book` siempre viene `None` (no construye
|
|
35
|
+
el libro); `BookBag.book_auth` viene poblado solo si
|
|
36
36
|
`bag['emisor']` incluye `autorizacion_dte`.
|
|
37
37
|
"""
|
|
38
38
|
data = self._client.call(
|
|
@@ -43,16 +43,16 @@ class BookBag:
|
|
|
43
43
|
Esta operación solo normaliza `caratula`/`detalle` a partir de los
|
|
44
44
|
datos de entrada — no construye el libro ni genera su documento
|
|
45
45
|
firmado (eso lo hace `BookBuilderService.build`), por lo que
|
|
46
|
-
`
|
|
47
|
-
importar los datos de entrada recibidos. `
|
|
48
|
-
del emisor del libro) solo viene poblada si esa
|
|
49
|
-
incluyó junto con los datos del emisor en la
|
|
50
|
-
`None`.
|
|
46
|
+
`book` (el libro ya construido) siempre viene `None` acá, sin
|
|
47
|
+
importar los datos de entrada recibidos. `book_auth` (la
|
|
48
|
+
autorización del emisor del libro) solo viene poblada si esa
|
|
49
|
+
autorización se incluyó junto con los datos del emisor en la
|
|
50
|
+
solicitud; si no, viene `None`.
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
book: dict[str, Any] | None
|
|
54
54
|
book_type: dict[str, Any]
|
|
55
|
-
|
|
55
|
+
book_auth: dict[str, Any] | None
|
|
56
56
|
caratula: dict[str, Any]
|
|
57
57
|
detalle: list[dict[str, Any]]
|
|
58
58
|
raw: dict[str, Any]
|
|
@@ -61,9 +61,9 @@ class BookBag:
|
|
|
61
61
|
def from_api(cls, data: dict[str, Any]) -> BookBag:
|
|
62
62
|
"""Construye un `BookBag` desde el `data` que devuelve la API."""
|
|
63
63
|
return cls(
|
|
64
|
-
|
|
64
|
+
book=data.get('book'),
|
|
65
65
|
book_type=data['book_type'],
|
|
66
|
-
|
|
66
|
+
book_auth=data.get('book_auth'),
|
|
67
67
|
caratula=data.get('caratula') or {},
|
|
68
68
|
detalle=data.get('detalle') or [],
|
|
69
69
|
raw=data,
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/examples.py
RENAMED
|
@@ -17,7 +17,7 @@ class DocumentExamplesService:
|
|
|
17
17
|
de `libredte-lib-core` (`tests/fixtures/yaml/documentos_ok/`) — uno
|
|
18
18
|
por variante de negocio real (descuentos, impuesto adicional, pago a
|
|
19
19
|
crédito, exportación, etc.), no datos inventados por el SDK.
|
|
20
|
-
`Example.
|
|
20
|
+
`Example.example` de `get()` se le pasa tal cual a
|
|
21
21
|
`DocumentBuilderService.build_draft()`/`.build_signed()`, típicamente
|
|
22
22
|
reemplazando `Encabezado.IdDoc.Folio` y `Encabezado.Receptor` por los
|
|
23
23
|
propios de quien usa el SDK antes de construir el documento.
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/models.py
RENAMED
|
@@ -56,29 +56,29 @@ class DocumentBag:
|
|
|
56
56
|
Bolsa normalizada devuelta por `document.loader::loadXml`.
|
|
57
57
|
|
|
58
58
|
No trae el XML del documento ni `id` — solo la bolsa ya
|
|
59
|
-
normalizada: `
|
|
59
|
+
normalizada: `document` (`Encabezado`/`Detalle`), `document_type`
|
|
60
60
|
(metadatos del tipo de documento: `codigo`, `nombre`, `categoria`,
|
|
61
|
-
`es_boleta`, etc., sin tipar) y `
|
|
61
|
+
`es_boleta`, etc., sin tipar) y `document_stamp` (el TED, como XML
|
|
62
62
|
plano, no en base64 ni parseado). Sirve para reconstruir los datos
|
|
63
63
|
de un DTE ya emitido a partir de su XML.
|
|
64
64
|
"""
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
document: dict[str, Any]
|
|
67
67
|
document_type: dict[str, Any]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
document_stamp: str | None
|
|
69
|
+
document_extra: dict[str, Any] | None
|
|
70
|
+
document_auth: dict[str, Any] | None
|
|
71
71
|
raw: dict[str, Any]
|
|
72
72
|
|
|
73
73
|
@classmethod
|
|
74
74
|
def from_api(cls, data: dict[str, Any]) -> DocumentBag:
|
|
75
75
|
"""Construye un `DocumentBag` desde el `data` de la API."""
|
|
76
76
|
return cls(
|
|
77
|
-
|
|
77
|
+
document=data['document'],
|
|
78
78
|
document_type=data['document_type'],
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
document_stamp=data.get('document_stamp'),
|
|
80
|
+
document_extra=data.get('document_extra'),
|
|
81
|
+
document_auth=data.get('document_auth'),
|
|
82
82
|
raw=data,
|
|
83
83
|
)
|
|
84
84
|
|
|
@@ -163,7 +163,7 @@ class Example:
|
|
|
163
163
|
"""
|
|
164
164
|
Un ejemplo de documento, tal como lo devuelve `examples::get()`.
|
|
165
165
|
|
|
166
|
-
`
|
|
166
|
+
`example` se pasa directamente al parámetro `input_data` de
|
|
167
167
|
`DocumentBuilderService.build_draft()`/`.build_signed()` — mismo
|
|
168
168
|
`Encabezado`/`Detalle` que usa el resto del SDK, sin transformación.
|
|
169
169
|
`expected` son los valores esperados del caso (totales, etc.) que usa
|
|
@@ -172,7 +172,7 @@ class Example:
|
|
|
172
172
|
"""
|
|
173
173
|
|
|
174
174
|
id: str
|
|
175
|
-
|
|
175
|
+
example: dict[str, Any]
|
|
176
176
|
expected: dict[str, Any]
|
|
177
177
|
|
|
178
178
|
@classmethod
|
|
@@ -180,7 +180,7 @@ class Example:
|
|
|
180
180
|
"""Construye un `Example` desde el `data` que devuelve la API."""
|
|
181
181
|
return cls(
|
|
182
182
|
id=data['id'],
|
|
183
|
-
|
|
183
|
+
example=data['example'],
|
|
184
184
|
expected=data.get('expected') or {},
|
|
185
185
|
)
|
|
186
186
|
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/models.py
RENAMED
|
@@ -193,11 +193,11 @@ class GetDocumentSiiReceptionDateResponse:
|
|
|
193
193
|
Fecha de recepción de un DTE en el SII (`getDocumentSiiReceptionDate`).
|
|
194
194
|
|
|
195
195
|
Si el documento consultado no tiene fecha de recepción registrada,
|
|
196
|
-
la API levanta `LibreDteApiError` — `
|
|
196
|
+
la API levanta `LibreDteApiError` — `fecha_recepcion_sii` nunca es
|
|
197
197
|
`None`.
|
|
198
198
|
"""
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
fecha_recepcion_sii: datetime
|
|
201
201
|
raw: dict[str, Any]
|
|
202
202
|
|
|
203
203
|
@classmethod
|
|
@@ -207,7 +207,7 @@ class GetDocumentSiiReceptionDateResponse:
|
|
|
207
207
|
) -> GetDocumentSiiReceptionDateResponse:
|
|
208
208
|
"""Construye desde el `data` que devuelve la API."""
|
|
209
209
|
return cls(
|
|
210
|
-
|
|
210
|
+
fecha_recepcion_sii=datetime.fromisoformat(
|
|
211
211
|
data['fecha_recepcion_sii'],
|
|
212
212
|
),
|
|
213
213
|
raw=data,
|
|
@@ -16,16 +16,16 @@ class Aec(XmlPayloadMixin):
|
|
|
16
16
|
"""
|
|
17
17
|
AEC (Archivo Electrónico de Cesión) construido (`aec::build`).
|
|
18
18
|
|
|
19
|
-
`
|
|
19
|
+
`aec` es la estructura ya parseada (bajo la clave `AEC` en la
|
|
20
20
|
respuesta cruda de la API), `xml_base64` el XML completo — permite
|
|
21
21
|
encadenar a `AecService.validate_schema`/`.validate_signature` o a
|
|
22
22
|
`SiiRtcService.send_aec`.
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
aec: dict[str, Any]
|
|
26
26
|
xml_base64: str
|
|
27
27
|
|
|
28
28
|
@classmethod
|
|
29
29
|
def from_api(cls, data: dict[str, Any]) -> Aec:
|
|
30
30
|
"""Construye un `Aec` desde el `data` que devuelve la API."""
|
|
31
|
-
return cls(
|
|
31
|
+
return cls(aec=data.get('AEC') or {}, xml_base64=data['xml'])
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/trading_parties/models.py
RENAMED
|
@@ -30,8 +30,8 @@ class Certificate:
|
|
|
30
30
|
|
|
31
31
|
certificate: str
|
|
32
32
|
private_key: str
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
id: str | None = None
|
|
34
|
+
name: str | None = None
|
|
35
35
|
email: str | None = None
|
|
36
36
|
valid_from: datetime | None = None
|
|
37
37
|
valid_until: datetime | None = None
|
|
@@ -63,8 +63,8 @@ class Certificate:
|
|
|
63
63
|
return cls(
|
|
64
64
|
certificate=data['cert'],
|
|
65
65
|
private_key=data['pkey'],
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
id=data.get('id'),
|
|
67
|
+
name=data.get('name'),
|
|
68
68
|
email=data.get('email'),
|
|
69
69
|
valid_from=(
|
|
70
70
|
datetime.fromisoformat(data['from'])
|
|
@@ -89,13 +89,13 @@ class Certificate:
|
|
|
89
89
|
class Mandatario:
|
|
90
90
|
"""Mandatario (representante) dueño de un certificado digital."""
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
run: str
|
|
93
93
|
nombre: str
|
|
94
94
|
email: str | None = None
|
|
95
95
|
|
|
96
96
|
def to_payload(self) -> dict[str, Any]:
|
|
97
97
|
"""Payload esperado por la API para un mandatario."""
|
|
98
|
-
payload: dict[str, Any] = {'run': self.
|
|
98
|
+
payload: dict[str, Any] = {'run': self.run, 'nombre': self.nombre}
|
|
99
99
|
if self.email is not None:
|
|
100
100
|
payload['email'] = self.email
|
|
101
101
|
return payload
|
|
@@ -104,7 +104,7 @@ class Mandatario:
|
|
|
104
104
|
def from_api(cls, data: dict[str, Any]) -> Mandatario:
|
|
105
105
|
"""Construye un `Mandatario` desde el `data` que devuelve la API."""
|
|
106
106
|
return cls(
|
|
107
|
-
|
|
107
|
+
run=data['run'],
|
|
108
108
|
nombre=data['nombre'],
|
|
109
109
|
email=data.get('email'),
|
|
110
110
|
)
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_certificate_loader.py
RENAMED
|
@@ -24,7 +24,7 @@ from libredte_lib_sdk.billing.trading_parties import Mandatario
|
|
|
24
24
|
pytestmark = pytest.mark.live
|
|
25
25
|
|
|
26
26
|
_MANDATARIO = Mandatario(
|
|
27
|
-
|
|
27
|
+
run='76192083-9',
|
|
28
28
|
nombre='SASCO SpA',
|
|
29
29
|
email='demo@sasco.example',
|
|
30
30
|
)
|
|
@@ -56,8 +56,8 @@ def test_load_extracts_the_mandatario_and_a_usable_certificate(
|
|
|
56
56
|
):
|
|
57
57
|
loaded = real_sdk.system.certificate.loader.load(fake_pkcs12, _PASSWORD)
|
|
58
58
|
|
|
59
|
-
assert loaded.
|
|
60
|
-
assert loaded.
|
|
59
|
+
assert loaded.id == '76192083-9'
|
|
60
|
+
assert loaded.name == 'SASCO SpA'
|
|
61
61
|
assert loaded.email == 'demo@sasco.example'
|
|
62
62
|
assert loaded.is_active is True
|
|
63
63
|
assert loaded.certificate.startswith('-----BEGIN CERTIFICATE-----')
|
|
@@ -69,6 +69,6 @@ def test_create_from_certificate_matches_load(fake_pkcs12, real_sdk):
|
|
|
69
69
|
mandatario_manager = real_sdk.billing.trading_parties.mandatario_manager
|
|
70
70
|
mandatario = mandatario_manager.create_from_certificate(loaded)
|
|
71
71
|
|
|
72
|
-
assert mandatario.
|
|
73
|
-
assert mandatario.nombre == loaded.
|
|
72
|
+
assert mandatario.run == loaded.id
|
|
73
|
+
assert mandatario.nombre == loaded.name
|
|
74
74
|
assert mandatario.email == loaded.email
|
|
@@ -6,7 +6,7 @@ Tests en vivo para `DocumentExamplesService`.
|
|
|
6
6
|
|
|
7
7
|
Los ejemplos son los mismos casos de prueba, ya validados, de
|
|
8
8
|
`libredte-lib-core` (`tests/fixtures/yaml/documentos_ok/`) — se prueba
|
|
9
|
-
que `get()` entrega un `
|
|
9
|
+
que `get()` entrega un `example` realmente utilizable por
|
|
10
10
|
`DocumentBuilderService`, no solo que la llamada HTTP responde.
|
|
11
11
|
"""
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@ pytestmark = pytest.mark.live
|
|
|
20
20
|
|
|
21
21
|
_EMISOR = {'rut': '76192083-9', 'razon_social': 'SASCO SpA'}
|
|
22
22
|
_MANDATARIO = Mandatario(
|
|
23
|
-
|
|
23
|
+
run='76192083-9',
|
|
24
24
|
nombre='SASCO SpA',
|
|
25
25
|
email='demo@sasco.example',
|
|
26
26
|
)
|
|
@@ -34,19 +34,19 @@ def test_list_returns_many_examples_across_document_types(real_sdk):
|
|
|
34
34
|
assert len(categories) > 1
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def
|
|
37
|
+
def test_get_returns_example_and_expected_values(real_sdk):
|
|
38
38
|
first = real_sdk.billing.document.examples.list()[0]
|
|
39
39
|
|
|
40
40
|
example = real_sdk.billing.document.examples.get(first.id)
|
|
41
41
|
|
|
42
42
|
assert example.id == first.id
|
|
43
|
-
assert 'Encabezado' in example.
|
|
44
|
-
assert 'Detalle' in example.
|
|
43
|
+
assert 'Encabezado' in example.example
|
|
44
|
+
assert 'Detalle' in example.example
|
|
45
45
|
assert example.expected
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
def test_an_example_builds_into_a_real_signed_document(real_sdk):
|
|
49
|
-
"""El `
|
|
49
|
+
"""El `example` de un ejemplo debe servir tal cual a `build_signed`."""
|
|
50
50
|
b = real_sdk.billing
|
|
51
51
|
example = next(
|
|
52
52
|
e
|
|
@@ -57,14 +57,14 @@ def test_an_example_builds_into_a_real_signed_document(real_sdk):
|
|
|
57
57
|
|
|
58
58
|
caf = b.identifier.caf_faker.create(
|
|
59
59
|
_EMISOR,
|
|
60
|
-
codigo_documento=data.
|
|
60
|
+
codigo_documento=data.example['Encabezado']['IdDoc']['TipoDTE'],
|
|
61
61
|
)
|
|
62
62
|
certificate = b.trading_parties.mandatario_manager.create_fake_certificate(
|
|
63
63
|
_MANDATARIO,
|
|
64
64
|
)
|
|
65
65
|
|
|
66
66
|
documento = b.document.builder.build_signed(
|
|
67
|
-
data.
|
|
67
|
+
data.example,
|
|
68
68
|
caf_xml=caf.xml_base64,
|
|
69
69
|
certificate=certificate,
|
|
70
70
|
)
|
|
@@ -42,7 +42,7 @@ def test_certificate_from_api_maps_cert_and_pkey_fields():
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
def test_mandatario_to_payload_omits_email_when_absent():
|
|
45
|
-
mandatario = Mandatario(
|
|
45
|
+
mandatario = Mandatario(run='76192083-9', nombre='SASCO SpA')
|
|
46
46
|
|
|
47
47
|
assert mandatario.to_payload() == {
|
|
48
48
|
'run': '76192083-9',
|
|
@@ -52,7 +52,7 @@ def test_mandatario_to_payload_omits_email_when_absent():
|
|
|
52
52
|
|
|
53
53
|
def test_mandatario_to_payload_includes_email_when_present():
|
|
54
54
|
mandatario = Mandatario(
|
|
55
|
-
|
|
55
|
+
run='76192083-9',
|
|
56
56
|
nombre='SASCO SpA',
|
|
57
57
|
email='sasco@example.com',
|
|
58
58
|
)
|
|
@@ -241,15 +241,15 @@ def test_mandatario_manager_create_fake_certificate(sdk):
|
|
|
241
241
|
|
|
242
242
|
service = sdk.billing.trading_parties.mandatario_manager
|
|
243
243
|
certificate = service.create_fake_certificate(
|
|
244
|
-
Mandatario(
|
|
244
|
+
Mandatario(run='76192083-9', nombre='SASCO SpA'),
|
|
245
245
|
)
|
|
246
246
|
|
|
247
247
|
sent = json.loads(route.calls.last.request.content)['parameters']
|
|
248
248
|
assert sent['mandatario']['run'] == '76192083-9'
|
|
249
249
|
assert certificate.certificate == 'CERT-PEM'
|
|
250
250
|
assert certificate.private_key == 'PKEY-PEM'
|
|
251
|
-
assert certificate.
|
|
252
|
-
assert certificate.
|
|
251
|
+
assert certificate.id == '76192083-9'
|
|
252
|
+
assert certificate.name == 'SASCO SpA'
|
|
253
253
|
assert certificate.email == 'sasco@example.com'
|
|
254
254
|
assert certificate.is_active is True
|
|
255
255
|
assert certificate.issuer == 'Derafu Test Certificate Authority'
|
|
@@ -555,7 +555,7 @@ def test_document_examples_get_sends_id_and_splits_expected(sdk):
|
|
|
555
555
|
|
|
556
556
|
sent = json.loads(route.calls.last.request.content)['parameters']
|
|
557
557
|
assert sent['id'] == '033_factura_afecta/033_001_simple'
|
|
558
|
-
assert example.
|
|
558
|
+
assert example.example == _INPUT_DATA
|
|
559
559
|
assert example.expected['Encabezado']['Totales']['MntTotal'] == 1190
|
|
560
560
|
|
|
561
561
|
|
|
@@ -586,7 +586,7 @@ def test_mandatario_manager_create_from_certificate(sdk):
|
|
|
586
586
|
'certificate': 'cert-pem',
|
|
587
587
|
'privateKey': 'key-pem',
|
|
588
588
|
}
|
|
589
|
-
assert mandatario.
|
|
589
|
+
assert mandatario.run == '76192083-9'
|
|
590
590
|
assert mandatario.nombre == 'SASCO SpA'
|
|
591
591
|
assert mandatario.email == 'demo@sasco.example'
|
|
592
592
|
|
|
@@ -742,8 +742,8 @@ def test_certificate_loader_load_sends_base64_and_decodes_metadata(sdk):
|
|
|
742
742
|
assert (
|
|
743
743
|
base64.b64decode(sent['certificate']['data']) == b'contenido-del-p12'
|
|
744
744
|
)
|
|
745
|
-
assert loaded.
|
|
746
|
-
assert loaded.
|
|
745
|
+
assert loaded.id == '76192083-9'
|
|
746
|
+
assert loaded.name == 'SASCO SpA'
|
|
747
747
|
assert loaded.email == 'demo@sasco.example'
|
|
748
748
|
assert loaded.is_active is True
|
|
749
749
|
assert loaded.certificate == 'CERT-PEM'
|
|
@@ -1038,7 +1038,7 @@ def test_sii_rcv_get_document_sii_reception_date_parses_the_datetime(sdk):
|
|
|
1038
1038
|
certificate=Certificate(certificate='cert-pem', private_key='key-pem'),
|
|
1039
1039
|
)
|
|
1040
1040
|
|
|
1041
|
-
assert result.
|
|
1041
|
+
assert result.fecha_recepcion_sii.isoformat() == '2025-01-02T10:30:00'
|
|
1042
1042
|
assert result.raw == {'fecha_recepcion_sii': '2025-01-02 10:30:00'}
|
|
1043
1043
|
|
|
1044
1044
|
|
|
@@ -1154,7 +1154,7 @@ def test_aec_build_sends_cedente_cesionario_cesion(sdk):
|
|
|
1154
1154
|
}
|
|
1155
1155
|
assert sent['cesionario']['RazonSocial'] == 'Factoring S.A.'
|
|
1156
1156
|
assert sent['cesion']['MontoCesion'] == 119000
|
|
1157
|
-
assert result.
|
|
1157
|
+
assert result.aec['DocumentoAEC']['Caratula']['RutCedente'] == (
|
|
1158
1158
|
'76192083-9'
|
|
1159
1159
|
)
|
|
1160
1160
|
assert result.xml_base64 == 'PEFFQz48L0FFQz4='
|
|
@@ -1218,11 +1218,11 @@ def test_document_loader_load_xml_decodes_the_full_bag(sdk):
|
|
|
1218
1218
|
|
|
1219
1219
|
sent = json.loads(route.calls.last.request.content)['parameters']
|
|
1220
1220
|
assert sent['xml'] == 'RFRFeG1s'
|
|
1221
|
-
assert result.
|
|
1221
|
+
assert result.document == {'Encabezado': {}}
|
|
1222
1222
|
assert result.document_type == {'codigo': 33, 'nombre': 'Factura'}
|
|
1223
|
-
assert result.
|
|
1224
|
-
assert result.
|
|
1225
|
-
assert result.
|
|
1223
|
+
assert result.document_stamp == '<TED/>'
|
|
1224
|
+
assert result.document_extra is None
|
|
1225
|
+
assert result.document_auth is None
|
|
1226
1226
|
|
|
1227
1227
|
|
|
1228
1228
|
_BOOK_BAG = {
|
|
@@ -1327,8 +1327,8 @@ def test_book_loader_load_decodes_book_type_caratula_and_detalle(sdk):
|
|
|
1327
1327
|
|
|
1328
1328
|
# `book`/`book_auth` siempre vienen `None` desde `load()` (no
|
|
1329
1329
|
# construye el libro) — ver docstring de `BookBag`.
|
|
1330
|
-
assert result.
|
|
1331
|
-
assert result.
|
|
1330
|
+
assert result.book is None
|
|
1331
|
+
assert result.book_auth is None
|
|
1332
1332
|
assert result.book_type == {
|
|
1333
1333
|
'codigo': 'libro_ventas',
|
|
1334
1334
|
'nombre': 'Libro de ventas',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/book/validator.py
RENAMED
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/__init__.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/builder.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/dispatcher.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/loader.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/renderer.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/document/validator.py
RENAMED
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/exchange/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/exchange/models.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/__init__.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/caf_faker.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/caf_loader.py
RENAMED
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/identifier/models.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/__init__.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/sii_dte.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/sii_rcv.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/integration/sii_rtc.py
RENAMED
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/billing/ownership_transfer/aec.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/human_resources/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/certificate/__init__.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/certificate/loader.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/repository/__init__.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/libredte_lib_sdk/system/repository/catalog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_document_rendering.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_document_validation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_operation_not_found.py
RENAMED
|
File without changes
|
{libredte_lib_sdk-0.3.0 → libredte_lib_sdk-0.4.0}/tests/integration/test_ownership_transfer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|