libredte_lib_sdk.billing.document package

Submodules

Module contents

Componente billing.document: DTE — construcción, sobre y render.

class libredte_lib_sdk.billing.document.DocumentBag(document: dict[str, Any] | None, document_parsed: dict[str, Any] | None, document_normalized: dict[str, Any] | None, document_type: dict[str, Any] | None, document_stamp_base64: str | None, document_extra: dict[str, Any] | None, document_auth: dict[str, Any] | None, document_id: str | None, document_xml_base64: str | None, options: dict[str, Any], certificate: Certificate | None, emisor: dict[str, Any] | None, receptor: dict[str, Any] | None, caf: Caf | None, timbre: dict[str, Any] | None, raw: dict[str, Any])

Bases: object

Bolsa de un documento tributario.

Devuelta por document.builder::build/document.loader::loadXml/ document.parser::parse — todas en esta misma forma, con los campos que correspondan a cuánto se hizo con el documento. document (Encabezado/Detalle, con el merge de libredte_data.extra.dte si se pasó al renderizar) es la vista «de datos» limpia del documento — SIN los campos opcionales no usados (se omiten, no quedan en False). document_normalized es la data cruda tal como la usa el builder internamente para generar el XML (con esos campos opcionales en False en vez de omitidos): es la que hay que guardar para poder reconstruir el documento después con options={“normalizer”: {“normalize”: False}} sin volver a normalizar — usar document para eso corrompe la reconstrucción.

document_id/xml_base64 dan el documento construido completo — puede ser un borrador, un documento timbrado, o timbrado y firmado, no una subclase distinta: es el mismo recurso en distintos estados según qué datos se le hayan pasado a DocumentBuilderService. Un borrador sin folio asignado tiene folio 0 en document_id (ver AbstractDocument::getId() en la biblioteca), nunca lanza error.

document_stamp_base64 es el TED — None si el documento aún no está timbrado (ver is_timbrado). document_extra son los campos que el tipo de documento no admite en el XML (ej. TermPagoGlosa en una boleta) pero sí se pasaron como libredte_data al construir. document_auth viene poblado solo si el emisor incluyó su autorización SII.

options son las opciones efectivas de la bolsa (builder/ normalizer/parser/renderer/sanitizer/validator), tal como las devuelve la API — vacías ([]) para el worker que no recibió ninguna al construir/cargar el documento.

certificate/caf son None salvo que el documento se haya construido con ellos (build_signed, o un loadXml de un XML ya firmado/timbrado) — un borrador (build_draft) no los trae. emisor/receptor sí están siempre que haya un documento construido (Encabezado.Emisor/Encabezado.Receptor ya resueltos como entidad, con todos sus campos — no solo los que trae document). timbre es el TED ya parseado como dict (document_stamp_base64 es el mismo dato, pero como XML) — None si el documento aún no está timbrado.

Una bolsa que solo se parseó (DocumentParserService, o cada bolsa de un DocumentBatch) trae document_parsed (los datos en el formato DTE del SII, tal como los entregó el parser) y deja en None lo que requiere construir el documento: document, document_type, el XML, etc.

No usa XmlPayloadMixin: acá xml_base64 es una @property (el documento puede no estar construido), no un campo simple.

caf: Caf | None
certificate: Certificate | None
document: dict[str, Any] | None
document_auth: dict[str, Any] | None
document_extra: dict[str, Any] | None
document_id: str | None
document_normalized: dict[str, Any] | None
document_parsed: dict[str, Any] | None
document_stamp_base64: str | None
document_type: dict[str, Any] | None
document_xml_base64: str | None
emisor: dict[str, Any] | None
classmethod from_api(data: dict[str, Any]) → DocumentBag

Construye un DocumentBag desde el data de la API.

property is_timbrado: bool

Si el documento ya tiene Timbre Electrónico (TED).

options: dict[str, Any]
raw: dict[str, Any]
receptor: dict[str, Any] | None
require_document() → dict[str, Any]

