# Cahier des charges — SaaS de gestion des offres commerciales et P&L
## Basé sur le fichier `725116v6_P-L-Rev6.xlsm` — HASLER Group
**Destination : Lovable (génération de code React/TypeScript fullstack)**

---

## 1. Contexte et objectif

HASLER Group est un fabricant d'équipements industriels (filtration, dosage, agitation, malaxage) qui gère ses offres commerciales et sa rentabilité projet dans un fichier Excel complexe de 18 feuilles. Ce cahier des charges vise à reproduire l'intégralité des fonctions de ce fichier dans une application SaaS multi-utilisateurs, multi-projets et multi-langues.

**L'application s'appelle :** `HASLER Offer Studio` (ou nom à définir)

**Utilisateurs cibles :**
- Ingénieurs d'offre (Tender Engineer / AE) — saisie des coûts
- Ingénieurs commerciaux / ASM (Area Sales Manager) — saisie des prix de vente
- Chefs de projet / Direction — lecture des KPIs et marges

---

## 2. Architecture générale

```
┌─────────────────────────────────────────────────────────┐
│                    HASLER Offer Studio                  │
├──────────────┬──────────────┬───────────────────────────┤
│  Projects    │  P&L / Budget│  Document Generator       │
│  (Affaires)  │  (Marges)    │  (Offres PDF multilingues) │
├──────────────┴──────────────┴───────────────────────────┤
│              Admin / Configuration                      │
│   (Utilisateurs, DAS, Marchés, Taux horaires, Cibles)  │
└─────────────────────────────────────────────────────────┘
```

**Stack recommandée pour Lovable :**
- **Frontend** : React + TypeScript + Tailwind CSS + shadcn/ui
- **Backend** : Supabase (PostgreSQL + Auth + Storage)
- **PDF** : React-PDF ou Puppeteer pour génération offres client
- **Calculs** : logique côté serveur (Edge Functions Supabase)

---

## 3. Modules et écrans détaillés

---

### MODULE 1 — Gestion des projets (Affaires)

**Équivalent feuilles :** `Simplified P&L` (section header), `Configuration`

#### 3.1 Liste des projets (Dashboard)

Tableau de tous les projets avec colonnes :
| Champ | Type | Source |
|---|---|---|
| Numéro d'offre | String | Ex : `725116` |
| Version offre commerciale | Integer | Ex : `6` |
| Version offre technique | Integer | Ex : `6` |
| Client | String | Ex : `St Gobain` |
| Description projet | Text | Ex : `Replacement of Gelsa Filter - 1x HVBF 6B10` |
| Pays | String | Ex : `Spain` |
| Marché | Dropdown | Liste : CCH, MMF, ENV, DEV (voir §7) |
| DAS | Dropdown | DOSING / FILTRATION / MIXING / PROCESSING |
| TAC | Dropdown | EQUIPMENT / REVAMPING / SPARE PARTS / SERVICE / OTHER |
| ASM (commercial) | Dropdown | Liste utilisateurs rôle ASM |
| T eng. (ingénieur) | Dropdown | Liste utilisateurs rôle Tender Engineer |
| CEGID Order | String | Numéro ordre interne |
| Statut | Enum | Draft / 1st Quotation / Final Order / Won / Lost |
| Incoterm | Dropdown | DAP / EXW / CIF / FOB / DDU |
| Lieu incoterm | String | Ex : `Gelsa (Spain)` |
| Délai de livraison | String | Ex : `45 weeks on EXW basis...` |
| Conditions de garantie | Dropdown | 6 options (voir §7.4) |
| Langue offre | Dropdown | English / French / Chinese |
| Date création | Date | Auto |
| Date dernière modification | Date | Auto |

**Filtres disponibles :** DAS, Marché, ASM, Statut, Pays, Période

**Actions :** Créer, Dupliquer, Archiver, Exporter PDF

---

### MODULE 2 — Budget / P&L Simplifié

**Équivalent feuilles :** `Simplified P&L`, `Budget Target`

#### 3.2 Vue P&L Simplifiée par projet

Deux colonnes de saisie côte à côte : **1st Quotation** et **Final Order**, plus une colonne **End figure** (réalisé).

##### 2.1 Section Chiffre d'affaires (Turnover)

| Ligne | Saisie / Calcul | Règle |
|---|---|---|
| **TOTAL Turnover** | Calculé | Somme des lignes ci-dessous |
| Equipment | Calculé depuis Budget Price | = Σ lignes EQUIPMENT du Budget |
| Revamping | Calculé | = Σ lignes REVAMPING |
| Spare Parts | Calculé | = Σ lignes SPARE PARTS |
| Freight out and Packaging | Calculé | = Σ lignes PACKAGING & TRANSPORT |
| Service | Calculé | = Σ lignes SERVICE |
| Warranty Extension | Manuel (%) | 6% par année supplémentaire |
| Other (Bank Charge Fees) | Manuel | Saisie libre |

##### 2.2 Section Coûts directs externes

| Ligne | Saisie / Calcul | Règle |
|---|---|---|
| **Purchasing** | Calculé | |
| Material & Transport | Calculé | |
| — Mechanical parts (Third Party) | Calculé | = Σ coûts EQ mécanique |
| — Hasler China | Manuel | Saisie AE |
| — Electrical parts | Calculé | = Σ coûts EQ électrique |
| — Packaging and Freight Out | Calculé | = Σ coûts transport |
| **External Subcontracting & Travel** | Calculé | |
| — Technical Subcontracting | Calculé | |
| — Purchasing Subcontracting | Calculé | |
| — Service Subcontracting | Calculé | |
| — Travel Expenses | Calculé | |
| — Miscellaneous | Calculé | |

##### 2.3 KPI Marge Brute (GM1)

```
GM1 = TOTAL Turnover - TOTAL Direct External Costs
GM1% = GM1 / TOTAL Turnover
```

**Affichage visuel :** Jauge colorée comparant GM1% à la cible (Budget Target) :
- Rouge si < cible − 5%
- Orange si dans la fourchette −5% / cible
- Vert si ≥ cible

**Cibles par type × DAS (table `Budget Target`) :**
| Type | DOSING | FILTRATION | MIXING | PROCESSING |
|---|---|---|---|---|
| EQUIPMENT | 46,5% | 37% | 27% | 50% |
| REVAMPING | 49% | 39% | 45% | 50% |
| PORT (Packaging/Transport) | 25% | 25% | 25% | 25% |

