Factuarea APIDevelopers

Catàleg de productes

Modela productes i serveis amb unitats UNECE, presentacions, variants, ofertes de proveïdor i snapshots documentals immutables.

El catàleg modela què vens i, per separat, com es presenta, identifica, emmagatzema i compra. Comença amb una clau fact_test_ i concedeix només products:read i/o products:write segons necessitis.

Producte o servei

Cada ítem declara un item_kind explícit:

  • product pot gestionar estoc decimal i tenir variants amb estoc propi.
  • service sempre té manage_stock: false, estoc 0.0000 i llindar d'estoc baix nul. Un servei no admet variants amb estoc propi.

La unitat base pertany al catàleg UNECE tancat: C62, KGM, GRM, LTR, MLT, MTR, MTK, HUR o DAY. Quantitats i estoc admeten quatre decimals; els factors de conversió, sis. La unitat base no es pot canviar quan reinterpretaria estoc, presentacions, variants, ofertes o historial existent.

{
  "name": "Oli d'oliva verge extra",
  "sku": "OOVE-GRANEL",
  "price": "8.75",
  "item_kind": "product",
  "base_unit": "LTR",
  "manage_stock": true,
  "stock": "125.5000",
  "low_stock_threshold": "20.0000",
  "specifications": { "origen": "Jaén", "collita": 2026 }
}

Semàntica de creació i actualització

POST /v1/products exigeix name i price. Si external_id ja identifica un producte de la mateixa empresa, la creació actua com un upsert idempotent en comptes de duplicar-lo. sku també és únic per empresa, però una col·lisió amb un altre producte és un error, no un upsert.

PUT /v1/products/{product}semàntica parcial: cada camp omès conserva el valor actual. Dos camps apliquen substitució explícita:

  • specifications substitueix l'objecte clau-valor complet; null el buida. Les llistes JSON no buides es rebutgen, mentre que {} i [] continuen sent representacions buides compatibles.
  • stock és una quantitat absoluta, no un delta. null el posa a zero. Una diferència real registra un moviment manual; enviar el valor actual no registra res. Utilitza l'endpoint dedicat d'estoc amb increase o decrease per a deltes explícits.

stock i low_stock_threshold admeten fins a quatre decimals. metadata de Producte conserva la frontera retrocompatible: fins a 50 claus, els valors escalars es converteixen a strings i les llistes JSON s'accepten i es persisteixen amb claus numèriques. Això és deliberadament diferent de specifications.

Presentacions

Una presentació és una forma comercial de vendre el producte; mai té estoc propi.

ModeSignificat
fixedquantitat base = quantitat comercial × conversion_factor. Una caixa de 12 usa 12.000000.
variable_measureLa mesura nominal és informativa. Cada línia ha de confirmar la quantitat base real.
POST /v1/products/{product}/presentations
{
  "name": "Caixa de 12",
  "mode": "fixed",
  "unit": "C62",
  "conversion_factor": "12.000000",
  "active": true
}

Usa GET/POST sobre la col·lecció i PUT/DELETE sobre cada ítem. Una presentació inactiva no es pot seleccionar en línies noves, però els documents antics continuen renderitzant des del seu snapshot.

Variants de producte

Una variant conserva identitat comercial pròpia: nom, SKU/codi de barres opcionals, overrides de preu i cost i, opcionalment, estoc propi.

{
  "name": "Blau / M",
  "sku": "SAM-BLA-M",
  "price_override": "24.5000",
  "manage_stock": true,
  "stock": "8.5000",
  "active": true
}

Amb manage_stock: true, els moviments afecten només la variant; altrament deleguen en el producte base sense perdre la identitat de variant a la línia ni al ledger. Una presentació es pot combinar amb una variant: la variant tria el destí d'estoc i la presentació converteix la quantitat.

Opcions configurables i combinacions vendibles

Els grups d'opcions modelen eleccions del comprador —acabat, sabor o nivell de servei—, no specifications informatives. Cada grup conté valors de selecció única; un valor pot afegir un price_adjustment per unitat comercial. Els grups i valors inactius continuen sent llegibles per conservar snapshots històrics, però no es poden triar en una línia nova.

Les configuracions comercials combinen una variant opcional, una presentació opcional i un conjunt canònic de valors d'opció. Cada configuració té una signature estable, pot declarar un preu final per unitat comercial i pot estar activa o inactiva.

catalog_availability_mode controla què es pot vendre:

ModeDisponibilitat
openEl producte cartesià dels eixos actius és vendible. Una configuració només restringeix la disponibilitat amb restricts_availability: true: limita la variant que anomena i tracta la presentació/opcions omeses com a comodins.
closedLes configuracions actives són la llista exacta permesa. Sense cap configuració activa, no es pot vendre res.

