Aller au contenu principal

Patterns

Catalogue produits et autoremplissage de lignes

Pré-remplir une ligne via `product_id` et enregistrer à la volée

Le registre `products` stocke des produits/services réutilisables (prix HT, TVA par défaut, unité UN/ECE Rec 20, `revenue_category` fiscale, catégorie d'organisation custom). À la création d'une facture, d'un devis ou d'un avoir, une ligne peut référencer `product_id` : l'API pré-remplit description, prix, taux de TVA et unité depuis le catalogue. Le flag `save_to_catalog=true` sur une ligne déclenche un upsert atomique du produit (dédup par SKU puis nom) DANS la transaction du document. Comme pour les buyers, le lien `line.product_id` est soft (FK `nullOnDelete`) : le snapshot de prix/description émis reste la vérité ISCA — supprimer un produit du catalogue n'altère pas les documents passés. La `revenue_category` (goods/service/accommodation) est distincte de la `product_category_id` (organisation interne, custom).

À retenir

  • `products` + `product_categories`, scope (tenant_id, sub_tenant_id)
  • Ligne avec `product_id` → autoremplissage desc/prix/TVA/unité
  • `save_to_catalog=true` → upsert atomique dans la transaction du doc
  • `line.product_id` soft (FK nullOnDelete), snapshot émis = vérité ISCA
  • `revenue_category` fiscale ≠ `product_category_id` (organisation)
  • Endpoints : `/api/v1/products` et `/api/v1/product-categories`

Exemple de code

import { ScellApiClient } from '@scell/sdk'; // v3.5.0

const client = new ScellApiClient({ apiKey: process.env.SCELL_API_KEY! });

// 1. Créer un produit catalogue
const product = await client.products.create({
  name: 'Licence SaaS annuelle',
  sku: 'SAAS-ANNUAL',
  unit_price_ht: 1200,
  default_tax_rate: 20,
  revenue_category: 'service',
  unit: 'C62', // unité par défaut UN/ECE Rec 20
});

// 2. Facturer : la ligne référence product_id (autoremplissage serveur)
const invoice = await client.invoices.create({
  format: 'factur-x',
  profile: 'EN16931',
  currency: 'EUR',
  buyer: { siret: '98765432109876', name: 'Acme SARL', address: { street: '2 av. Demo', city: 'Lyon', postal_code: '69001', country: 'FR' } },
  lines: [
    { product_id: product.id, quantity: 2 }, // desc/prix/TVA repris du catalogue
    // 3. Nouvelle ligne enregistrée à la volée dans le catalogue
    { description: 'Setup initial', quantity: 1, unit_price: 500, vat_rate: 20, save_to_catalog: true },
  ],
});
console.log('Facture :', invoice.id);

Voir aussi

Vos préférences cookies

Nous utilisons des cookies pour améliorer votre expérience. Les cookies essentiels sont toujours actifs. Politique cookies.