##### 2.4 Section Man-Hours (Heures directes)

Tableau à 3 colonnes (1st Quotation / Final Order / End Figure) :

| Département | Taux horaire (€/h) | Qté heures saisie | Total coût |
|---|---|---|---|
| Technical department | 50 | Manuel AE | Calculé |
| Mechanical | (inclus Technical) | Manuel | Calculé |
| Electrical | (inclus Technical) | Manuel | Calculé |
| Purchasing | 50 | Manuel | Calculé |
| Project Management | 65 | Manuel | Calculé |
| Workshop — Assembling | 40 | Manuel | Calculé |
| Workshop — Packaging | 40 | Manuel | Calculé |
| Service | 50 | Manuel | Calculé |

**Total Man-Hours coût direct** = Σ (heures × taux)

**Référence heures indicatives** (feuille Rules, lines 22-32) — à afficher en tooltip :
- Technical dept : 210h
- Mechanical : 120h
- Electrical : 90h
- Purchasing : 120h
- PM : 180h
- Workshop : 60h total (30 assembling + 30 packaging)
- Service : 200h

##### 2.5 Autres coûts

| Ligne | Règle |
|---|---|
| % Commissions (% CA) | Manuel — saisie % |
| Commission amount | Calculé = % × TOTAL Turnover |
| % Financial cost | Manuel |
| Financial cost amount | Calculé |
| Bank guarantees | Manuel |
| Documentary credit | Manuel |

##### 2.6 KPI finaux affichés

```
GM1 Equipment = CA Equipment - Coûts directs Equipment
GM1% Equipment vs Cible
GM1 Service = CA Service (marge = 100% car pas de coût direct matière)
% GM1 / TOTAL Turnover
```

---

### MODULE 3 — Budget Détaillé (Budget Price)

**Équivalent feuilles :** `Budget Price 1st quotation`, `Budget Price Final order`

Ces deux feuilles ont la même structure. Dans le SaaS, il s'agit d'un seul formulaire avec le statut (1st Quotation ou Final Order).

#### 3.3 Grille de saisie des lignes budgétaires

**Chaque ligne représente un composant de l'équipement ou un service.**

##### Champs par ligne (27 colonnes dans le fichier) :

| Champ | Type | Règle |
|---|---|---|
| Position | Integer | N° de position (ex : 1, 2, 3…) |
| Type d'équipement | Dropdown | EQUIPMENT / PACKAGING / TRANSPORT / SERVICE |
| Méca/Élec | Dropdown | MECA / ELEC |
| Base / Options | Dropdown | BASE / OPTIONS |
| Description | Text | Libellé du composant |
| Référence | String | Référence HASLER |
| Quantité | Integer | |
| **EQ Unit Cost (coût unitaire)** | Float | Saisie AE — coût d'achat unitaire |
| **TOTAL EQ Cost** | Calculé | = Qty × EQ Unit Cost |
| **Nb hours TECH** | Integer | Saisie AE — heures bureau technique |
| Hours Unit Cost TECH | Float | Paramètre global = 50 €/h |
| **Nb hours PUR** | Integer | Heures achats |
| Hours Unit Cost PUR | Float | = 50 €/h |
| **Nb hours PM** | Integer | Heures chef de projet |
| Hours Unit Cost PM | Float | = 65 €/h |
| **Nb hours WORKSHOP** | Integer | Heures atelier |
| Hours Unit Cost WORKSHOP | Float | = 40 €/h |
| **TOTAL Hours cost** | Calculé | = Σ (heures × taux) |
| **TOTAL Cost** | Calculé | = TOTAL EQ Cost + TOTAL Hours Cost |
| **EQ Unit Selling Price** | Float | **Saisie ASM** (prix de vente unitaire) |
| **TOTAL EQ Selling Price** | Calculé | = Qty × EQ Unit Selling Price |
| **Total Hours Selling Price** | Float | Saisie ASM (heures vendues) |
| **TOTAL Selling Price** | Calculé | = TOTAL EQ Selling Price + Total Hours Selling Price |
| **Gross Margin (€)** | Calculé | = TOTAL Selling Price − TOTAL Cost |
| **Gross Margin (%)** | Calculé | = GM / TOTAL Selling Price |
| Margin on EQ | Calculé | = GM EQ / TOTAL EQ Selling Price |
| Margin on hours | Calculé | = GM Hours / Total Hours Selling Price |

##### Sections spéciales (lignes fixes) :

| Section | Type | Règle |
|---|---|---|
| Technical Subcontracting | EQUIPMENT | Saisie libre |
| Purchasing Subcontracting | EQUIPMENT | Saisie libre |
| Service Subcontracting | SERVICE | Saisie libre |
| Travel Expenses | EQUIPMENT | Saisie libre |
| Miscellaneous (warranty extension) | EQUIPMENT | Saisie libre |
| PACKAGING | PACKAGING | Saisie coût + prix |
| TRANSPORT | TRANSPORT | Saisie avec destination (incoterm) |
| SERVICE lignes 1-4 | SERVICE | Prix de vente uniquement (marge = 100%) |

##### Ligne de total automatique :

```
TOTAL CALCULATED:
  TOTAL EQ Cost = Σ coûts EQ
  TOTAL Hours cost = Σ coûts heures
  TOTAL Cost = Σ coûts totaux
  EQ Unit Selling = Σ prix vente EQ
  Total Hours Selling = Σ prix heures vendues
  TOTAL Selling = Σ prix vente total
  Gross Margin = Σ marges
```

##### Ratio de couverture (affiché en bas) :
```
Ratio = TOTAL Selling Price / TOTAL Cost
```
Dans le fichier, ce ratio est de **1.639** pour le projet exemple (64% de marge nette sur coûts).

#### 3.4 Règles de saisie et UX

**Couleurs des cellules (à reproduire avec des badges/styles) :**
- **Blanc** = saisie AE obligatoire (coûts)
- **Orange** = saisie ASM (prix de vente, colonnes K & L dans le fichier)
- **Calculé** = non modifiable, fond gris

**Validation métier :**
- Si EQ Unit Selling Price < EQ Unit Cost → alerte rouge "Marge négative"
- Si GM% < cible DAS − 10% → warning orange
- Note de ligne possible : champ texte libre pour annoter une estimation (ex: "50% from MS0450")

