Ce module permet d'exporter les données d'un client existant vers un fichier XLSX, puis de les importer pour créer un nouveau compte client de démonstration.
Exporte toutes les données d'un client vers un fichier XLSX.
php artisan demo:export {source_idc} [--output=chemin]
Arguments:
| Argument | Description |
|----------|-------------|
| source_idc | ID du customer source à exporter |
Options:
| Option | Description |
|--------|-------------|
| --output | Chemin du fichier de sortie (défaut: storage/app/exports/demo_YYYYMMDD_HHMMSS.xlsx) |
Exemple:
# Exporter le client 999
php artisan demo:export 999
# Exporter vers un fichier spécifique
php artisan demo:export 999 --output=exports/template_hopital.xlsx
Importe les données depuis un fichier XLSX pour créer un nouveau client.
php artisan demo:import {file} [options]
Arguments:
| Argument | Description |
|----------|-------------|
| file | Chemin vers le fichier XLSX à importer |
Options:
| Option | Description |
|--------|-------------|
| --target-idc | ID du customer cible (requis pour import réel) |
| --target-name | Nom du customer cible (requis pour import réel) |
| --dry-run | Prévisualiser sans insérer les données |
| --date-offset | Décalage de dates en jours (défaut: auto) |
| --skip-validation | Ignorer la validation du fichier |
| --force | Forcer l'import même avec des avertissements |
Exemples:
# Prévisualisation (dry-run)
php artisan demo:import storage/app/exports/demo.xlsx --dry-run
# Import réel
php artisan demo:import storage/app/exports/demo.xlsx --target-idc=888 --target-name="Hôpital Demo"
# Import avec décalage de dates personnalisé (30 jours)
php artisan demo:import storage/app/exports/demo.xlsx --target-idc=888 --target-name="Demo" --date-offset=30
# Forcer l'import malgré les avertissements
php artisan demo:import storage/app/exports/demo.xlsx --target-idc=888 --target-name="Demo" --force
php artisan demo:hospital {idc} {name} [options]
php artisan demo:mairie {idc} {name} [options]
php artisan demo:stinglay {idc} {name} [options]
Options:
| Option | Description |
|--------|-------------|
| --reset | Purge toutes les données de l'idc avant import |
| --merge | Fusionne le template avec l'instance existante (mode idempotent) |
| --dry-run | Simule l'import sans rien écrire en DB |
| --force-restore | Ignore les tombstones et recrée les lignes seed supprimées par le PO (nécessite --merge) |
Exemples:
# Créer ou réinitialiser
php artisan demo:hospital 985 "Hôpital Providence Sud" --reset
# Mettre à jour un compte existant (merge idempotent)
php artisan demo:hospital 985 "Hôpital Providence Sud" --merge
# Merge en ignorant les suppressions PO (force-restore)
php artisan demo:hospital 985 "Hôpital Providence Sud" --merge --force-restore
# Prévisualiser un merge sans rien écrire
php artisan demo:hospital 985 "Hôpital Providence Sud" --merge --dry-run
--merge)Le mode merge permet de remettre à jour un compte de démonstration existant sans écraser les modifications apportées par le PO ou l'équipe commerciale.
Trois stratégies coexistent selon le type de données :
Pour les tables avec des colonnes SEED (données template) et des colonnes FREE (données PO). Le merge met à jour uniquement les colonnes SEED en préservant les colonnes FREE.
Pour les tables dont les données ne peuvent pas être réconciliées ligne par ligne (événements, interventions, équipements, tâches, projets...).
Comportement : delete ciblé des lignes seed (via demo_seed_map) + re-insert complet à chaque merge. Les lignes créées par le PO ne sont jamais touchées.
Tables concernées : cyber_ev, customer_event, dsi_hw, dsi_lic, _com_interv, _com_contr, equipment_types, crm_aff, cust_suivi, dsi_hw_users, project_step, project_news, project_meeting, project_backlog, equipments, project_kpival, _com_task, _com_livrable, equipment_counters, project_crit, risk_mesure, risk_item, project_matrice, project_for
Pour les tables où la présence de données PO active indique une appropriation métier complète du module.
Comportement : si le tenant a des lignes actives (hors dtdel), les données seed sont entièrement ignorées pour cette table.
Tables concernées : tickets, crm_miss
Un tombstone est une ligne seed supprimée par le PO (hard delete ou soft delete dtdel). Le système détecte ces suppressions avant chaque merge et les enregistre dans demo_seed_map avec deleted_by_po=1.
Comportement par défaut (sans --force-restore) :
Comportement avec --force-restore :
Note :
--force-restorene fonctionne qu'avec--merge. Le SkipIfExistsMergeStrategy n'est pas affecté par--force-restore(protection des données PO actives).
_configPremier onglet obligatoire contenant les métadonnées:
| Clé | Valeur | Description |
|---|---|---|
version |
1.0 |
Version du format |
source_idc |
999 |
ID du client source |
export_date |
2026-01-13 10:30:00 |
Date d'export |
target_idc |
(vide) | Rempli à l'import |
target_name |
(vide) | Rempli à l'import |
Chaque table a son propre onglet avec:
PK, FK:table.col, DATE, R=requis, O=optionnel)Les IDs sont remplacés par des identifiants temporaires au format:
TEMP_{TABLE}_{NNNN}
Exemples:
TEMP_CUSTOMER_0001TEMP_USERS_0042TEMP_PROJECT_0003Ces IDs permettent de maintenir les relations entre les enregistrements. À l'import, ils sont automatiquement remplacés par les vrais IDs générés.
L'import/export gère 45+ tables organisées par niveau de dépendance:
| Niveau | Tables |
|---|---|
| 0 | customer |
| 1 | customer_addr, users, _customer_sub, customer_group, customer_event, crm_cust, customer_fac, dsi_param, dsi_param_po, customer_ask_system, supplier |
| 2 | customer_addr_bat, users_profile, dsi_hw, dsi_hwvm, dsi_con, dsi_app, dsi_lic, dsi_tel, dsi_planip, tickets, _com_interv, _com_contr, customer_act_san, customer_act_ms, _com_wiki, _com_know, project |
| 3 | customer_addr_bat_lo, project_team, project_step, project_role, project_news, project_danger, project_kpi, project_meeting, project_budget |
| 4 | customer_addr_bat_lo_loc, customer_addr_bat_lo_pi, project_kpival, _com_task, _com_acl, _term |
Pour les commandes d'instance (demo:hospital, demo:mairie, demo:stinglay), les dates sont automatiquement fraîches à chaque exécution : le template génère ses dates via Carbon::now() et la valeur export_date est positionnée à l'heure courante, ce qui donne un décalage effectif de 0 jours.
Pour les imports depuis fichier XLSX (demo:import), le décalage est calculé automatiquement à partir de la date d'export contenue dans l'onglet _config.
Valeurs du paramètre dateOffsetDays (API interne) :
| Valeur | Comportement |
|--------|-------------|
| -1 | Auto : calcule le décalage depuis export_date (défaut pour demo:import) |
| 0 | Aucun décalage (dates importées telles quelles) |
| N > 0 | Décalage forcé de N jours |
Pour désactiver le décalage sur un import fichier : --date-offset=0
Si un onglet est absent ou vide dans le fichier XLSX, des données par défaut peuvent être insérées pour certaines tables (ex: project). Ceci est configurable dans DefaultDataConfig.php.
À l'import, certaines données sont automatiquement transformées:
| Table | Transformation |
|---|---|
customer |
SIRET unique généré, email modifié |
users |
Email rendu unique (format email+demoXXX@domain), mot de passe hashé |
| Toutes | Colonne _id mise à jour vers le target_idc |
Avant l'import, le fichier est validé:
_config, colonnes requisesLes erreurs bloquent l'import. Les avertissements sont affichés mais n'empêchent pas l'import (sauf si --force n'est pas utilisé).
app/
├── Services/DemoAccount/
│ ├── DemoAccountService.php # Façade principale
│ ├── Config/
│ │ ├── TableConfig.php # PK, FK, dates par table
│ │ └── DefaultDataConfig.php # Données par défaut
│ ├── Export/
│ │ └── DemoExporter.php
│ ├── Import/
│ │ ├── DemoImporter.php
│ │ └── Validators/XlsxValidator.php
│ └── Helpers/
│ ├── IdMappingHelper.php # Mapping temp_id → real_id
│ └── DateOffsetHelper.php
├── Exports/DemoAccount/
│ ├── DemoAccountExport.php
│ └── Sheets/
│ ├── ConfigSheet.php
│ └── TableSheet.php
└── Console/Commands/DemoAccount/
├── ExportDemoCommand.php
└── ImportDemoCommand.php
use App\Services\DemoAccount\DemoAccountService;
$service = new DemoAccountService();
// Export
$filePath = $service->export(999, 'exports/demo.xlsx');
// Validation
$result = $service->validate('storage/app/exports/demo.xlsx');
if (!$result->isValid) {
foreach ($result->errors as $error) {
echo $error;
}
}
// Import
$result = $service->import(
filePath: 'storage/app/exports/demo.xlsx',
targetIdc: 888,
targetName: 'Mon Client Demo',
dryRun: false,
dateOffsetDays: -1 // auto
);
if ($result->success) {
echo "Import réussi: {$result->statistics['customer']['inserted']} customers créés";
}
Le target_idc existe déjà. Choisissez un autre ID.
Une colonne NOT NULL n'a pas de valeur dans le fichier. Vérifiez les données ou ajoutez une valeur par défaut dans DefaultDataConfig.php.
Des FK pointent vers des enregistrements non exportés (utilisateurs supprimés, etc.). Ces références seront nulles à l'import.
Utilisez --date-offset=N pour forcer un décalage spécifique en jours.
Si une ligne n'est toujours pas recréée après --force-restore, vérifier qu'elle n'est pas aussi filtrée par une collision PK (tables non auto-increment). Consulter les warnings de la commande.
docs/demo/demo-merge-tests.md.claude/technical-docs/demo/demo-instances.md