Skip to content

Quotes Integration Guide

This guide explains how to integrate the Quote (Devis) system. A quote represents a customer quotation containing one or more products with pricing, validation states, and multi-language PDF generation capabilities.

  1. Create Quote: POST /quotes with project, company, and items (briefs or articles)
  2. Add Items: POST /quotes/:id/quote-items to add configured products or catalog articles
  3. Publish Quote: Update state from “draft” to “published” (assigns unique code)
  4. Generate PDF: POST /quotes/:id/generate-pdf with language preference
  5. Track Status: Monitor quote state (published → signed/rejected/expired)
EndpointReturnsUse Case
POST /quotesQuoteCreate customer quotation
GET /quotes/:idComplete quote + itemsGet all quote data
POST /quotes/:id/quote-itemsUpdated quoteAdd line items
POST /quotes/:id/generate-pdfPDF fileGenerate quote document
GET /quotes/:id/localisation/:localePDF downloadDownload by language

Root entity representing a customer quotation with pricing and validation state.

Key Properties: id, code, name, state, totalPrice, toolingCost, deliveryCost, validUntil, email

Validation States:

  • draftpublishedsigned / rejected / expired
  • Code assigned only when published

Main Relationships:

  • itemsQuoteItem[] (One-to-Many, required)
  • projectProject, companyCompany
  • contact → User, address → Address
  • pdfs → File[] (multi-language support)

📖 Full Quote Entity Documentation


Line item within a quote, can reference configured products or predefined articles.

What It Contains:

  • Product Reference: Links to either Brief/BriefElement OR Article
  • Pricing: Quantity, unit price, total price
  • Dimensions: Length, width, height for logistics
  • Hierarchy: Parent-child relationships for complex structures

Item Types:

  • BriefElement from actual Brief: References a configured product from an existing Brief (links via brief and briefElement)
  • Article: References a predefined catalog product (links via article)
    • Article may be linked to a BriefElement (from an actual Brief or standalone)
    • Article may exist without any BriefElement link

Hierarchical Structure (Quotes from Briefs):

When a quote is generated from Briefs, QuoteItems are automatically structured as hierarchical groups:

  • Parent QuoteItem → References the Brief
  • Children QuoteItems → Reference individual BriefElements from that Brief

Example structure:

Quote
└── QuoteItem (parent) → Brief 1
├── QuoteItem (child) → BriefElement 1
├── QuoteItem (child) → BriefElement 2
└── QuoteItem (child) → BriefElement 3
└── QuoteItem (parent) → Brief 2
└── QuoteItem (child) → BriefElement 1

Key Properties: id, quoteId, quantity, price, totalPrice, position, valid

Main Relationships:

  • quoteQuote (Many-to-One)
  • briefBrief, briefElementBriefElement (for configured products from actual briefs)
  • articleArticle (for predefined products, which may or may not link to a BriefElement)
  • parent/children → QuoteItem (for hierarchical items)

📖 Full QuoteItem Entity Documentation


Predefined product that can be added to quotes, linked to production specifications.

What It Contains:

  • Product Details: Name, code, description, pricing
  • Inventory: Stock status and quantity
  • Production Specs: Link to BriefElement for manufacturing details
  • ERP Integration: External ID for synchronization

Key Properties: id, code, name, price, stocked, quantity, briefElementId, externalId

Creation Scenarios:

  • Created after configuration (links to existing BriefElement)
  • Created from ERP (auto-creates BriefElement)

Main Relationships:

  • companyCompany (Many-to-One, required)
  • briefElementBriefElement (Many-to-One)
  • quoteItemsQuoteItem[] (One-to-Many)
  • files → File[] (preview, CAD files, documents)

📖 Full Article Entity Documentation


Company → Project → Quote → QuoteItem
├─→ Brief → BriefElement
└─→ Article → BriefElement
  1. Quote Structure: Company → Project → Quote → QuoteItems
  2. Configured Products: QuoteItem → Brief → BriefElement
  3. Catalog Products: QuoteItem → Article → BriefElement (for specs)
  4. Mixed Quotes: QuoteItems can contain both configured products and articles

POST /quotes

Creates a new quote in draft state with project, company, and initial items.

Request Example:

{
"name": "Quote for Packaging Project",
"projectId": "uuid-of-project",
"companyId": "uuid-of-company",
"email": "[email protected]",
"phoneNumber": "+33123456789",
"receiverName": "John Doe",
"contactId": "uuid-of-contact",
"addressId": "uuid-of-address",
"validUntil": "2024-12-31T23:59:59Z",
"briefIds": ["uuid-brief-1", "uuid-brief-2"]
}

GET /quotes/:id

Retrieves a single quote with all relationships (items, project, company, etc.).

GET /quotes