---

### MODULE 4 — Génération des documents d'offre

**Équivalent feuilles :** `Main cover`, `cover_L`, `PRICE_LIST`, `Quotation`, `Quotation2`, `Quotation3`, `STS`, `Customer_services`, `Services_client`, `GTC`

Le SaaS doit générer un dossier d'offre complet en PDF, dans la langue sélectionnée (EN/FR/CN).

#### 4.1 Table des matières (cover_L)

Document structuré automatiquement avec les sections suivantes (cochable pour inclure/exclure) :

| Section | Sous-sections | Inclure ? |
|---|---|---|
| Cover Letter | | Toujours |
| Price List | | Toujours |
| Special Terms of Sales | Delivery Time, INCOTERM, Terms of Payment, Warranty, Validity | Toujours |
| Contacts | Customer Contact List, HASLER France Contact List | Toujours |
| General Terms & Conditions of Sale | | Option |
| General Conditions of Intervention | | Option (si service) |
| Engineering Deliverables | | Option |

#### 4.2 Page de couverture (Main cover)

Champs automatiques depuis la fiche projet :
- Logo HASLER Group
- Titre : "Filtration system" / "Dosing system" etc. (depuis DAS)
- Numéro de l'offre : `725116-6_COMM`
- Description projet
- Nom du client
- Date

#### 4.3 Lettre d'introduction (cover_L)

Template avec variables dynamiques :
- Numéro offre commerciale : `725116-6`
- Référence offre technique liée : `725116-6_TECH`
- Corps de lettre paramétrable
- Signataires : Tender Engineer + ASM (nom + fonction)
- Mention "Budget offer" si `Budget proposal = Yes`

#### 4.4 Liste de prix — Équipements (Quotation)

**Section Base (obligatoire) :**

Tableau de l'équipement de base avec colonnes :
| Item | Description | MOC | Ø (mm) | Débit (m³/h) | Puissance (kW) | Qté |
|---|---|---|---|---|---|---|

Suivi du **GRAND TOTAL EQUIPMENT excl. Options & Engineering (€ HT)**

Détail de l'équipement principal (filtre) :
- Taille (m²)
- Largeur (m)
- MOC (matériaux de construction) : Frame, Vacuum box, Slurry Feeder, Cake Washing Feeder, Collection trough, Cake discharge hopper, Cloth & belt support rollers, Belt, Curbs, Filter Cloth, Gear box, Safety guards CE
- Motorisation

**Section Engineering :** Total heures vendues (si applicable)

**Packaging & Delivery :**
| Item | Description | Prix unitaire € HT | Prix total € HT |
|---|---|---|---|
| Packing | | | |
| Freight | [Incoterm + destination] | | |

**GRAND TOTAL OFFER (€ HT)**

#### 4.5 Liste de prix — Options (Quotation2)

Tableau des options avec colonnes :
| Réf. | Description | MOC | Ø | Débit | Qté | Puissance | PU € HT | Total € HT |
|---|---|---|---|---|---|---|---|---|

Notes liées aux options (ex: "Note (1) : Saint Gobain want to reuse their own equipment")

**GRAND TOTAL OPTIONS (€ HT)**

#### 4.6 Liste de prix — Services & Pièces de rechange (Quotation3)

Tableau :
| Réf. | Description | Qté | PU € HT | Total € HT |
|---|---|---|---|---|
| A | Erection for X weeks | 1 | ... | ... |
| B | Factory Acceptance Test & Cold Commissioning | 1 | ... | ... |
| C | Hot Commissioning | 1 | ... | ... |

Note conditions tarifaires de base.

**GRAND TOTAL SERVICES / SPARE PARTS (€ HT)**

#### 4.7 Conditions Particulières de Vente (STS)

Textes conditionnels (paramétrables depuis Configuration) :

| Section | Contenu |
|---|---|
| **Délai de livraison** | Texte long avec durée saisie (ex : "45 weeks EXW basis...") |
| **Note transport** | "Please take into account additional time for delivery to incoterm place" |
| **Note délai estimatif** | Texte standard HASLER (long) |
| **INCOTERM** | Valeur depuis projet (ex : DAP Gelsa, Spain) |
| **Conditions de paiement** | Tableau avec échéances |
| **Tableau des acomptes** | Installment #, % paiement, Terme, Mode, Délai crédit |
| **Garantie** | Texte sélectionné depuis dropdown (6 options) |
| **Validité** | Durée (ex : "1 month") |
| **Contacts client** | Tableau : Société, Adresse, Ville, Pays, Tel, Web + contacts Achat/Technique |
| **Contacts HASLER** | Adresse fixe + ASM + Ingénieur d'offre |

**Options de paiement disponibles (tableau Configuration, col P) :**
| % | Terme | Mode |
|---|---|---|
| 5% à 100% (par pas) | À la commande / à la mise à disposition EXW / autres | Par virement bancaire |

#### 4.8 Tarif services (Customer_services / Services_client)

Deux versions selon langue : Worldwide (EN) et France (FR).

**Structure tarifaire :**

| Type de service | Catégorie personnel | Tarif journalier (8h, L-V) | Samedi | Dimanche/Férié |
|---|---|---|---|---|
| Filtration/Processing : Erection, Maintenance, Audit mécanique | Technicien / Auditeur | 1 222 €/j (153 €/h) | 1 830 € | 2 444 € |
| Dosing/Mixing : Mise en service, Erection, Maintenance | Spécialiste Dosage | 1 352 €/j (169 €/h) | 2 030 € | 2 704 € |
| Filtration/Processing : Essais labo, Commissioning, Formation, Audit process | Ingénieur Process | 1 471 €/j (184 €/h) | 2 206 € | 2 942 € |
| Essais RPA (filtres à bande, rotatifs, UCP) | Ingénieur Process | Sur demande | | |

**Majorations heures supplémentaires :**
- 40-43h/sem → +25%
- 44-48h/sem → +50%
- Nuit (22h-6h) → +50%

**Frais annexes :**
- Rapport d'audit détaillé : 973,35 €
- Journée de voyage : 920 € / 760 € (FR)
- Journée non travaillée : 610 € / 508 €
- Frais kilométriques : 1,30 €/km + 15%
- Frais administratifs préparation : 336 €
- Validité : 1er janvier – 31 décembre 2024

