cadrumo.application.invoices._bulk_import_columns module¶
Resolve a bulk-invoice-import file’s own headers onto importer fields.
A real libro registro carries every field the importer needs under names it has
never seen — fecha_expedicion, base_imponible, nif_destinatario —
and not one of them matches a canonical column name. The importer used to refuse
such a file whole, so a book with every required field present imported nothing.
Resolution is deterministic first: a column whose header is already a canonical
importer column keeps that field without consulting anything. Only the columns
left over are put to the semantic mapping lane, once per file, over the closed
FieldRole vocabulary. Exact-first matters for the same reason it
does in the statement lane — a file already written in the product’s own
vocabulary must never depend on a judgement to be read.
A column that resolves to no importer field is reported, never refused. The
book that carries cuota_iva and total_factura — figures the importer
derives rather than accepts — still imports every row; the operator is told
which columns were not used instead of being handed a rejected file.
See also
FieldRoleThe closed vocabulary the mapping lane selects from.
bulk_importReads the file and applies this resolution to each row.
- BULK_IMPORT_FIELD_BY_ROLE: dict[FieldRole, str]¶
a role the importer has no field for (the IVA cuota and the grand total, both of which it derives rather than accepts) is absent here, so a column carrying one resolves to no field and is reported rather than quietly discarded.
A retención rate is accepted only beside its amount: the importer checks the two against each other and never derives the amount from the rate.
- Type:
Which importer field each role feeds. Deliberately partial
- ColumnRoleMapper¶
Establishes one role per column for a header row, or
Nonewhen it cannot.alias of
Callable[[Sequence[str]],Sequence[FieldRole] |None]
- class ResolvedColumn(**data)[source]¶
Bases:
BaseModelOne source column and the importer field it feeds.
- Variables:
column_index – Zero-based position in the source header.
header – The header text exactly as the file printed it.
field – The importer field this column supplies, or
Nonewhen the column’s meaning was not established or maps to nothing the importer accepts.role – The role the column was mapped to.
UNMAPPEDwhen the mapping lane could not place it; a real role withfieldstillNonemeans the product understood the column but has no slot for it.
- Parameters:
data (Any)
- column_index: NonNegativeInt¶
- header: str¶
- field: str | None¶
- role: FieldRole¶
- class BulkImportColumnResolution(**data)[source]¶
Bases:
BaseModelHow one file’s header row resolved onto importer fields.
- Variables:
columns – Every source column, in order.
consulted_mapping_lane – Whether the semantic lane was called.
Falsemeans every column matched a canonical name outright.
- Parameters:
data (Any)
- columns: tuple[ResolvedColumn, ...]¶
- consulted_mapping_lane: bool¶
- property unmapped_columns: tuple[ResolvedColumn, ...]¶
Return every column that feeds no importer field, for reporting.
- resolve_bulk_import_columns(headers, *, mapper=None, required_fields=frozenset({}))[source]¶
Resolve
headersonto importer fields, exact names first.A header that already names a canonical importer column is bound to it without consulting
mapperat all. The mapping lane is called at most once, and only when exact matching cannot supply every required field — a file already written in the product’s own vocabulary is read without any judgement, even when it carries extra columns the importer has no slot for. Those extras are simply reported. Its verdict is applied only to columns exact matching left open, so it can never displace an exact match.- Parameters:
headers (
Sequence[str]) – The source header cells, in column order.mapper (
Callable[[Sequence[str]],Sequence[FieldRole] |None] |None) – Establishes roles for the columns exact matching did not resolve.Noneleaves them unmapped and reported.required_fields (
frozenset[str]) – Fields the importer cannot proceed without. The mapping lane is consulted only if exact matching misses one.
- Return type:
- Returns:
The per-column resolution, with everything unresolved reported rather than refused.