Redesign the final STEP phase to build a step_finali folder

Previously it only compared the top-level BOM against step/ and reported
matches, without copying anything. Now it unions the BOM codes with the
sub-components resolved in phase 4, copies every matching .stp into a new
step_finali/ folder, and reports what got created vs what's still missing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5 committed 2026-09-17 10:23:35 +02:00
1 parent ee408219bd
commit 52d126372d
4 files changed
+57 -32

No files matched your search

+1
View File
@@ -28,6 +28,7 @@ publish/
/*.csv /*.csv
/raw/ /raw/
/step/ /step/
/step_finali/
*.dxc *.dxc
# Report BOM generati manualmente da Creo per debug/validazione: mai una dipendenza # Report BOM generati manualmente da Creo per debug/validazione: mai una dipendenza
+4 -2
View File
@@ -59,8 +59,10 @@ entrambi rimossi: ora l'unico programma è questo, con GUI e indicizzazione inte
sotto-assiemi/parti che contengono (`RisolviAlberoComponenti`), copiandoli anch'essi sotto-assiemi/parti che contengono (`RisolviAlberoComponenti`), copiandoli anch'essi
in `raw/`. in `raw/`.
5. **Verifica completezza e STEP** — "Verifica completezza assiemi" (ricorsivo sui 5. **Verifica completezza e STEP** — "Verifica completezza assiemi" (ricorsivo sui
percorsi originali in indice, non su `raw/`) e "Report STEP realizzati" (confronto percorsi originali in indice, non su `raw/`) e "Crea cartella step_finali": unisce i
con `step/`). codici della distinta con quelli risolti in fase 4 (`_componentiRisolti`), cerca in
`step/` il file `<codice>.stp` di ciascuno, lo copia in `step_finali/` se lo trova
e mostra l'esito (creato/mancante) in `ReportStepForm`.
- **Indexer.cs** — logica di scansione del disco e scrittura/aggiornamento del DB - **Indexer.cs** — logica di scansione del disco e scrittura/aggiornamento del DB
SQLite (`Indexer.ScanAsync`). Cammina tutte le cartelle di primo livello trovate sotto SQLite (`Indexer.ScanAsync`). Cammina tutte le cartelle di primo livello trovate sotto
la radice (scoperte dinamicamente con `Directory.GetDirectories`, non un elenco fisso) la radice (scoperte dinamicamente con `Directory.GetDirectories`, non un elenco fisso)
+40 -18
View File
@@ -46,6 +46,7 @@ public partial class Form1 : Form
private List<(string Componente, string Descrizione)>? _righeCorrenti; private List<(string Componente, string Descrizione)>? _righeCorrenti;
private Dictionary<string, List<string>>? _ultimaVerifica; private Dictionary<string, List<string>>? _ultimaVerifica;
private string? _ultimaCartellaRaw; private string? _ultimaCartellaRaw;
private List<(string Codice, string Tipo, string Percorso)>? _componentiRisolti;
public Form1() public Form1()
{ {
@@ -432,13 +433,13 @@ public partial class Form1 : Form
AutoSize = true, AutoSize = true,
ForeColor = SystemColors.GrayText, ForeColor = SystemColors.GrayText,
Margin = new Padding(0, 0, 0, 8), Margin = new Padding(0, 0, 0, 8),
Text = "Dopo aver esportato gli STEP con Creo, premi qui per confrontare i " Text = "Dopo aver esportato gli STEP con Creo, premi qui per confrontare i componenti "
+ "componenti della distinta con i file .stp presenti in 'step' e vedere quali " + "della distinta (e i sotto-componenti trovati in fase 4) con i file .stp presenti "
+ "sono già stati realizzati e quali mancano ancora.", + "in 'step', copiare quelli trovati in 'step_finali' e vedere quali mancano ancora.",
}; };
contenuto.Controls.Add(lblIstruzioniStep); contenuto.Controls.Add(lblIstruzioniStep);
_btnReport.Text = "Report STEP realizzati"; _btnReport.Text = "Crea cartella step_finali";
_btnReport.Size = new Size(220, 32); _btnReport.Size = new Size(220, 32);
_btnReport.Click += (_, _) => GeneraReportStep(); _btnReport.Click += (_, _) => GeneraReportStep();
contenuto.Controls.Add(_btnReport); contenuto.Controls.Add(_btnReport);
@@ -475,6 +476,7 @@ public partial class Form1 : Form
_gridRaw.Rows.Clear(); _gridRaw.Rows.Clear();
_ultimaCartellaRaw = null; _ultimaCartellaRaw = null;
_ultimaVerifica = null; _ultimaVerifica = null;
_componentiRisolti = null;
ImpostaStatoImport($"CSV generato ({righe.Count} righe): {csv}", Color.DarkGreen); ImpostaStatoImport($"CSV generato ({righe.Count} righe): {csv}", Color.DarkGreen);
} }
@@ -551,33 +553,52 @@ public partial class Form1 : Form
if (_percorsoInputCorrente is null || _righeCorrenti is null) if (_percorsoInputCorrente is null || _righeCorrenti is null)
return; return;
var cartellaStep = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(_percorsoInputCorrente))!, "step"); string radice = Path.GetDirectoryName(Path.GetFullPath(_percorsoInputCorrente))!;
var cartellaStep = Path.Combine(radice, "step");
if (!Directory.Exists(cartellaStep)) if (!Directory.Exists(cartellaStep))
{ {
ImpostaStatoImport($"Cartella 'step' non trovata in {cartellaStep}.", Color.DarkRed); ImpostaStatoImport($"Cartella 'step' non trovata in {cartellaStep}.", Color.DarkRed);
return; return;
} }
var codiciConStep = new HashSet<string>( var descrizioni = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Directory.GetFiles(cartellaStep, "*.stp").Select(Path.GetFileNameWithoutExtension)!); foreach (var r in _righeCorrenti)
descrizioni[r.Componente] = r.Descrizione;
var righeReport = _righeCorrenti // Il confronto include sia i componenti della distinta sia i sotto-componenti scoperti
.Select(r => (r.Componente, r.Descrizione, Realizzato: codiciConStep.Contains(r.Componente))) // ricorsivamente in fase 4 (_componentiRisolti): un assieme può avere lo STEP fatto solo
// per i suoi pezzi, non per l'assieme intero, o viceversa.
var tuttiICodici = _righeCorrenti.Select(r => r.Componente)
.Concat((_componentiRisolti ?? Enumerable.Empty<(string Codice, string Tipo, string Percorso)>()).Select(c => c.Codice))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList(); .ToList();
int realizzati = righeReport.Count(r => r.Realizzato);
var cartellaStepFinali = Path.Combine(radice, "step_finali");
Directory.CreateDirectory(cartellaStepFinali);
var righeReport = new List<(string Componente, string Descrizione, bool Creato)>();
foreach (var codice in tuttiICodici)
{
var percorsoStp = Path.Combine(cartellaStep, codice + ".stp");
bool trovato = File.Exists(percorsoStp);
if (trovato)
File.Copy(percorsoStp, Path.Combine(cartellaStepFinali, codice + ".stp"), overwrite: true);
righeReport.Add((codice, descrizioni.GetValueOrDefault(codice, ""), trovato));
}
int creati = righeReport.Count(r => r.Creato);
ImpostaStatoImport( ImpostaStatoImport(
$"Report STEP: {realizzati} componenti realizzati su {righeReport.Count} " $"STEP finali: {creati} componenti copiati su {righeReport.Count} "
+ $"({righeReport.Count - realizzati} mancanti).", + $"({righeReport.Count - creati} mancanti) in {cartellaStepFinali}.",
Color.DarkGreen); Color.DarkGreen);
using var dialog = new ReportStepForm(righeReport, cartellaStep); using var dialog = new ReportStepForm(righeReport, cartellaStepFinali);
dialog.ShowDialog(this); dialog.ShowDialog(this);
} }
/// <summary>Svuota in un colpo solo le cartelle "raw" e "step" nella root (stessa cartella /// <summary>Svuota in un colpo solo le cartelle "raw", "step" e "step_finali" nella root
/// base del file distinta importato), previa un'unica conferma. Non tocca l'indice CAD: solo /// (stessa cartella base del file distinta importato), previa un'unica conferma. Non tocca
/// le copie locali generate dalla pipeline.</summary> /// l'indice CAD: solo le copie locali generate dalla pipeline.</summary>
private void PulisciRawEStep() private void PulisciRawEStep()
{ {
string radice; string radice;
@@ -595,12 +616,12 @@ public partial class Form1 : Form
radice = dialog.SelectedPath; radice = dialog.SelectedPath;
} }
var cartelle = new[] { Path.Combine(radice, "raw"), Path.Combine(radice, "step") } var cartelle = new[] { Path.Combine(radice, "raw"), Path.Combine(radice, "step"), Path.Combine(radice, "step_finali") }
.Where(Directory.Exists) .Where(Directory.Exists)
.ToList(); .ToList();
if (cartelle.Count == 0) if (cartelle.Count == 0)
{ {
ImpostaStatoImport($"Nessuna cartella 'raw' o 'step' trovata in {radice}.", Color.DarkRed); ImpostaStatoImport($"Nessuna cartella 'raw', 'step' o 'step_finali' trovata in {radice}.", Color.DarkRed);
return; return;
} }
@@ -730,6 +751,7 @@ public partial class Form1 : Form
progressForm.ShowDialog(this); progressForm.ShowDialog(this);
var (trovati, codiciNonTrovati) = await task; var (trovati, codiciNonTrovati) = await task;
_componentiRisolti = trovati;
int numPrt = trovati.Count(r => r.Tipo == "prt"); int numPrt = trovati.Count(r => r.Tipo == "prt");
int numAsm = trovati.Count(r => r.Tipo == "asm"); int numAsm = trovati.Count(r => r.Tipo == "asm");
+12 -12
View File
@@ -2,15 +2,15 @@ using System.Diagnostics;
namespace CadSearchGui; namespace CadSearchGui;
/// <summary>Mostra, per ogni componente della distinta base, se lo STEP corrispondente /// <summary>Mostra, per ogni componente (distinta base + sotto-componenti risolti in fase 4),
/// è già stato esportato (file .stp presente in "step") o manca ancora.</summary> /// se lo STEP corrispondente è stato trovato in "step" e copiato in "step_finali", o se manca.</summary>
public class ReportStepForm : Form public class ReportStepForm : Form
{ {
public ReportStepForm(List<(string Componente, string Descrizione, bool Realizzato)> righe, string cartellaStep) public ReportStepForm(List<(string Componente, string Descrizione, bool Creato)> righe, string cartellaStepFinali)
{ {
int realizzati = righe.Count(r => r.Realizzato); int creati = righe.Count(r => r.Creato);
Text = "Report STEP realizzati"; Text = "Report STEP finali";
ClientSize = new Size(720, 440); ClientSize = new Size(720, 440);
StartPosition = FormStartPosition.CenterParent; StartPosition = FormStartPosition.CenterParent;
Font = new Font("Segoe UI", 9.5f); Font = new Font("Segoe UI", 9.5f);
@@ -21,8 +21,8 @@ public class ReportStepForm : Form
AutoSize = false, AutoSize = false,
Height = 32, Height = 32,
Padding = new Padding(12, 8, 12, 8), Padding = new Padding(12, 8, 12, 8),
Text = $"{realizzati} componenti realizzati su {righe.Count} ({righe.Count - realizzati} mancanti), " Text = $"{creati} componenti copiati su {righe.Count} ({righe.Count - creati} mancanti) "
+ $"confrontati con \"{cartellaStep}\".", + $"in \"{cartellaStepFinali}\".",
}; };
var grid = new DataGridView var grid = new DataGridView
@@ -42,16 +42,16 @@ public class ReportStepForm : Form
grid.Columns["descrizione"]!.FillWeight = 55; grid.Columns["descrizione"]!.FillWeight = 55;
grid.Columns["step"]!.FillWeight = 25; grid.Columns["step"]!.FillWeight = 25;
foreach (var (componente, descrizione, realizzato) in righe.OrderBy(r => r.Realizzato).ThenBy(r => r.Componente)) foreach (var (componente, descrizione, creato) in righe.OrderBy(r => r.Creato).ThenBy(r => r.Componente))
{ {
int i = grid.Rows.Add(componente, descrizione, realizzato ? "Realizzato" : "Mancante"); int i = grid.Rows.Add(componente, descrizione, creato ? "Creato" : "Mancante");
grid.Rows[i].DefaultCellStyle.ForeColor = realizzato ? Color.DarkGreen : Color.DarkRed; grid.Rows[i].DefaultCellStyle.ForeColor = creato ? Color.DarkGreen : Color.DarkRed;
} }
var btnApriCartella = new Button { Text = "Apri cartella step", Dock = DockStyle.Bottom, Height = 34 }; var btnApriCartella = new Button { Text = "Apri cartella step_finali", Dock = DockStyle.Bottom, Height = 34 };
btnApriCartella.Click += (_, _) => btnApriCartella.Click += (_, _) =>
{ {
try { Process.Start("explorer.exe", cartellaStep); } try { Process.Start("explorer.exe", cartellaStepFinali); }
catch (Exception ex) catch (Exception ex)
{ {
MessageBox.Show(this, $"Impossibile aprire Esplora risorse:\n{ex.Message}", "Errore", MessageBox.Show(this, $"Impossibile aprire Esplora risorse:\n{ex.Message}", "Errore",