Module Catalogue main-d'oeuvre¶
Objectif¶
Le module Catalogue main-d'oeuvre separe les prestations de main-d'oeuvre du catalogue produit standard.
Il couvre :
- un type de catalogue dedie
main_oeuvre; - une navigation de premier niveau dans le catalogue ;
- des familles et categories metier ;
- des prestations sans fournisseur ni image obligatoire ;
- des options configurables ;
- le choix entre options multipliees par quantite et options forfaitaires ;
- l'utilisation dans les devis, factures et avoirs ;
- le rendu PDF correct des lignes et options.
Emplacement du code¶
Fichiers principaux :
app/controllers/CatalogueController.php
app/models/CatalogueModel.php
app/models/CatalogueTaxonomyModel.php
app/views/catalogue.php
app/views/layout/catalogue.php
app/views/partials/catalogue.php
app/views/partials/modals/create-product-form-shared.php
app/views/partials/modals/modifier-produit-pour-catalogue.php
app/views/partials/modals/choisir-produit-pour-devis.php
app/views/partials/modals/price-simulator-modal.php
app/helpers/pdfDocumentGenerator.php
app/models/BaseDocumentModel.php
Migrations :
Tests de garde identifies :
tests/catalogue_main_oeuvre_top_tab_test.php
tests/catalogue_toolbar_layout_test.php
tests/main_oeuvre_option_quantity_multiplier_test.php
Vue d'ensemble architecture¶
Catalogue UI
|
| catalogue_kind=main_oeuvre
v
CatalogueController
|
v
CatalogueModel
- catalogue
- catalogue_options
- catalogue_taxonomy_families
- catalogue_taxonomy_categories
|
v
Documents
- devis
- factures
- avoirs
- PDF
Le point cle est catalogue_kind. Une ligne catalogue peut etre :
standard: produit/prestation du catalogue classique ;main_oeuvre: prestation de main-d'oeuvre dediee.
Schema de donnees¶
Catalogue¶
Migration :
app/bd/catalogue-main-oeuvre.sql
Ajouts sur catalogue :
catalogue_kind ENUM('standard','main_oeuvre') NOT NULL DEFAULT 'standard'
idx_catalogue_kind
taxonomy_family_id
taxonomy_category_id
idx_catalogue_taxonomy
catalogue_kind isole les prestations main-d'oeuvre sans creer une table separee.
Options¶
Ajouts sur les options :
catalogue_options.image_option VARCHAR(500) NULL DEFAULT NULL
catalogue_options.multiply_with_quantity TINYINT(1) NOT NULL DEFAULT 1
devis_ligne_options.multiply_with_quantity TINYINT(1) NOT NULL DEFAULT 1
facture_ligne_options.multiply_with_quantity TINYINT(1) NOT NULL DEFAULT 1
multiply_with_quantity est le flag critique :
1: l'option suit la quantite de la ligne ;0: l'option est forfaitaire et ne doit pas etre remultipliee par la quantite.
Le defaut 1 conserve le comportement historique.
Taxonomies¶
Migration :
app/bd/catalogue-taxonomies.sql
Tables :
Colonnes structurantes :
societe_id;scope:main_oeuvreououvrage;name;sort_order;active.
Contraintes importantes :
- unicite famille :
societe_id,scope,name; - unicite categorie :
family_id,name; - suppression cascade des categories quand une famille est supprimee.
Ces taxonomies sont partagees par la logique main-d'oeuvre et ouvrages, mais chaque ligne porte un scope.
Controleur¶
Fichier :
app/controllers/CatalogueController.php
Liste¶
Le controleur lit catalogue_kind depuis la query string.
Regle de normalisation :
Cette regle evite que le catalogue standard affiche la main-d'oeuvre par defaut.
Le controleur fournit aussi les taxonomies main-d'oeuvre a la vue :
Creation¶
Endpoint logique :
Quand catalogue_kind = main_oeuvre, le controleur force :
type = prestation;marque = null;reference_fournisseur = null;fournisseur_id = null;recherche_fournisseur = '';- image ignoree meme si un fichier est envoye.
Les champs obligatoires restent :
Le controleur decode aussi options si le payload en contient. Les options vides sont filtrees selon leur nom.
Edition¶
Endpoint logique :
L'edition reprend la meme normalisation catalogue_kind. Si le produit est une main-d'oeuvre, les champs fournisseur/marque/image sont neutralises et les options peuvent etre remplacees.
Taxonomies¶
Endpoints logique :
Ces actions deleguent a CatalogueTaxonomyModel.
Modele catalogue¶
Fichier :
app/models/CatalogueModel.php
Filtrage¶
getPaginatedCatalogue() accepte :
Les filtres famille/categorie ne s'appliquent que pour catalogue_kind = main_oeuvre.
Le modele joint :
en filtrant explicitement scope = 'main_oeuvre'.
Lecture d'une fiche¶
getById($id, true) peut charger :
- la ligne catalogue ;
- les taxonomies ;
- les options ;
options_count.
Les options lues contiennent :
id
catalogue_id
nom
description
signe
unite
valeur
obligatoire
active
image_option
multiply_with_quantity
Remplacement des options¶
La methode interne de remplacement supprime les options existantes du catalogue puis insere les nouvelles.
Regles appliquees a chaque option :
nomvide : option ignoree ;signelimite aplusoumoins;unitelimitee aeurooupourcent;valeurforcee a un nombre positif ;obligatoireconverti en booleen ;activeconverti en booleen ;multiply_with_quantityconserve le defaut historique si absent.
Taxonomy model¶
Fichier :
app/models/CatalogueTaxonomyModel.php
Responsabilites :
- lister familles et categories actives par
scope; - creer/reactiver une famille ;
- creer/reactiver une categorie ;
- normaliser un couple famille/categorie ;
- verifier que la famille et la categorie appartiennent a la societe active.
Regle de scope :
normalizePair() retourne null pour la famille et la categorie si la famille est invalide. Si la famille est valide mais la categorie invalide, seule la categorie est remise a null.
Point important : le modele utilise $_SESSION['active_societe_id']. Les tests unitaires purs doivent donc initialiser la session ou passer par des tests de presence de code.
UI et navigation¶
La main-d'oeuvre est promue en onglet principal du catalogue.
Test de garde :
tests/catalogue_main_oeuvre_top_tab_test.php
Ce test verifie que :
layout/catalogue.phpcontientid="main-oeuvre-btn";- l'onglet pointe vers
catalogue_kind=main_oeuvre; - l'onglet main-d'oeuvre est place avant Ouvrages ;
- la main-d'oeuvre n'apparait plus comme sous-onglet du catalogue standard ;
- une ancienne URL
Prestationsanscatalogue_kindgarde un comportement compatible.
La toolbar catalogue a aussi ete simplifiee.
Test de garde :
tests/catalogue_toolbar_layout_test.php
Il verifie que les vues catalogue, ouvrages et bibliotheques utilisent une structure :
catalogue-toolbar
catalogue-toolbar-title-row
catalogue-toolbar-search-row
catalogue-toolbar-actions-row
Interaction avec devis, factures et PDF¶
La main-d'oeuvre est selectionnable depuis les modales de document via :
choisir-produit-pour-devis.php;price-simulator-modal.php.
Le simulateur doit distinguer :
- les options unitaires ;
- les options forfaitaires.
Test de garde :
tests/main_oeuvre_option_quantity_multiplier_test.php
Ce test verifie notamment que :
- la migration ajoute
multiply_with_quantity; - le modele lit et sauvegarde ce flag ;
- les formulaires creation/edition exposent le switch ;
- le simulateur transmet
multiply_with_quantityaux lignes document ; - le PDF ne remultiplie pas une option forfaitaire ;
BaseDocumentModelpersiste le flag dans les options de ligne.
Point critique : si une option est forfaitaire, le prix unitaire transmis au document doit integrer correctement le total de ligne sans provoquer une double multiplication dans le PDF.
Invariants de reprise¶
catalogue_kindest la separation fonctionnelle centrale. Ne pas se baser uniquement surtype = prestation.- La main-d'oeuvre ne doit pas conserver de fournisseur, marque, reference fournisseur ou image produit.
- Les taxonomies doivent toujours etre verifiees par
societe_idetscope. - Une categorie ne doit etre acceptee que si elle appartient a la famille selectionnee.
multiply_with_quantitydoit etre transporte du catalogue vers les lignes document puis jusqu'au PDF.- Les anciennes donnees doivent rester compatibles grace aux valeurs par defaut
standardetmultiply_with_quantity = 1.
Points d'attention pour reprise¶
- La creation et l'edition remplacent les options en bloc. Si un futur besoin demande l'historique option par option, il faudra changer ce contrat.
- Les migrations utilisent
ADD COLUMN IF NOT EXISTSdanscatalogue-taxonomies.sql, mais pas partout danscatalogue-main-oeuvre.sql. Verifier l'idempotence avant execution sur une base deja partiellement migree. - Les tests identifies sont surtout des tests de presence de code et d'invariants structurels. Ils protegent les regressions grossieres, mais ne remplacent pas un test bout-en-bout avec base SQL.
- Les fonctions de taxonomie dependent de la societe active en session. Une reprise en CLI ou API devra fournir ce contexte explicitement.
- Le scope
ouvragepartage les tables de taxonomie. Une modification de schema pour la main-d'oeuvre peut donc toucher les ouvrages.