Entrega document, o falla si la bolsa no tiene el documento.

Para quien sabe que la bolsa viene de construir o cargar un documento (builder, loader, dispatcher): document es opcional solo porque una bolsa que se parseó (parser, batch_processor) no lo trae, y esto evita revisar el None en cada acceso.

Muestra:

ValueError – Si document es None.

timbre: dict[str, Any] | None
property xml: str

XML del documento construido, como texto (ISO-8859-1).

property xml_base64: str

XML completo del documento construido, en base64.

property xml_bytes: bytes

XML del documento construido, decodificado desde base64.

class libredte_lib_sdk.billing.document.DocumentBatch(document_bags: tuple[DocumentBag, ...], raw: dict[str, Any])

Bases: object

Lote de documentos de una emisión masiva, ya parseado.

Devuelto por batch_processor::parse. document_bags trae una bolsa (DocumentBag) por cada documento del archivo, en el orden del archivo, con los datos parseados en document_parsed — todavía no se construyó ningún documento. No incluye el contenido enviado ni el certificado.

document_bags: tuple[DocumentBag, ...]
classmethod from_api(data: dict[str, Any]) → DocumentBatch

Construye un DocumentBatch desde el data de la API.

raw: dict[str, Any]
class libredte_lib_sdk.billing.document.DocumentBatchProcessorService(client: ApiClient)

Bases: object

Parsea un lote de documentos de una emisión masiva.

Solo cubre parse: entrega los documentos parseados, sin construirlos (sin folios, CAF ni certificado).

parse(input_data: str | bytes, *, emisor: dict[str, Any] | None = None, strategy: str | None = None, complete: bool | None = None) → DocumentBatch

Parsea el archivo de un lote y entrega las bolsas de sus documentos.

input_data es el contenido del archivo (CSV, XLSX, etc.). Se debe pasar como bytes (leído en modo rb): se envía sin alterar. Un str ya es texto decodificado y se envía en UTF-8.

emisor es un dict con rut/razon_social (y demás datos del emisor): con complete activo (por defecto) se usan para completar los datos del emisor de cada documento.

strategy es la estrategia del archivo (“spreadsheet.csv” por defecto; “spreadsheet.xlsx” solo existe en Lib Pro). complete indica si se completan los datos del documento con los del emisor (por defecto la API lo hace).

Un error en el archivo lanza LibreDteApiError indicando la fila (ej. Fila 3: ...).

class libredte_lib_sdk.billing.document.DocumentBuilderService(client: ApiClient)

Bases: object

Construye documentos tributarios (billing.document.builder).

El mismo worker de la API sirve tanto para un borrador como para el documento timbrado y firmado, según qué datos se le pasen — acá se separa en dos métodos explícitos para que la intención de cada llamada quede clara en el código que la usa.

build_draft(input_data: str | bytes | dict[str, Any], *, options: dict[str, Any] | None = None) → DocumentBag

Emite el borrador de un DTE a partir de datos de entrada.

input_data es el Encabezado/Detalle (y demás nodos) del formato DTE del SII como dict — o datos en otro formato (XML/YAML, un formulario, etc.), como bytes o str, junto con options={“parser”: {“strategy”: “<estrategia>”}} para indicar cómo parsearlos. El contenido de un archivo se debe pasar como bytes (leído en modo rb): se envía sin alterar su codificación. Un str ya es texto decodificado y se envía en UTF-8. Sin options, la API asume que input_data ya viene en el formato DTE del SII (estrategia default.json). Encabezado.IdDoc.Folio es opcional acá — un borrador sin folio no falla (queda con folio 0 en DocumentBag.document_id, sin nodo Folio en el XML). Sin CAF ni certificado, el resultado no queda timbrado (DocumentBag.is_timbrado es False).

build_signed(input_data: str | bytes | dict[str, Any], *, options: dict[str, Any] | None = None, caf_xml: str, certificate: Certificate) → DocumentBag

Genera el DTE real, timbrado y firmado.

