Validazione Profili Duplicati nelle Macchine
Validazione Profili Duplicati nelle Macchine
🎯 Problema
Cosa succede se associ lo stesso profilo più volte a una macchina?
Esempio Problematico
``json
{
"profiles_config": [
{
"servizio": "Taglio",
"profilo_id": 5,
"nomeProfilo": "Profilo Standard"
},
{
"servizio": "Piega",
"profilo_id": 5, ← STESSO PROFILO!
"nomeProfilo": "Profilo Standard"
}
]
}
`
Conseguenze
Il sistema genera il path CSV basandosi solo su machine_id + profilo_id:
`php
$pathName = "csv_I40_{$machine->id}_{$config['profilo_id']}";
// Esempio: csv_I40_1_5
`
Risultato:
- Entry 1: csv_I40_1_5
(servizio: Taglio) - Entry 2: csv_I40_1_5
(servizio: Piega) ← PATH DUPLICATO! - ✅ MachinesController::store()
- Creazione nuova macchina - ✅ MachinesController::update()
- Modifica macchina esistente - Profili già associati: Visualizzati come readonly con badge "Assegnato"
- Dropdown "Aggiungi": Mostra solo profili disponibili
- ✅
- ✅
- Un profilo definisce la struttura del CSV
- Se il CSV ha sempre la stessa struttura, è lo stesso profilo
- Non serve duplicarlo: tutti i CSV arriveranno nello stesso path
- ✅
- ✅
Problemi Causati:
1. Conflitto Creazione Path - Il secondo path sovrascrive il primo - Il primo symlink viene eliminato - Solo l'ultimo profilo rimane "attivo"
2. Dati Mescolati - CSV di servizi diversi finiscono nella stessa cartella - Impossibile distinguere quale CSV appartiene a quale servizio
3. Confusione Elaborazione - L'import non sa quale tracciato record usare - I campi CSV potrebbero non corrispondere al profilo atteso
4. Statistiche Errate - Il conteggio file è unico per entrambi i servizi - Le dashboard mostrano dati incorretti
---
✅ Soluzione Implementata
1. Validazione Lato Server
Impedire l'associazione dello stesso profilo più volte alla stessa macchina.
2. Filtro Profili Disponibili (Lato Client)
In modifica macchina, il dropdown "Aggiungi Profilo" mostra solo i profili NON ancora associati, prevenendo confusione e errori dell'utente.
Codice (MachinesController)
`php
// Verifica profili duplicati
$profileIds = array_column($validated['profiles_config'], 'profilo_id');
if (count($profileIds) !== count(array_unique($profileIds))) {
return back()
->withInput()
->withErrors([
'profiles_config' => 'Non puoi associare lo stesso profilo più volte alla stessa macchina. Ogni profilo può essere usato una sola volta.'
]);
}
`
Implementato In:
Validazione Aggiuntiva:
`php
'profiles_config.*.profilo_id' => 'required|integer',
`Filtro Profili (Controller
edit)`php
// Ottieni tutti i profili
$allProfiles = ImportProfile::orderBy('name')->get();// Ottieni gli ID dei profili già associati alla macchina
$usedProfileIds = array_column($machine->profiles_config ?? [], 'profilo_id');
// Filtra solo i profili NON ancora associati
$availableProfiles = $allProfiles->filter(function($profile) use ($usedProfileIds) {
return !in_array($profile->id, $usedProfileIds);
});
`Risultato:
---
🎭 Scenario d'Uso Valido
Una Macchina, Più Servizi, Profili Diversi
`json
{
"profiles_config": [
{
"servizio": "Taglio",
"profilo_id": 5,
"nomeProfilo": "Profilo Taglio Standard"
},
{
"servizio": "Piega",
"profilo_id": 7, ← PROFILO DIVERSO ✓
"nomeProfilo": "Profilo Piega CNC"
}
]
}
`Path Generati:
csv_I40_1_5 → Taglio
csv_I40_1_7 → PiegaRisultato: Ogni servizio ha la sua cartella CSV dedicata.
---
🚫 Scenario Bloccato
Stesso Profilo, Servizi Diversi
`json
{
"profiles_config": [
{
"servizio": "Taglio",
"profilo_id": 5,
"nomeProfilo": "Profilo Standard"
},
{
"servizio": "Piega",
"profilo_id": 5, ← DUPLICATO ✗
"nomeProfilo": "Profilo Standard"
}
]
}
`Errore mostrato:
> ❌ Non puoi associare lo stesso profilo più volte alla stessa macchina. Ogni profilo può essere usato una sola volta.
---
🤔 Caso Particolare: Stesso Servizio, Stesso Profilo
È Necessario Duplicare?
Domanda: E se volessi usare lo stesso profilo più volte per lo stesso servizio?
Risposta: Non ha senso logico.
Motivo:
Alternativa:
Se hai bisogno di varianti dello stesso formato:
1. Duplica il profilo (funzione già implementata)
2. Modifica la variante (es. aggiungendo/rimuovendo colonne)
3. Assegna la variante alla macchina con un servizio diverso
---
📊 Gestione delle Varianti
Workflow Consigliato
Se hai bisogno di "profili simili" per servizi diversi:
1. Crea Profilo Base
- Esempio: "Profilo Taglio Standard"
2. Duplica per Variante
- Click su "Duplica" nella lista profili
- Rinomina: "Profilo Taglio Standard - Variante A"
3. Personalizza la Variante
- Aggiungi/rimuovi colonne
- Modifica nomi mnemonici
- Salva come nuovo profilo
4. Assegna alla Macchina
- Servizio 1: Profilo Base (ID=5)
- Servizio 2: Variante A (ID=12)
Risultato:
csv_I40_1_5 → Servizio 1 (Profilo Base)
csv_I40_1_12 → Servizio 2 (Variante A)---
🔍 Come Verificare Profili Duplicati
Da Interfaccia Web
Quando tenti di salvare una macchina con profili duplicati: 1. Il form viene respinto 2. Errore visualizzato sopra il form 3. Dati inseriti vengono preservati per correzione
Da Database
Query per trovare macchine con profili duplicati (se esistenti prima della validazione):
`sql
SELECT
m.id,
m.name,
m.profiles_config,
JSON_LENGTH(m.profiles_config) as total_configs,
(
SELECT COUNT(DISTINCT JSON_EXTRACT(p.value, '$.profilo_id'))
FROM JSON_TABLE(
m.profiles_config,
'$[*]' COLUMNS(value JSON PATH '$')
) p
) as unique_profiles
FROM machines_i40 m
HAVING total_configs > unique_profiles;
`
---
🎯 Best Practices
✅ DO (Fai)
1. Un Profilo per Servizio - Ogni servizio ha il suo profilo dedicato - CSV ben organizzati per tipo
2. Duplica per Varianti - Usa la funzione "Duplica" per creare varianti - Rinomina chiaramente le varianti
3. Nomi Descrittivi - "Taglio - Lamiera Sottile" - "Taglio - Lamiera Spessa" - Facilita la scelta del profilo corretto
❌ DON'T (Non Fare)
1. Non Forzare Profili Duplicati - Se il form rifiuta, c'è un motivo - Non modificare il database manualmente
2. Non Riusare Profili Incompatibili - Se le strutture CSV sono diverse, servono profili diversi - Non cercare di "adattare" profili esistenti
3. Non Confondere Servizio e Profilo - Servizio = Label descrittivo (es. "Taglio", "Piega") - Profilo = Struttura tecnica del CSV - Sono concetti diversi!
---
📝 Riepilogo
| Aspetto | Decisione |
|---------|-----------|
| Profili Duplicati | ❌ Bloccati dalla validazione |
| Stessa Struttura CSV | ✅ Usa lo stesso profilo |
| Strutture Diverse | ✅ Crea/Duplica profili diversi |
| Path Generato | csv_I40_{machine_id}_{profilo_id} |
| Univocità Garantita Da | Coppia (machine_id, profilo_id)` |
---
Ultimo aggiornamento: 17 Ottobre 2025
Analisi Codice
Blocco 1 json
{
"profiles_config": [
{
"servizio": "Taglio",
"profilo_id": 5,
"nomeProfilo": "Profilo Standard"
},
{
"servizio": "Piega",
"profilo_id": 5, ← STESSO PROFILO!
"nomeProfilo": "Profilo Standard"
}
]
}
Blocco 2 php
$pathName = "csv_I40_{$machine->id}_{$config['profilo_id']}";
// Esempio: csv_I40_1_5
Blocco 3 php
// Verifica profili duplicati
$profileIds = array_column($validated['profiles_config'], 'profilo_id');
if (count($profileIds) !== count(array_unique($profileIds))) {
return back()
->withInput()
->withErrors([
'profiles_config' => 'Non puoi associare lo stesso profilo più volte alla stessa macchina. Ogni profilo può essere usato una sola volta.'
]);
}
Blocco 4 php
'profiles_config.*.profilo_id' => 'required|integer',
Blocco 5 php
// Ottieni tutti i profili
$allProfiles = ImportProfile::orderBy('name')->get();
// Ottieni gli ID dei profili già associati alla macchina
$usedProfileIds = array_column($machine->profiles_config ?? [], 'profilo_id');
// Filtra solo i profili NON ancora associati
$availableProfiles = $allProfiles->filter(function($profile) use ($usedProfileIds) {
return !in_array($profile->id, $usedProfileIds);
});
Blocco 6 json
{
"profiles_config": [
{
"servizio": "Taglio",
"profilo_id": 5,
"nomeProfilo": "Profilo Taglio Standard"
},
{
"servizio": "Piega",
"profilo_id": 7, ← PROFILO DIVERSO ✓
"nomeProfilo": "Profilo Piega CNC"
}
]
}
Blocco 7 json
{
"profiles_config": [
{
"servizio": "Taglio",
"profilo_id": 5,
"nomeProfilo": "Profilo Standard"
},
{
"servizio": "Piega",
"profilo_id": 5, ← DUPLICATO ✗
"nomeProfilo": "Profilo Standard"
}
]
}
Blocco 8 sql
SELECT
m.id,
m.name,
m.profiles_config,
JSON_LENGTH(m.profiles_config) as total_configs,
(
SELECT COUNT(DISTINCT JSON_EXTRACT(p.value, '$.profilo_id'))
FROM JSON_TABLE(
m.profiles_config,
'$[*]' COLUMNS(value JSON PATH '$')
) p
) as unique_profiles
FROM machines_i40 m
HAVING total_configs > unique_profiles;