---

### MODULE 5 — Conditions Générales (GTC)

**Équivalent feuille :** `GTC`

La feuille GTC contient les CGV en anglais (General Terms & Conditions of Sale — 245 lignes, 31 colonnes).

Dans le SaaS :
- Stockées en base comme document texte riche (Markdown / HTML)
- Versionnables (avec date de mise à jour)
- Incluses automatiquement dans le PDF si option cochée
- Non modifiables par les utilisateurs standards

---

### MODULE 6 — Configuration et administration

**Équivalent feuille :** `Configuration`

#### 6.1 Gestion des utilisateurs

| Code | Prénom Nom | Rôle | Email |
|---|---|---|---|
| AGIB | Alexis Gilbert | Tender engineer | a.gilbert@hasler.group |
| FBAD | Francis Badin | Tender team manager | f.badin@hasler.group |
| BROU | Benoît Roudaut | Area Sales Manager | b.roudaut@hasler.group |
| BJOL | Baptiste Joly | Tender engineer | b.joly@hasler.group |
| YMAR | Yuri Marcuzzo | Tender engineer | y.marcuzzo@hasler.group |
| KSCH | Konstantin Schilow | Tender engineer | k.schilow@hasler.group |
| MLAN | Matthieu Landrieu | Tender engineer | m.landrieu@hasler.group |
| ANGO | Ahou N'gotta | Tender engineer | ac.n'gotta@hasler.group |
| ABOU | Ahssen Boudeheb | Tender engineer | a.boudeheb@hasler.group |
| MBAL | Mélisa Balguy | Trial Technician Filtration | m.balguy@hasler.group |
| CWIE | Cyrus Wiecko | Business Development Manager | c.wiecko@hasler.group |
| GFOR | Guillaume Fort | Area Sales Manager | g.fort@hasler.group |
| CPIS | Cosimo Piscopiello | Area Sales Manager | c.piscopiello@hasler.group |
| WSON | Wei Song | Area Sales Manager | w.song@hasler.group |
| LZHA | Li Zhang | Area Sales Manager | l.zhang@hasler.group |
| JHOU | Jason Houdebine | Business Development Manager | j.houdebine@hasler.group |
| TOUE | Toufik Ouerdani | Area Sales Manager | t.ouerdani@hasler.group |
| EVAQ | Emilie Vaquero | Area Sales Manager | e.vaquero@hasler.group |
| NDEL | Nicolas Delattre | Business Development Manager | n.delattre@hasler.group |
| MJAM | Michel Jamey | Sales Director | m.jamey@hasler.group |
| DCRI | Daniel Criado | Area Sales Manager | d.criado@hasler.group |
| LMEN | Laurent Menigoz | Sales & Marketing Director | l.menigoz@hasler.group |
| AHOU | Adrien Hourlier | Business Development Manager | a.hourlier@hasler.group |
| EGUA | Enrico Gualdi | Area Sales Manager | e.gualdi@hasler.group |
| LLI | Leo Li | Area Sales Manager | l.li@hasler.group |
| PTES | Phirun Tes | Area Sales Manager | p.tes@hasler.group |

**Rôles applicatifs :**
- **Admin** → accès total
- **Sales Director / Marketing Director** → lecture totale, validation
- **Area Sales Manager (ASM)** → saisie prix de vente (colonnes orange), lecture P&L
- **Tender Engineer (AE)** → saisie coûts (colonnes blanches), lecture P&L
- **Business Dev Manager** → lecture uniquement

#### 6.2 Listes de référence (dropdowns)