input_data/options funcionan igual que en build_draft() — acá sí se necesita un Encabezado.IdDoc.Folio real, cubierto por caf_xml (el SDK no asigna folios: eso lo decide quien llama, típicamente porque lleva el correlativo). Requiere un CAF real (XML tal como lo entrega el SII) y el certificado digital del emisor. Para pruebas, ambos se pueden generar con IdentifierComponent.caf_faker y TradingPartiesComponent.mandatario_manager.

class libredte_lib_sdk.billing.document.DocumentComponent(client: ApiClient)

Bases: object

Agrupa los servicios de billing.document.

class libredte_lib_sdk.billing.document.DocumentDispatcherService(client: ApiClient)

Bases: object

Arma y valida el sobre EnvioDTE (billing.document.dispatcher).

create(bag: DocumentBag) → DocumentEnvelope

Envuelve y firma un documento ya timbrado en un sobre EnvioDTE.

bag es el DocumentBag ya timbrado y firmado que devuelve DocumentBuilderService.build_signed() — trae certificate/ emisor incluidos, no hace falta pasarlos aparte. El sobre resultante es lo que se envía al SII (SiiDteService.send).

create_many(bags: Sequence[DocumentBag]) → DocumentEnvelope

Envuelve y firma 2+ documentos ya timbrados en un sobre EnvioDTE.

Igual que create(), pero para un sobre que agrupa más de un documento — cada DocumentBag trae su propio certificate/ emisor. El sobre resultante queda firmado con el certificado del PRIMER DocumentBag (el sobre en sí también se firma, no solo cada documento).

load_xml(xml_base64: str) → DocumentEnvelope

Carga un sobre EnvioDTE ya existente desde su XML (base64).

El DocumentEnvelope resultante trae en documents una bolsa por cada documento tributario que el sobre agrupaba — uno o más — y en caratula los datos de la carátula ya presente en ese XML.

validate(source: str) → dict[str, Any]

Valida un sobre EnvioDTE ya construido (source, XML en base64).

Devuelve el XML del sobre, como dict (representación parseada, ej. EnvioDTE.SetDTE.Caratula…).

validate_schema(source: str) → dict[str, Any]

Valida source contra el esquema XSD del sobre EnvioDTE.

validate_signature(source: str) → list[dict[str, Any]]

Valida cada firma electrónica encontrada en el sobre.

Un sobre trae más de una firma (la del DTE y la del propio EnvioDTE) — devuelve una lista, un ítem por firma. Cada ítem es un dict vacío en caso de éxito.

class libredte_lib_sdk.billing.document.DocumentEnvelope(tag: str, xml_base64: str, documents: tuple[DocumentBag, ...], caratula: dict[str, Any] | None)

Bases: XmlPayloadMixin

Sobre EnvioDTE, ya sea recién construido o cargado desde un XML.

documents trae una bolsa (DocumentBag) por cada documento tributario que el sobre contiene — uno solo si se armó con create(), uno o más si se armó con createMany() o si se cargó con loadXml() un sobre que agrupaba varios documentos. caratula es el dict con los datos de la carátula del sobre (RutEmisor, RutEnvia, RutReceptor, FchResol, NroResol, TmstFirmaEnv, SubTotDTE).

caratula: dict[str, Any] | None
documents: tuple[DocumentBag, ...]
classmethod from_api(data: dict[str, Any]) → DocumentEnvelope

Construye un DocumentEnvelope desde el data de la API.

tag: str
xml_base64: str
class libredte_lib_sdk.billing.document.DocumentExamplesService(client: ApiClient)

Bases: object

Ejemplos de documentos reales (billing.document.examples).

Son los mismos casos de prueba, validados, que usa la suite de tests de libredte-lib-core (tests/fixtures/yaml/documentos_ok/) — uno por variante de negocio real (descuentos, impuesto adicional, pago a crédito, exportación, etc.), no datos inventados por el SDK. Example.example de get() se le pasa tal cual a DocumentBuilderService.build_draft()/.build_signed(), típicamente reemplazando Encabezado.IdDoc.Folio y Encabezado.Receptor por los propios de quien usa el SDK antes de construir el documento.

