Factuarea APIDevelopers
Contracte

Línies de compra mesurades

Les línies de factura de compra registren ja els embalums rebuts, la unitat a la qual s’aplica el cost del proveïdor i la mesura real. El contracte afegeix un bloc de mesura, persisteix el descompte de línia, resol el cost des de l’oferta del proveïdor i duplica una compra des d’un origen autoritzat.

Les factures de compra separen ja la part física d’una compra de la part facturada. Una línia pot indicar quants embalums han arribat, en quina unitat s’expressa el cost del proveïdor i la mesura real; el servidor deriva la quantitat facturada, el factor de conversió a la unitat base i el cost unitari congelat. Una línia sense el bloc nou conserva la seva semàntica anterior de quantity × unit_price.

Nous camps de la petició

POST /v1/purchase_invoices i PUT /v1/purchase_invoices/{purchase_invoice} accepten aquests camps additius. Ometre’ls tots continua sent una petició vàlida.

CampSignificat
source_purchase_invoice_idUUID d’una factura de compra de la teva empresa les línies històriques de la qual vols duplicar. Només en crear. La key necessita purchase_invoices:read a més de purchase_invoices:write; si no, 403 insufficient_scope. Un origen desconegut o d’una altra empresa retorna 404 purchase_invoice_not_found.
lines[].purchase_measurementObjecte tancat amb package_quantity (string decimal o null) i cost_basis (offer_unit, base_unit o presentation_unit). Omès o null conserva el contracte legacy. Els camps derivats de lectura (billing_*, unit_cost) es rebutgen en escriptura, encara que provinguin d’una lectura anterior.
lines[].discount_percentDescompte percentual, 0–100 amb fins a quatre decimals, aplicat abans d’impostos. L’API l’acceptava i el descartava en silenci; ara es persisteix i es retorna.
lines[].source_line_indexOrdinal base zero de la línia al document origen autoritzat. Manté la línia duplicada aparellada amb les seves mesures i el seu cost congelat històrics. Mai una clau interna.
lines[].price_sourcemanual o supplier_offer. Nou a l’API pública; canvia com es llegeix unit_price (vegeu més avall).
metadata.purchase_source_reviewClau reservada: string JSON compacte de 500 caràcters com a màxim amb l’estat de la conciliació OCR (pending, reconciled o accepted_difference), totals d’origen i calculat, diferència i motiu. La metadata continua sent plana; els objectes imbricats es rebutgen.

Exemple: tres caixes de 2 kg comprades amb una oferta per quilo

El proveïdor cotitza 7,40 per kg. Tres caixes de 2 kg es facturen com a 6 kg; el servidor deriva el mateix import brut, 44,40, triïs la base que triïs.

{
  "external_invoice_number": "F-2026-0918",
  "issued_on": "2026-09-18",
  "supplier_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a10",
  "lines": [
    {
      "product_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01",
      "presentation_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a02",
      "supplier_offer_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a03",
      "quantity": "6.0000",
      "unit_price": "7.4000",
      "price_source": "supplier_offer",
      "tax_rate": 10,
      "purchase_measurement": { "package_quantity": "3.0000", "cost_basis": "offer_unit" }
    }
  ]
}

La mateixa compra a preu per caixa fa servir "quantity": "3.0000", "unit_price": "14.8000" i "cost_basis": "presentation_unit" amb cost manual. Una presentació pesada (mesura variable) exigeix a més confirmed_base_quantity, encara que s’hi apliqui una oferta.

Com es resol el cost

Canvien dos comportaments a les línies de catàleg (les que porten product_id) a l’API pública i a MCP, igual que a l’aplicació web:

  • unit_price omès significa «cost no confirmat», no zero. El servidor proposa el cost de l’oferta del proveïdor aplicable. Si el proveïdor no té cap oferta activa per al producte o la variant triats, la línia es rebutja amb 422 parameter_invalid_value i param: unit_price. Abans aquell silenci es desava com a 0.00 i l’stock entrava valorat a zero. Les línies manuals sense product_id continuen exigint unit_price.
  • price_source: "supplier_offer" deixa de ser decoratiu. Enviat juntament amb unit_price, l’import es llegeix com l’eco del cost que va resoldre el servidor i es torna a congelar el cost de l’oferta. Per imposar un cost, envia price_source: "manual" o omet-lo: l’import que envies es respecta.

El cost supplier_offer s’aplica a la unitat de compra de l’oferta. Una compra de mesura variable sense confirmed_base_quantity es rebutja fins i tot amb oferta. Els documents històrics no es recalculen.

Nous camps de la resposta

PurchaseInvoiceLine, retornat en llistar, consultar, crear i actualitzar:

CampSignificat
purchase_measurementBloc derivat o null: package_quantity, billing_quantity, billing_unit_code, billing_conversion_factor, unit_cost i cost_basis.
confirmed_base_quantityMesura real en la unitat base com a string decimal; null quan la línia no l’exigeix.
discount_percentAplicat abans d’impostos. subtotal ja n’és net, de manera que unit_price × quantity no és igual a subtotal en una línia amb descompte.
source_line_indexOrdinal base zero de la línia dins del seu document, en ordre estable de lectura.
quantity, unit_priceEl tipus passa a ser number | string. Una línia mesurada retorna strings de 4 decimals per no perdre precisió; una línia legacy conserva el número que sempre ha publicat. Parseja tots dos.

Errors

Els errors de mesura són 422 amb code: parameter_invalid_value i subcode: catalog_line_assembly_invalid; param assenyala el camp que cal corregir.

paramCausa
purchase_measurement.cost_basisLa base no és vàlida, falta l’oferta o presentació que requereix, o la unitat de compra i la unitat base són de famílies diferents.
purchase_measurement.package_quantityEls embalums han de ser positius, amb quatre decimals com a màxim.
quantityLa quantitat facturada no coincideix amb els embalums ni amb la mesura confirmada.
confirmed_base_quantityObligatòria en una presentació de mesura variable, o la mesura no es pot expressar amb quatre decimals en la unitat de facturació.
unit_priceNo hi ha cap cost a aplicar: el proveïdor no té oferta activa per a la selecció, o una conversió legacy perdria precisió.

Un bloc de mesura emmagatzemat que no supera la validació es notifica amb subcode: catalog_line_snapshot_invalid. Consulta Errors.

MCP

create_purchase_invoice i update_purchase_invoice publiquen el mateix schema de línia, inclosos purchase_measurement, discount_percent, price_source, source_line_index i source_purchase_invoice_id, i apliquen la mateixa regla addicional de purchase_invoices:read en duplicar. get_purchase_invoice retorna els nous camps de línia. Consulta el catàleg de tools MCP.

Llegeix Catàleg de productes per a les ofertes de proveïdor i Imports i dates per als camps de línia de compra.

Endpoints actualitzats4

EndpointDescripció
POST/v1/purchase_invoicesCrea una factura de compra
PUT/v1/purchase_invoices/{purchase_invoice}Actualitzar una factura de compra
GET/v1/purchase_invoices/{purchase_invoice}Obtenir una factura de compra
GET/v1/purchase_invoicesLlistar totes les factures de compra

En aquesta pàgina

Et donem un cop de mà?Contactar amb suport