La creació fa servir open per defecte; ometre el camp en actualitzar conserva el mode actual. Una fila amb restricts_availability: false encara pot aportar identitat o un preu exacte sense restringir un catàleg obert.

Fes servir GET /v1/products/{product}/options i GET /v1/products/{product}/configurations per inspeccionar el catàleg. Tots dos fan servir products:read i paginació per cursor. El detall del producte els pot incloure amb include=configurable_catalog.

POST /v1/products/{product}/resolve-selection també és una lectura malgrat ser POST: accepta una selecció parcial niada i retorna resolved, incomplete, ambiguous o incompatible, a més dels eixos compatibles i grups pendents. Dos valors del mateix grup formen una petició invàlida.

Abans d'una escriptura que redueixi la disponibilitat, crida POST /v1/products/{product}/configurations/impact-preview amb products:write. No persisteix res i retorna les combinacions afectades, els preus negociats que es retirarien i un impact_token que identifica aquell estat exacte del catàleg. Retorna el token a l'actualització destructiva; si el catàleg o els preus afectats canvien, demana una altra previsualització.

Ledger de stock

GET /v1/products/{product}/stock-movements exposa el llibre major immutable d'estoc del més recent al més antic. Cada fila porta el delta signat en unitats base, el saldo stock_after calculat sobre el llibre complet, el motiu, el document origen, l'usuari i la variant gestora. La paginació fa servir limit i starting_after; direction=in|out filtra les files visibles sense canviar els valors històrics de stock_after.

Ofertes de proveïdor

Una oferta representa condicions de compra sense canviar el preu de venda. Apunta al producte o a una variant i registra proveïdor, unitat de compra, factor, disponibilitat, cost i termini.

{
  "supplier_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a10",
  "variant_id": null,
  "supplier_sku": "PROV-OOVE-20L",
  "purchase_unit": "LTR",
  "conversion_factor": "1.000000",
  "unit_cost": "5.1250",
  "availability": "available",
  "minimum_quantity": "20.0000",
  "lead_time_days": 3,
  "preferred": true,
  "active": true
}

available exigeix unit_cost no negatiu. unavailable, unknown, seasonal i store_dependent exigeixen unit_cost: null. Només hi pot haver una oferta activa preferida per destí; l'acció preferred la canvia atòmicament.

Quan una línia de factura de compra compra contra una oferta, purchase_measurement registra els embalums rebuts i la unitat en què s'expressa el cost (offer_unit, base_unit o presentation_unit); el servidor deriva la quantitat facturada i congela el cost unitari. unit_price omès en una línia de catàleg significa «cost no confirmat»: l'API aplica el cost de l'oferta o rebutja la línia si el proveïdor no té cap oferta activa. Consulta Línies de compra mesurades.

Els documents guarden snapshots

Les línies de catàleg retornen product_id, variant_id, presentation_id, configuració/signatura comercial i valors d'opció, item_kind, unitat comercial i base, factor, quantitat base, origen i semàntica del preu, ajustos d'opció, identitat de tarifa i unitat de preu. Són snapshots: canviar o retirar el catàleg viu no reescriu documents emesos ni històrics.

Per a una presentació variable_measure, envia confirmed_base_quantity en crear la línia. Deixa que l'API derivi totals i quantitats de moviment.

Permisos, eliminació i MCP

  • Les lectures usen products:read; altes, edicions i eliminacions dels nous subrecursos usen products:write. El producte base s'elimina amb products:delete.
  • Les eliminacions de presentació, variant i oferta porten x-irreversible: true a OpenAPI.
  • Un producte referenciat per un ítem de tarifa o oferta vigent no es pot eliminar físicament. Retira abans la referència; l'històric queda en snapshots.
  • El domini Product de MCP té ara 38 tools. A més de les 13 tools de presentacions, variants i ofertes, quatre lectures noves exposen opcions, configuracions, moviments de stock i resolució de seleccions.

Consulta Tarifes, Scopes i irreversibilitat i els esquemes exactes a la Referència de l'API.

Descripcions i consultes de documents

Les línies admeten additional_description nullable de fins a 5000 caràcters al costat de description. Està disponible en factures de venda i rectificatives, pressupostos, proformes, albarans, factures de compra i plantilles recurrents. Mantén aquest detall separat de quantitats, preus, camps fiscals i identificadors del catàleg; afegir descripció no canvia el càlcul de l’import. Consulta GET /v1/products/low-stock-report per a la col·lecció i total_count, i GET /v1/products/{product}/sales-analytics per a les mètriques de vendes; aquestes respostes no són recursos de producte individuals. Els exemples complets són a la referència de l’API.

En aquesta pàgina

Et donem un cop de mà?Contactar amb suport