Query Parameters: page, limit, sort, search, status, projectId, companyId

PUT /quotes/:id

Updates quote properties (name, email, validUntil, etc.).

POST /quotes/:id/generate-pdf

Generates PDF document with specified language.

Request: { "localisationId": "fr-FR" }

GET /quotes/:id/localisation/:localisationId

Downloads the generated PDF file.


POST /quotes/:id/quote-items

Adds configured products (briefs) or catalog articles to a quote.

Request Example:

{
"items": [
{
"briefId": "uuid-brief-1",
"briefElementId": "uuid-element-1",
"quantity": 1000,
"comment": "Custom packaging"
},
{
"articleId": "uuid-article-1",
"quantity": 50,
"price": 25.0,
"comment": "Catalog item"
}
]
}

DELETE /quotes/:id/quote-items/:itemId

Removes an item from a quote.


POST /articles

Creates a new article with optional BriefElement reference.

Request Example:

{
"name": "Custom Box 20x20x10",
"code": "BOX-001",
"description": "Custom packaging box",
"price": 2.50,
"stocked": true,
"quantity": 500,
"companyId": "uuid-of-company",
"briefElementId": "uuid-of-brief-element",
"externalId": "ERP-12345"
}

GET /articles/:id

Retrieves article details with all relations.

GET /articles

Query Parameters: page, limit, search, sort, companyId, briefElementId, enabled

PATCH /articles/:id

Updates article properties.

DELETE /articles/:id

Soft deletes an article.


  1. Create/Select Project: GET /projects or POST /projects
  2. Create Briefs: User configures products in configurator
  3. Create Quote:
    POST /quotes
    {
    "projectId": "uuid",
    "companyId": "uuid",
    "briefIds": ["brief-1", "brief-2"]
    }
  4. Publish: Change state from “draft” to “published” (assigns code)
  5. Generate PDF: POST /quotes/:id/generate-pdf
  1. Select Articles: GET /articles?companyId=uuid
  2. Create Quote:
    POST /quotes
    {
    "projectId": "uuid",
    "items": [
    { "articleId": "uuid-1", "quantity": 100, "price": 10.0 }
    ]
    }
POST /quotes/:id/quote-items
{
"items": [
{ "briefId": "uuid-brief", "comment": "Custom" },
{ "articleId": "uuid-article", "quantity": 50 }
]
}

Scenario A - Link to Existing Configuration:

POST /articles
{
"name": "Box from ERP",
"code": "ERP-001",
"briefElementId": "existing-uuid",
"externalId": "ERP-12345"
}

Scenario B - Auto-Create Configuration:

POST /articles
{
"name": "Box from ERP",
"code": "ERP-002",
"externalId": "ERP-54321",
"briefElement": {
"productId": "uuid",
"lengthDimension": 200
}
}

The state property is critical for quote workflow:

// Quote states
"draft" → Quote is being prepared, can be edited
"published" → Quote sent to client, code assigned, locked
"signed" → Client accepted the quote
"rejected" → Client declined the quote
"expired" → Quote past validUntil date
// Only published quotes get a unique code
const quote = await createQuote({ state: "draft" }); // No code
await publishQuote(quote.id); // Code assigned automatically

When quotes are generated from Briefs, items are automatically structured:

// Parent-child structure from Briefs
Quote → QuoteItem (parent: Brief)
└─ QuoteItem (child: BriefElement 1)
└─ QuoteItem (child: BriefElement 2)
// Access hierarchy
const parentItem = quote.items.find(i => i.briefId && !i.parentId);
const childItems = quote.items.filter(i => i.parentId === parentItem.id);

Articles can be added to quotes in two ways:

1. Link to Existing BriefElement:

POST /articles
{
"briefElementId": "existing-uuid",
"externalId": "ERP-001"
}

2. Auto-Create BriefElement from ERP:

POST /articles
{
"externalId": "ERP-002",
"briefElement": { "productId": "uuid", ... }
}
  • Quote: items array is required (must have at least one QuoteItem)
  • QuoteItem: Either briefId/briefElementId OR articleId must be provided
  • State Transitions: Draft → Published requires all pricing to be calculated
  • Multi-language Support: Generate PDFs in different languages using localisationId
  • State Requirement: Quote must be in published state before PDF generation
  • Guest Access: PDFs can be accessed via guest links without authentication

  • Multi-language PDF: Generate quotes in multiple languages
  • Guest Access: Share quotes via temporary access links
  • Draft System: Auto-save quotes before publishing
  • Mixed Content: Support for both configured products and catalog articles
  • State Management: Draft → Published → Signed/Rejected/Expired
  • ERP Integration: External ID fields for synchronization
  • Hierarchical Items: Parent-child relationships for complex products