get(example_id: str) → Example

Entrega los datos completos del ejemplo example_id.

list() → list[ExampleSummary]

Lista los ejemplos disponibles (id, category, case).

class libredte_lib_sdk.billing.document.DocumentLoaderService(client: ApiClient)

Bases: object

Carga un documento tributario completo desde su XML.

Solo cubre loadXml — pensado para reconstruir los datos normalizados de un DTE ya emitido (timbrado y firmado) a partir de su XML, ej. un documento recibido de un tercero o recuperado de un respaldo.

load_xml(xml_base64: str) → DocumentBag

Carga y normaliza el documento cuyo XML (base64) es xml_base64.

Devuelve la misma DocumentBag que DocumentBuilderService — document_id/xml_base64 reconstruyen lo que ya se le pasó acá, document/document_type/document_stamp_base64/etc. son el valor agregado real: los datos ya normalizados.

class libredte_lib_sdk.billing.document.DocumentParserService(client: ApiClient)

Bases: object

Parsea los datos de entrada de un documento (billing.document.parser).

Solo transforma los datos al formato DTE del SII: no normaliza ni construye el documento, no necesita CAF ni certificado.

parse(input_data: str | bytes | dict[str, Any], *, strategy: str | None = None) → DocumentBag

Parsea input_data y entrega la bolsa con los datos parseados.

input_data es el documento en el formato DTE del SII como dict, o datos en otro formato (XML, YAML, un formulario, etc.) como bytes o str. El contenido de un archivo se debe pasar como bytes (leído en modo rb): se envía sin alterar su codificación. Un str ya es texto decodificado y se envía en UTF-8.

strategy es la estrategia de parseo (ej. “default.xml”, “form.lite”); sin ella la API asume default.json.

El resultado es una DocumentBag con document_parsed; document, document_type y el XML quedan en None.

class libredte_lib_sdk.billing.document.DocumentRendererService(client: ApiClient)

Bases: object

Renderiza un documento tributario (billing.document.renderer).

Soporta format=”html” y format=”pdf”. La API devuelve siempre data.renderings, una lista de archivos en base64 — ver RenderResult/RenderedDocument en models.py.

render(document_xml_base64: str, *, format: str = 'pdf', renderings: dict[str, int] | None = None, libredte_data: dict[str, Any] | None = None) → RenderResult

Genera el PDF (u otro formato soportado por la API) de un documento.

Sirve tanto para un borrador como para un documento ya timbrado y firmado: el resultado depende solo del XML que se le pase (ej. DocumentBag.xml_base64).

Sin renderings, la API genera una única copia “tributaria” (comportamiento por defecto). renderings pide presentaciones y cantidad de copias de cada una — ej. {“tributaria”: 1, “cedible”: 1} — y la API rechaza (LibreDteApiError, 500) una presentación que no existe, o si ninguna de las pedidas pudo generarse (ej. pedir solo “cedible” para un tipo de documento sin acuse de recibo). Ver RenderResult para cómo se identifica cada copia en la respuesta.

libredte_data son datos adicionales que no están en el XML del documento pero sí se usan al renderizar la plantilla — ej. {“extra”: {“dte”: {…}, “historial”: […]}}: lo que va en extra.dte se combina con los datos del documento antes de renderizar; el resto de extra (ej. historial) queda disponible aparte para la plantilla.

class libredte_lib_sdk.billing.document.DocumentValidatorService(client: ApiClient)

Bases: object

Valida un documento tributario ya construido (billing.document).

source es el XML del documento en base64 (ej. DocumentBag.xml_base64 de un documento ya construido) — la API acepta también la bolsa o el documento ya cargado, pero el SDK solo necesita pasar el XML.

validate(source: str) → None

Valida los datos del documento (source, XML en base64).

