# Extrafields et formulaires dynamiques > Les extrafields Dolibarr permettent d'ajouter des champs personnalisés aux objets métier. SmartMaker offre un système complet pour les exposer à l'application React avec génération automatique de formulaires. ## Vue d'ensemble Le système extrafields SmartMaker fonctionne en trois étapes : ``` 1. Admin Dolibarr : Configure quels extrafields exposer (RO/RW) ↓ 2. Mapper PHP : Lit la configuration, expose les métadonnées ↓ 3. React : Génère dynamiquement les formulaires ``` ## 1. Configuration admin ### Page de configuration SmartBoot génère une page d'administration `admin/smartmaker.php` qui permet de configurer les extrafields exposés à l'application. ```php // Définir les objets Dolibarr à configurer $elementsToConfig = array( 'fichinter' => 'Interventions', 'societe' => 'Tiers', 'projet_task' => 'Tâches', ); ``` Cette page affiche tous les extrafields de chaque objet avec deux colonnes : ^ Option ^ Description ^ | **RO** (Read-Only) | Le champ est visible dans l'application mais non modifiable | | **RW** (Read-Write) | Le champ est visible ET modifiable | ### Stockage de la configuration La configuration est stockée dans les constantes Dolibarr : ``` MONMODULE_SMARTMAKER_EXTRAFIELDS_RO = "champ1,champ2,champ3" MONMODULE_SMARTMAKER_EXTRAFIELDS_RW = "champ4,champ5" ``` ## 2. Mapper PHP (dmGenericObject) ### Structure de base Le mapper hérite de `dmBase` et utilise `dmTrait` pour la gestion des extrafields : ```php 'id', 'ref' => 'ref', 'description' => 'description', 'fk_statut' => 'status', ]; // Champs modifiables via API protected $writableFields = []; } ``` ### Chargement automatique des extrafields Le constructeur charge la configuration depuis Dolibarr : ```php public function __construct() { global $db; $this->db = $db; // Extrafields en lecture seule $extRO = getDolGlobalString('MONMODULE_SMARTMAKER_EXTRAFIELDS_RO'); if (!empty($extRO)) { foreach (explode(',', $extRO) as $field) { $field = trim($field); if (!empty($field)) { $key = 'options_' . $field; $this->listOfPublishedFields[$key] = $key; } } } // Extrafields en lecture-écriture $extRW = getDolGlobalString('MONMODULE_SMARTMAKER_EXTRAFIELDS_RW'); if (!empty($extRW)) { foreach (explode(',', $extRW) as $field) { $field = trim($field); if (!empty($field)) { $key = 'options_' . $field; $this->listOfPublishedFields[$key] = $key; $this->writableFields[] = $key; } } } $this->boot(); } ``` ### Méthode objectDesc() La méthode `objectDesc()` (fournie par `dmTrait`) retourne les métadonnées des champs pour le frontend : ```php // Dans le controller $mapping = new dmItem(); $config = $mapping->objectDesc(); // Retourne un tableau avec les infos de chaque champ : // [ // 'options_niveau' => [ // 'type' => 'select', // 'label' => 'Niveau', // 'required' => true, // 'options' => ['1' => 'Facile', '2' => 'Moyen', '3' => 'Difficile'], // 'writable' => true, // ], // ... // ] ``` ## 3. Controller : Exposer la configuration Le controller doit retourner la configuration au frontend : ```php class ItemController { private $mapping; public function __construct() { $this->mapping = new dmItem(); } // GET /items (liste + config) public function index($arr = null) { // ... charger les items ... return [[ 'statusCode' => 200, 'items' => $items, 'config' => $this->mapping->objectDesc(), // Métadonnées des champs ], 200]; } // GET /items/123 (détail + config) public function show($arr = null) { $id = $arr['id'] ?? 0; // ... charger l'item ... return [[ 'statusCode' => 200, 'item' => $this->mapping->map($dolibarrObject), 'config' => $this->mapping->objectDesc(), ], 200]; } } ``` ## 4. Frontend : Formulaires dynamiques ### Stockage de la configuration Stocker la configuration reçue de l'API dans Redux ou le state local : ```jsx // Dans le composant ou via Redux const [config, setConfig] = useState({}); useEffect(() => { api.private.get('items') .then(response => { setConfig(response.config || {}); // ... traiter les items ... }); }, []); ``` ### FormComponentsMap SmartCommon fournit `FormComponentsMap` qui mappe les types Dolibarr vers les composants React : ```jsx import { FormComponentsMap } from "@cap-rel/smartcommon"; // FormComponentsMap retourne le composant approprié selon le type : // 'varchar' → Input // 'text' → Textarea // 'int' → Input type="number" // 'double' → Input type="number" step="0.01" // 'date' → DatePicker // 'datetime' → DateTimePicker // 'boolean' → Checkbox // 'select' → Select // 'sellist' → Select (avec options depuis la DB) // 'radio' → RadioGroup // 'checkbox' → CheckboxGroup // 'link' → SearchSelect (lien vers autre objet) ``` ### Génération dynamique du formulaire ```jsx const DynamicForm = ({ config, values, onChange }) => { return (