**DAS (Domaines d'Activité Stratégique) :**
- DOSING → "Dosing system" / "Solution de dosage"
- FILTRATION → "Filtration system" / "Solution de filtration"
- MIXING → "Mixing system" / "Solution d'agitation"
- PROCESSING → "Kneading system" / "Solution de malaxage"

**TAC (Type d'Activité Commerciale) :**
- EQUIPMENT
- REVAMPING
- SPARE PARTS
- SERVICE
- OTHER

**Marchés disponibles :**
- CCH — A2 Cement
- CCH — E4 Technical Silica (and Bulk)
- CCH — F5 Cement and kiln dust dosing
- CCH — H4 Soda Ash
- CCH — other
- MMF — A1 Phosphoric Acid
- MMF — A3 Phosphate Rock
- MMF — B1 Phosphated Fertilizers (MAP, DAP, TSP, DCP…)
- MMF — I3 Lithium
- MMF — L3 Zinc and cadmium
- MMF — N3 Nickel, Cobalt and Manganese
- MMF — Other
- ENV — A5 FGD (Flue-gas & kiln dust/alternative fuels desulfurization)
- ENV — B5 Water Treatment
- ENV — E5 Industrial Waste Water Treatment
- ENV — Other
- DEV — A4 Feed (additives)
- DEV — B4 CERAMIC & MATERIALS (Catalyst, proppants)
- DEV — D4 Sealant - Bonding - Adhesives
- DEV — F4 Battery Pastes
- DEV — G4 Specialty Polymers and resins and compounds
- DEV — I4 Aminated Acids / vitamins / specialty acids
- DEV — J3 Metals recycling
- DEV — Other

**Options de garantie :**
- 12 months after commissioning, latest 18 months after delivery
- 18 months after commissioning, latest 24 months after delivery
- 24 months after commissioning, latest 30 months after delivery *(défaut)*
- 24 months after commissioning, latest 36 months after delivery
- 36 months after commissioning, latest 42 months after delivery

**Échelons de paiement (% disponibles) :**
5%, 10%, 15%, 20%, 25%, 30%, 35%, 40%, 45%, 50%, 55%, 60%, 65%, 70%, 75%, 80%, 85%, 90%, 95%, 100%

#### 6.3 Taux horaires (paramétrables)

| Département | Taux actuel (€/h) |
|---|---|
| Technical department (Meca + Elec inclus) | 50 |
| Purchasing | 50 |
| Project Management | 65 |
| Workshop (Assembling + Packaging) | 40 |
| Service | 50 |

Ces taux doivent être modifiables par Admin et historisés avec date de mise à jour.

#### 6.4 Budget Target par DAS

Table modifiable par Admin :

| Type | DAS | Taux cible GM1 | Date màj |
|---|---|---|---|
| EQUIPMENT | DOSING | 46,5% | 01/01/2024 |
| EQUIPMENT | FILTRATION | 37% | — |
| EQUIPMENT | MIXING | 27% | — |
| EQUIPMENT | PROCESSING | 50% | — |
| REVAMPING | DOSING | 49% | 01/01/2024 |
| REVAMPING | FILTRATION | 39% | — |
| REVAMPING | MIXING | 45% | — |
| REVAMPING | PROCESSING | 50% | — |
| PORT | Tous DAS | 25% | — |

#### 6.5 Textes multilingues (traductions)

Toutes les chaînes de l'interface et des documents doivent être stockées en base, trilingues (EN / FR / CN) :

| Clé | Anglais | Français |
|---|---|---|
| `doc.price_list` | Price List | Liste de prix |
| `doc.cover_letter` | Cover Letter | Lettre d'introduction |
| `doc.special_terms` | Special Terms of Sales | Conditions particulières de vente |
| `doc.delivery_time` | Delivery Time | Délai de livraison |
| `doc.incoterm` | INCOTERM | INCOTERM |
| `doc.payment_terms` | Terms of Payment | Conditions de paiement |
| `doc.warranty` | Warranty | Garantie |
| `doc.validity` | Validity | Durée de validité |
| `doc.contacts` | Contacts | Coordonnées |
| `doc.customer_contacts` | Customer Contact List | Liste de contacts client |
| `doc.hasler_contacts` | HASLER France Contact List | Liste de contacts HASLER France |
| `doc.gtc` | General Terms & Conditions of Sale | Conditions générales de vente |
| `doc.gtc_intervention` | General Conditions of Intervention | Conditions générales d'intervention |
| `doc.budget_offer` | The following offer is a budget offer, NOT valid for order. | La presente offre est une offre budgetaire, NON-valable pour commande. |
| `doc.our_ref` | Our Reference: | Notre référence : |
| `doc.das.dosing` | Dosing system | Solution de dosage |
| `doc.das.filtration` | Filtration system | Solution de filtration |
| `doc.das.mixing` | Mixing system | Solution d'agitation |
| `doc.das.processing` | Kneading system | Solution de malaxage |
| `doc.field.customer` | Customer | Client |
| `doc.field.address` | Address | Adresse |
| `doc.field.city` | City | Ville |
| `doc.field.country` | Country | Pays |
| `doc.field.name` | Name | Nom |
| `doc.field.position` | Position | Fonction |
| `doc.payment.bank_transfer` | By bank transfer | Par virement bancaire |
| `doc.payment.advance` | At placing the order, upon receipt of the order confirmation… | A la commande au titre d'acompte… |
| `doc.payment.exw_ready` | 30 days net after invoice, issued at Ex Works readiness date | A la mise à disposition EXW, à 30 jours date de facture |
| `doc.delivery.note` | Please take into account additional time for delivery… | Prévoir un délai supplémentaire pour l'acheminement… |
| `doc.warranty.text` | The equipment must not be modified without prior consultation… | L'équipement ne peut être modifié sans accord préalable… |

---

### MODULE 7 — Règles métier critiques

**Équivalent feuille :** `Rules`

Ces règles doivent être appliquées dans l'interface et documentées dans une aide contextuelle :

#### 7.1 Règles de saisie

1. **Boîtes blanches (coûts)** = saisie AE obligatoire — représentatives de l'offre réelle
2. **Boîtes orange (prix de vente)** = saisie ASM uniquement
3. Chaque ligne équipement peut inclure ou non des heures d'ingénierie vendues (colonnes TECH, PUR, PM)
4. Seules les études spécifiques au design doivent être vendues → décision en Feasibility Review
5. Ajouter une note si estimation partielle (ex : "50% from previous order MS0450, 25% estimé, 25% consulté")

#### 7.2 Règles sur les Services

- Les lignes SERVICE (ligne 29 et suivantes dans le Budget) : **l'AE saisit le prix de vente**, aucune marge appliquée sur ces lignes (marge = 100% par définition)
- Turnover services = prix de vente direct

#### 7.3 Règles sur les Pièces de Rechange

- Les spare parts d'un projet nouveau équipement → rattachés à la marge EQUIPMENT
- Les spare parts d'un projet revamping → rattachés à la marge REVAMPING
- Spare parts achetés (purchased) : marge brute **45%** → Prix vente = Coût achat / 0,55
- Spare parts propriétaires : marge brute **70%** → Prix vente = Coût achat / 0,30
- Objectif futur : proposer listes standards de spare parts (1 an, 2 ans d'exploitation)

#### 7.4 Règles sur les Heures vendues

- Man-hours vendus → CA comptabilisé dans le Turnover de l'activité principale du projet
  - Projet NEW EQUIPMENT → CA heures dans Equipment Turnover
  - Projet REVAMPING → CA heures dans Revamping Turnover

#### 7.5 Règles sur le P&L Simplifié

- La première version du Simplified P&L existe uniquement si **Turnover > 15 000 €**
- Les révisions suivantes sont enregistrées dans "Budget Price Final Order" sans écraser le "1st Quotation"

#### 7.6 Règles d'affichage de la Price List (offre client)

- Toutes les lignes qu'on ne veut pas montrer dans l'offre → masquées (pas supprimées)
- Dans le SaaS : toggle "Visible dans l'offre" par ligne

---

## 4. Modèle de données (Schéma base de données)

### Tables principales

```sql
-- Projets / Affaires
projects (
  id UUID PK,
  offer_number VARCHAR(20),   -- ex: "725116"
  commercial_version INT,
  technical_version INT,
  customer_name VARCHAR(200),
  project_description TEXT,
  country VARCHAR(100),
  market VARCHAR(100),         -- CCH, MMF, ENV, DEV...
  das VARCHAR(20),             -- DOSING, FILTRATION, MIXING, PROCESSING
  tac VARCHAR(20),             -- EQUIPMENT, REVAMPING...
  asm_id UUID FK → users,
  tender_engineer_id UUID FK → users,
  cegid_order VARCHAR(50),
  status VARCHAR(20),          -- draft, 1st_quotation, final_order, won, lost
  incoterm VARCHAR(20),
  incoterm_location VARCHAR(200),
  delivery_weeks INT,
  delivery_note TEXT,
  warranty_option VARCHAR(200),
  offer_language VARCHAR(10),  -- EN, FR, CN
  is_budget_proposal BOOLEAN DEFAULT FALSE,
  commission_rate DECIMAL(5,4),
  financial_cost_rate DECIMAL(5,4),
  created_at TIMESTAMP,
  updated_at TIMESTAMP
)

-- Lignes de budget (Budget Price)
budget_lines (
  id UUID PK,
  project_id UUID FK → projects,
  phase VARCHAR(20),           -- 1st_quotation, final_order, end_figure
  position INT,
  equipment_type VARCHAR(20),  -- EQUIPMENT, PACKAGING, TRANSPORT, SERVICE
  meca_elec VARCHAR(10),       -- MECA, ELEC
  base_or_option VARCHAR(10),  -- BASE, OPTIONS
  description TEXT,
  reference VARCHAR(100),
  quantity INT DEFAULT 1,
  eq_unit_cost DECIMAL(15,2),
  nb_hours_tech INT DEFAULT 0,
  nb_hours_pur INT DEFAULT 0,
  nb_hours_pm INT DEFAULT 0,
  nb_hours_workshop INT DEFAULT 0,
  eq_unit_selling_price DECIMAL(15,2),
  hours_selling_price DECIMAL(15,2),
  visible_in_offer BOOLEAN DEFAULT TRUE,
  note TEXT,
  sort_order INT,
  -- Champs calculés (dénormalisés pour performance)
  total_eq_cost DECIMAL(15,2),
  total_hours_cost DECIMAL(15,2),
  total_cost DECIMAL(15,2),
  total_eq_selling DECIMAL(15,2),
  total_selling DECIMAL(15,2),
  gross_margin DECIMAL(15,2),
  gross_margin_pct DECIMAL(5,4),
  created_at TIMESTAMP,
  updated_at TIMESTAMP
)

-- Man-hours directs (Simplified P&L)
man_hours (
  id UUID PK,
  project_id UUID FK → projects,
  phase VARCHAR(20),
  department VARCHAR(30),      -- technical, mechanical, electrical, purchasing, pm, workshop_assembling, workshop_packaging, service
  hours_qty INT,
  hourly_rate DECIMAL(8,2),
  total_cost DECIMAL(12,2)
)

-- Contacts client par projet
customer_contacts (
  id UUID PK,
  project_id UUID FK → projects,
  company_name VARCHAR(200),
  address TEXT,
  city VARCHAR(100),
  country VARCHAR(100),
  telephone VARCHAR(50),
  website VARCHAR(200),
  department VARCHAR(50),     -- purchase, technical
  contact_name VARCHAR(100),
  contact_position VARCHAR(100),
  contact_email VARCHAR(200)
)

-- Conditions de paiement par projet
payment_terms (
  id UUID PK,
  project_id UUID FK → projects,
  installment_number INT,
  payment_percentage DECIMAL(5,4),
  payment_term TEXT,
  payment_mode VARCHAR(100),
  credit_days INT
)

-- Utilisateurs
users (
  id UUID PK,
  code VARCHAR(10),           -- CPIS, ANGO...
  first_name VARCHAR(100),
  last_name VARCHAR(100),
  email VARCHAR(200),
  role VARCHAR(50),           -- admin, sales_director, asm, tender_engineer, bdm
  is_active BOOLEAN,
  created_at TIMESTAMP
)

-- Taux horaires (historisés)
hourly_rates (
  id UUID PK,
  department VARCHAR(30),
  rate DECIMAL(8,2),
  effective_from DATE,
  effective_to DATE
)

-- Budget Target
budget_targets (
  id UUID PK,
  tac_type VARCHAR(20),       -- EQUIPMENT, REVAMPING, PORT
  das VARCHAR(20),
  margin_rate_target DECIMAL(5,4),
  effective_from DATE
)

-- Traductions interface et documents
translations (
  key VARCHAR(100),
  lang VARCHAR(5),            -- EN, FR, CN
  value TEXT,
  PRIMARY KEY (key, lang)
)
```

---

## 5. Interfaces utilisateur — wireframes textuels

### 5.1 Dashboard principal

```
┌─────────────────────────────────────────────────────────────┐
│ HASLER Offer Studio                    [Nouvel projet +]    │
├─────────────────────────────────────────────────────────────┤
│ Filtres: [DAS ▾] [Marché ▾] [ASM ▾] [Statut ▾] [Période ▾]│
├─────┬──────────┬─────────────────┬───────┬──────┬────┬─────┤
│ N°  │ Client   │ Description     │ DAS   │ ASM  │ v  │ GM% │
├─────┼──────────┼─────────────────┼───────┼──────┼────┼─────┤
│725116│St Gobain│Replacement...   │FILTR. │CPIS  │ 6  │47,9%│ ← badge vert
│725200│Solvay   │Soda Ash Filter  │FILTR. │GFOR  │ 2  │35,2%│ ← badge orange
│725050│Lafarge  │Dosing System    │DOSING │BROU  │ 1  │41%  │ ← badge rouge
└─────┴──────────┴─────────────────┴───────┴──────┴────┴─────┘
```

### 5.2 Fiche projet — Navigation par onglets

```
┌── 725116 — St Gobain ────────────────────────────────────────┐
│ [Infos] [Budget] [P&L] [Documents] [Contacts] [Historique]  │
└──────────────────────────────────────────────────────────────┘
```

### 5.3 Onglet Budget — Grille de saisie

```
Afficher: [1st Quotation ◉] [Final Order ○]
                                                    [+ Ajouter ligne]
┌──┬────────┬──────┬───────┬────────────────┬──────┬──────────┬──────────┬──────┬──────┐
│Pos│Type    │Méca  │Base/Opt│Description    │ Qté  │Coût unit.│Prix vente│GM €  │GM %  │
├──┼────────┼──────┼───────┼────────────────┼──────┼──────────┼──────────┼──────┼──────┤
│ 1│EQUIP.  │MECA  │BASE   │HVBF 6B10 (6m²)│  1   │137 583 ✏️│264 160 ✏️│126 576│47,9%│
│ 1│EQUIP.  │MECA  │BASE   │Manifold        │  1   │  4 916  │  9 439  │  4 523│47,9%│
│ 1│EQUIP.  │MECA  │BASE   │Local Ctrl Panel│  1   │  3 975  │  7 632  │  3 657│47,9%│
│...│       │      │       │                │      │          │          │      │      │
├──┼────────┼──────┼───────┼────────────────┼──────┼──────────┼──────────┼──────┼──────┤
│  │OPTIONS │      │       │                │      │          │          │      │      │
│ 1│EQUIP.  │MECA  │OPT    │Vacuum Pump     │  1   │ 35 990  │ 69 101  │ 33 111│47,9%│
├──┼────────┼──────┼───────┼────────────────┼──────┼──────────┼──────────┼──────┼──────┤
│  │PACKAGING│     │       │                │      │          │          │      │      │
│  │TRANSP.  │     │       │DAP Gelsa Truck │  1   │  2 100  │  2 800  │    700│25%  │
├──┼────────┼──────┼───────┼────────────────┼──────┼──────────┼──────────┼──────┼──────┤
│  │SERVICE │      │       │                │      │          │Prix vente│      │100% │
│  │SERVICE │      │       │Erection 3 weeks│  1   │  —      │ 29 026  │ 29 026│100% │
└──┴────────┴──────┴───────┴────────────────┴──────┴──────────┴──────────┴──────┴──────┘
TOTAL CALCULÉ:  Coût: 260 069 €  |  Prix vente: 548 882 €  |  GM1: 288 813 € (52,6%)
Cible FILTRATION EQUIPMENT: 37%  ✅ Objectif atteint (+15,6 pts)
```

### 5.4 Onglet P&L Simplifié

```
                    1st Quotation    Final Order    End Figure
CA TOTAL:               —           546 083 €          —
  Equipment:            —           495 300 €
  Service:              —            50 782 €

COÛTS DIRECTS:          —           257 969 €
  Méca Third Party:     —           250 469 €
  Électrique:           —             7 500 €

GM1:                    —           288 113 €   [████████████░░░░ 52,7%]
Cible: 37%              —                       ✅ +15,7 pts

MAN-HOURS DIRECTS:      —               0 €
  Tech (210h × 50€/h)   10 500 €        0 €
  Purchasing (120h)       6 000 €        0 €
  PM (180h)              11 700 €        0 €
  Workshop (60h)          2 400 €        0 €
  Service (200h)         10 000 €        0 €
TOTAL MAN-HOURS:         40 600 €        0 €

COMMISSIONS:            —                0 €  (0,0% CA)
FRAIS BANCAIRES:        —                0 €
```

### 5.5 Onglet Documents — Générateur

```
┌─────────────────────────────────────────────────────────────┐
│ Générer le dossier d'offre                                  │
│                                                             │
│ Langue: [English ▾]     Version: Commercial v6             │
│                                                             │
│ Sections à inclure:                                         │
│ ✅ Page de couverture          ✅ Liste de prix — Base      │
│ ✅ Lettre d'introduction       ✅ Liste de prix — Options   │
│ ✅ Conditions Particulières    ✅ Services / Spare Parts    │
│ ✅ Contacts                    ☐ Livrables ingénierie      │
│ ☐ CGV                         ☐ Conditions intervention   │
│                                                             │
│ Mention Offre budgétaire: ☐ Oui                            │
│                                                             │
│            [Aperçu PDF]    [Générer & Télécharger]         │
└─────────────────────────────────────────────────────────────┘
```

---

## 6. Spécifications fonctionnelles détaillées

### 6.1 Calculs automatiques (logique côté serveur)

```typescript
// Calcul d'une ligne de budget
function computeBudgetLine(line: BudgetLine, rates: HourlyRates): ComputedLine {
  const totalHoursCost =
    line.nbHoursTech * rates.technical +
    line.nbHoursPur * rates.purchasing +
    line.nbHoursPm * rates.pm +
    line.nbHoursWorkshop * rates.workshop;
  
  const totalEqCost = line.quantity * line.eqUnitCost;
  const totalCost = totalEqCost + totalHoursCost;
  
  const totalEqSelling = line.quantity * line.eqUnitSellingPrice;
  const totalSelling = totalEqSelling + line.hoursSellingPrice;
  
  const grossMargin = totalSelling - totalCost; // pour EQ
  // Pour SERVICE: grossMargin = totalSelling (pas de coût matière)
  const grossMarginPct = totalSelling > 0 ? grossMargin / totalSelling : null;
  
  return { totalHoursCost, totalEqCost, totalCost, totalEqSelling, totalSelling, grossMargin, grossMarginPct };
}

// Prix de vente suggéré depuis coût (règle spare parts)
function suggestSellingPrice(cost: number, type: 'purchased' | 'proprietary'): number {
  if (type === 'purchased') return cost / 0.55;    // marge 45%
  if (type === 'proprietary') return cost / 0.30;  // marge 70%
  return cost;
}

// Prix de vente suggéré depuis cible de marge
function suggestPriceFromTarget(cost: number, targetMarginRate: number): number {
  return cost / (1 - targetMarginRate);
}
```

### 6.2 Numérotation des offres

Format : `[Numéro projet]-[Version]` — ex: `725116-6`
- Offre commerciale : `725116-6_COMM`
- Offre technique liée : `725116-6_TECH`

### 6.3 Versionnement des projets

- Chaque modification du Budget enregistre une version (timestamp + auteur)
- La version "1st Quotation" est figée à la 1ère validation
- Les révisions suivantes n'écrasent pas la 1st Quotation

### 6.4 Notifications et alertes

| Déclencheur | Alerte |
|---|---|
| GM1% < Cible DAS − 10% | ⚠️ "Marge insuffisante — vérifier avec ASM" |
| Ligne avec marge négative | 🔴 Badge rouge sur la ligne |
| Offre non renseignée depuis > 30j | 📧 Rappel au Tender Engineer |
| Turnover < 15 000 € | ℹ️ "P&L simplifié non requis à ce stade" |

### 6.5 Export et génération PDF

**Format du PDF offre client :**
- Format A4 portrait
- En-tête : Logo HASLER + numéro offre + date
- Police : Arial ou équivalent, corps 10pt
- Tableaux : bordures fines, alternance blanc/gris clair
- Devise : € HT (excl. VAT)
- Pied de page : HASLER France SAS | 496 Rue Louis Breguet, 38780 Pont-Évêque | +33 4 74 16 11 50 | www.hasler-gp.com

**Données HASLER France (fixes) :**
- Adresse : 496 Rue Louis Breguet, 38780 Pont-Évêque, France
- Téléphone : +33 4 74 16 11 50
- Site web : www.hasler-gp.com
- Email service : service@hasler.group
- SIREN : 514 743 038 - RCS Vienne France

### 6.6 Import depuis Excel (migration)

Prévoir une fonction d'import de fichiers `.xlsm` existants pour migrer les projets historiques :
- Lecture des feuilles `Budget Price Final order` et `Simplified P&L`
- Mapping automatique des champs
- Rapport d'erreurs / champs non mappés

---

## 7. Priorités de développement (phases)

### Phase 1 — MVP (core)
1. Auth Supabase + gestion utilisateurs + rôles
2. Création / liste des projets avec champs de base
3. Grille de budget (lignes, coûts, prix de vente, calculs temps réel)
4. P&L Simplifié avec KPIs et comparaison cible
5. Configuration (taux horaires, budget target, utilisateurs)

### Phase 2 — Génération documents
6. Générateur de listes de prix client (Quotation 1/2/3)
7. Génération PDF offre complète (FR + EN)
8. Conditions particulières de vente paramétrables

### Phase 3 — Analytics & avancé
9. Dashboard analytique global (pipeline, marges par DAS, par ASM)
10. Alertes et notifications
11. Historique / versionnement des offres
12. Import Excel historique
13. Export CSV / Excel
14. Support chinois (CN)

---

## 8. Exemple de projet de référence (à utiliser comme données de test)

**Projet : 725116 — Rev 6**
- **Client** : St Gobain
- **Description** : Replacement of Gelsa Filter — 1x HVBF 6B10
- **Pays** : Spain
- **Marché** : CCH — other
- **DAS** : FILTRATION
- **TAC** : EQUIPMENT
- **ASM** : Cosimo Piscopiello (CPIS)
- **T eng.** : Ahou N'gotta (ANGO)
- **Incoterm** : DAP Gelsa (Spain)
- **Délai** : 45 weeks EXW, excl. 3 weeks summer
- **Garantie** : 24 months after commissioning, latest 30 months after delivery
- **Langue** : English

**Budget Final Order (12 lignes équipement + 3 services) :**

| # | Description | Type | Méca | Base/Opt | Coût | Prix vente | GM% |
|---|---|---|---|---|---|---|---|
| 1 | Horizontal Vacuum Belt Filter 6B10 (6m²) | EQ | MECA | BASE | 137 583 € | 264 160 € | 47,9% |
| 1 | Manifold | EQ | MECA | BASE | 4 916 € | 9 439 € | 47,9% |
| 1 | Local Control Panel (Maintenance) | EQ | MECA | BASE | 3 975 € | 7 632 € | 47,9% |
| 1 | Instrumentation & Valves | EQ | MECA | BASE | 5 900 € | 11 328 € | 47,9% |
| 1 | Fume Hood | EQ | MECA | BASE | 8 123 € | 15 596 € | 47,9% |
| 1 | Drip Pan | EQ | MECA | BASE | 9 578 € | 18 390 € | 47,9% |
| 1 | Filtrate Receiver 1 | EQ | MECA | BASE | 3 878 € | 7 445 € | 47,9% |
| 1 | Filtrate Pump 1 | EQ | MECA | BASE | 8 922 € | 17 131 € | 47,9% |
| 1 | Cloth Ultrasonic welding machine | EQ | ELEC | BASE | 7 500 € | 14 400 € | 47,9% |
| 1 | Decrystallization solution | EQ | MECA | BASE | 2 187 € | 4 199 € | 47,9% |
| 1 | High Pressure pump & Ramp for cloth washing | EQ | MECA | BASE | 12 167 € | 23 361 € | 47,9% |
| 1 | Vacuum Pump + recirculation system | EQ | MECA | OPTIONS | 35 990 € | 69 101 € | 47,9% |
| 1 | Cooling Unit | EQ | MECA | OPTIONS | 17 250 € | 33 120 € | 47,9% |
| — | DAP Gelsa — Truck transport | TRANSP | — | — | 2 100 € | 2 800 € | 25% |
| — | Erection for 3 weeks | SERVICE | — | — | — | 29 026 € | 100% |
| — | FAT & Cold Commissioning 1 week | SERVICE | — | — | — | 10 878 € | 100% |
| — | Hot Commissioning 1 week | SERVICE | — | — | — | 10 878 € | 100% |

**Totaux :**
- CA Total : 548 882 €
- CA Equipment : 495 300 €
- CA Service : 50 782 €
- Coûts directs : 257 969 €
- **GM1 : 288 813 € (52,7%)**
- Cible FILTRATION EQUIPMENT : 37% → **+15,7 pts au-dessus de la cible** ✅

---

## 9. Points d'attention pour Lovable

1. **Calculs temps réel** : chaque modification d'une cellule du budget doit immédiatement recalculer le total et le P&L simplifié → utiliser React Query avec mutations optimistes

2. **Deux niveaux d'édition** : une même interface mais avec des champs différents selon le rôle (AE = coûts visibles et éditables, ASM = prix de vente éditables, les deux en lecture croisée)

3. **Marge SERVICE toujours 100%** : les lignes de type SERVICE n'ont pas de coût direct dans le calcul de marge (le coût est des heures internes, pas un achat externe)

4. **Masquage de lignes** : le toggle "visible dans l'offre" ne supprime pas la ligne du budget — elle reste dans les calculs mais n'apparaît pas dans le PDF client

5. **Nombre de lignes** : le budget peut avoir jusqu'à 360+ lignes (feuille Budget = 361 lignes) → la grille doit être performante (virtualisation)

6. **Multilingue document** : les textes longs (garantie, délai, conditions de paiement) existent en EN et FR dans la feuille Configuration — ils doivent être sélectionnés automatiquement selon la langue de l'offre

7. **Historisation stricte** : jamais écraser la 1st Quotation avec les révisions Final Order — deux phases distinctes en base

8. **Précision monétaire** : tous les montants en centimes d'euros (DECIMAL 15,2) — les arrondis doivent être cohérents avec Excel

---

*Document généré depuis l'analyse complète de `725116v6_P-L-Rev6.xlsm` (18 feuilles, HASLER Group)*
*Version : 1.0 — Avril 2026*