No devuelve valor: si el documento no es válido, la API levanta LibreDteApiError (no hay un resultado «inválido» con detalle).

validate_schema(source: str) → dict[str, Any]

Valida source contra el esquema XSD del documento.

Devuelve el XML ya validado, como dict (la representación parseada del XML, ej. DTE.Documento.Encabezado…) — el SDK no la tipa, ya que su forma depende del tipo de documento.

validate_signature(source: str) → dict[str, Any]

Valida la firma electrónica del documento.

Devuelve un dict vacío en caso de éxito. Si la firma no es válida, la API levanta LibreDteApiError.

class libredte_lib_sdk.billing.document.Example(id: str, example: dict[str, Any], expected: dict[str, Any])

Bases: object

Un ejemplo de documento, tal como lo devuelve examples::get().

example se pasa directamente al parámetro input_data de DocumentBuilderService.build_draft()/.build_signed() — mismo Encabezado/Detalle que usa el resto del SDK, sin transformación. expected son los valores esperados del caso (totales, etc.) que usa la suite de tests de libredte-lib-core para validarlo — información de referencia, no un dato del documento en sí.

example: dict[str, Any]
expected: dict[str, Any]
classmethod from_api(data: dict[str, Any]) → Example

Construye un Example desde el data que devuelve la API.

id: str
class libredte_lib_sdk.billing.document.ExampleSummary(id: str, category: str, case: str)

Bases: object

Un ejemplo listado por DocumentExamplesService.list().

case: str
category: str
classmethod from_api(data: dict[str, Any]) → ExampleSummary

Construye un ExampleSummary desde un ítem de la lista.

id: str
class libredte_lib_sdk.billing.document.RenderResult(renderings: tuple[RenderedDocument, ...])

Bases: object

Resultado de un renderizador.

Ej. DocumentRendererService.render(), PayrollRendererService .render(). renderings trae un ítem por copia generada. Para document.renderer: por defecto (sin pedir renderings explícito) es un único “tributaria”; pidiendo más de una presentación y/o copia (ej. renderings={“tributaria”: 2, “cedible”: 1}), trae uno por cada copia efectivamente generada — una presentación que la API no pudo generar para ese documento (ej. “cedible” en un tipo de documento sin acuse de recibo) se omite en silencio, no rompe la llamada. Para payroll.renderer (que no modela presentaciones) siempre trae un único elemento, sin label. .first es un atajo para el caso más común (un solo archivo); .by_label() filtra por presentación cuando se pidió más de una.

by_label(label: str) → tuple[RenderedDocument, ...]

Los renderings de una presentación (ej. “tributaria”).

property first: RenderedDocument

El primer archivo generado.

classmethod from_api(data: dict[str, Any]) → RenderResult

Construye un RenderResult desde el data que devuelve la API.

renderings: tuple[RenderedDocument, ...]
class libredte_lib_sdk.billing.document.RenderedDocument(content_base64: str, mime_type: str, filename: str, label: str | None, copies: int, copy_number: int)

Bases: object

Un archivo generado por un renderizador.

Ej. DocumentRendererService.render(), PayrollRendererService .render(). content_base64 es el archivo completo en base64 (un PDF, un HTML, lo que sea — mime_type dice qué es). label es la presentación pedida en renderings (ej. “tributaria”, “cedible”) cuando el renderizador modela más de una presentación posible; None cuando no aplica (ej. una liquidación de sueldo, que siempre es un único archivo). copies/copy_number identifican esta copia entre las pedidas de ese mismo label (ej. copies=2, copy_number=1 es la primera de 2 copias tributarias). El nombre de los campos en la API (content/mimeType/filename/copyNumber) es camelCase; acá quedan en snake_case como el resto del SDK.

content_base64: str
property content_bytes: bytes

Contenido del archivo, decodificado desde base64.

copies: int
copy_number: int
filename: str
classmethod from_api(data: dict[str, Any]) → RenderedDocument

Construye desde un ítem de data.renderings.

label: str | None
mime_type: str