diff --git a/CLAUDE.md b/CLAUDE.md index 4eefae4..060ea5e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -52,7 +52,8 @@ entrambi rimossi: ora l'unico programma è questo, con GUI e indicizzazione inte 1. **Database** — carica/aggiorna l'indice, mostra data ultimo aggiornamento; qui vive anche la **cartella di lavoro** (`_cartellaLavoro`, mostrata in `_lblCartellaLavoro`, cambiabile con "Cambia cartella..." → `ScegliCartellaLavoro`): destinazione di CSV, - `raw/`, `step/`, `step_finali/` per tutte le fasi successive. All'avvio + `raw/` per tutte le fasi successive (gli STEP esportati a mano con Creo vanno in + `step/`, dentro la stessa cartella). All'avvio `InizializzaCartellaLavoro` propone l'ultima usata (ricordata in `%AppData%/PrepStep/ultima_cartella_lavoro.txt`, stesso pattern di `ultimo_db.txt` per il DB) se esiste ancora, altrimenti `AppContext.BaseDirectory` @@ -73,18 +74,14 @@ entrambi rimossi: ora l'unico programma è questo, con GUI e indicizzazione inte già in `raw/` (`AssemblyComponentScanner`) per risolvere ricorsivamente i sotto-assiemi/parti che contengono (`RisolviAlberoComponenti`), copiandoli anch'essi in `raw/`. - 5. **Verifica completezza e STEP** — appena si entra nella fase, `AggiornaAnteprimaAsm` + 5. **Verifica completezza** — appena si entra nella fase, `AggiornaAnteprimaAsm` mostra in una `ListView` a icone i file `.asm` della distinta importata (esclusi i sotto-assiemi di fase 4) già presenti in `raw/` — letti dal filesystem locale, non dall'indice/share — trascinabili (drag&drop, `ItemDrag` → `DoDragDrop` con - `DataFormats.FileDrop`) direttamente su Creo o Esplora risorse. "Verifica completezza - assiemi" (ricorsivo sui percorsi originali in indice, non su `raw/`) e "Crea cartella - step_finali": solo per i codici della distinta importata dal CSV (non i - sotto-componenti di fase 4, che servono solo a completare `raw/`) cerca in `step/` il - file `.stp` e lo copia in `step_finali/` se lo trova. Per i mancanti distingue, - incrociando l'indice CAD, `EsitoStep.StepMancante` (il CAD c'è, manca solo - l'esportazione STEP) da `ComponenteNonTrovato` (il componente non è nemmeno - nell'indice) — vedi `ReportStepForm`. + `DataFormats.FileDrop`) direttamente su Creo o Esplora risorse, per l'esportazione + STEP con Creo Distributed Batch. "Verifica completezza assiemi" controlla + ricorsivamente (sui percorsi originali in indice, non su `raw/`) se tutti i + sotto-componenti di ogni assieme della distinta sono nell'indice. - **Indexer.cs** — logica di scansione del disco e scrittura/aggiornamento del DB SQLite (`Indexer.ScanAsync`). Cammina tutte le cartelle di primo livello trovate sotto la radice (scoperte dinamicamente con `Directory.GetDirectories`, non un elenco fisso) diff --git a/PrepStep/Form1.cs b/PrepStep/Form1.cs index a9e6fe3..9e5f1d7 100644 --- a/PrepStep/Form1.cs +++ b/PrepStep/Form1.cs @@ -9,7 +9,6 @@ public partial class Form1 : Form private readonly Button _btnAggiorna = new(); private readonly Button _btnCreaRaw = new(); private readonly Button _btnTrovaPrt = new(); - private readonly Button _btnReport = new(); private readonly Button _btnVerifica = new(); private readonly Button _btnCompletezza = new(); private readonly ListView _lstAnteprimaAsm = new(); @@ -32,7 +31,7 @@ public partial class Form1 : Form "2. Importa Distinta Base", "3. Crea cartella raw", "4. Trova componenti referenziati", - "5. Verifica completezza e STEP", + "5. Verifica completezza", }; private readonly Panel[] _panelFasi = new Panel[NomiFasi.Length]; private readonly Panel _faseContainer = new() { Dock = DockStyle.Fill }; @@ -282,9 +281,10 @@ public partial class Form1 : Form AutoSize = true, ForeColor = SystemColors.GrayText, Margin = new Padding(0, 20, 0, 4), - Text = "Cartella di lavoro: qui vengono scritti il CSV della distinta e le " - + "cartelle 'raw', 'step' e 'step_finali'. Proposta automaticamente " - + "(ricordata da un avvio all'altro), modificabile con 'Cambia cartella...'.", + Text = "Cartella di lavoro: qui vengono scritti il CSV della distinta e la " + + "cartella 'raw' (gli STEP esportati con Creo vanno invece in 'step', " + + "dentro la stessa cartella). Proposta automaticamente (ricordata da un " + + "avvio all'altro), modificabile con 'Cambia cartella...'.", }; contenuto.Controls.Add(lblIstruzioniCartella); @@ -530,35 +530,9 @@ public partial class Form1 : Form }; top.Controls.Add(lblAnteprimaAsm); - var bottom = new TableLayoutPanel - { - Dock = DockStyle.Bottom, - AutoSize = true, - AutoSizeMode = AutoSizeMode.GrowAndShrink, - ColumnCount = 1, - }; - bottom.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100)); - - var lblIstruzioniStep = new Label - { - Dock = DockStyle.Top, - AutoSize = true, - ForeColor = SystemColors.GrayText, - Margin = new Padding(12, 0, 0, 8), - Text = "Dopo aver esportato gli STEP con Creo, premi qui per confrontare i componenti " - + "della distinta (e i sotto-componenti trovati in fase 4) con i file .stp presenti " - + "in 'step', copiare quelli trovati in 'step_finali' e vedere quali mancano ancora.", - }; - bottom.Controls.Add(lblIstruzioniStep); - - _btnReport.Text = "Crea cartella step_finali"; - UiStile.Secondario(_btnReport); - _btnReport.Click += (_, _) => GeneraReportStep(); - bottom.Controls.Add(_btnReport); - // Dock=Fill invece di una Size fissa: la lista occupa tutto lo spazio verticale - // rimasto tra le istruzioni sopra e sotto, così si vedono più file .asm senza scroll - // anche a finestra ingrandita, invece dei ~160px fissi di prima. + // rimasto sotto le istruzioni, così si vedono più file .asm senza scroll anche a + // finestra ingrandita, invece dei ~160px fissi di prima. _lstAnteprimaAsm.View = View.LargeIcon; _lstAnteprimaAsm.MultiSelect = true; _lstAnteprimaAsm.LargeImageList = new ImageList { ImageSize = new Size(32, 32) }; @@ -575,7 +549,6 @@ public partial class Form1 : Form }; panel.Controls.Add(_lstAnteprimaAsm); - panel.Controls.Add(bottom); panel.Controls.Add(top); return panel; } @@ -675,82 +648,18 @@ public partial class Form1 : Form AggiornaStatoAvanti(); } - /// Confronta i componenti della distinta importata con i file .stp presenti nella - /// cartella "step" (esportati manualmente con Creo Distributed Batch), per dire quali sono - /// già stati realizzati e quali mancano ancora. - private void GeneraReportStep() - { - if (_righeCorrenti is null) - return; - - string radice = _cartellaLavoro!; - var cartellaStep = Path.Combine(radice, "step"); - if (!Directory.Exists(cartellaStep)) - { - ImpostaStatoImport($"Cartella 'step' non trovata in {cartellaStep}.", Color.DarkRed); - return; - } - - var descrizioni = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var r in _righeCorrenti) - descrizioni[r.Componente] = r.Descrizione; - - // Solo i componenti della distinta importata dal CSV: i sotto-componenti trovati in - // fase 4 (_componentiRisolti) servono a completare "raw", non entrano nello STEP finale. - var tuttiICodici = _righeCorrenti.Select(r => r.Componente) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); - - // Per i codici senza STEP, distingue "il CAD c'è ma lo STEP non è stato esportato" da - // "il componente non è nemmeno nell'indice CAD" (riusa la verifica già fatta in fase 2/3 - // se disponibile, altrimenti la rifà). - var cadTrovati = _ultimaVerifica ?? TrovaPercorsiCad(tuttiICodici); - - var cartellaStepFinali = Path.Combine(radice, "step_finali"); - Directory.CreateDirectory(cartellaStepFinali); - - var righeReport = new List<(string Componente, string Descrizione, EsitoStep Esito)>(); - foreach (var codice in tuttiICodici) - { - var percorsoStp = Path.Combine(cartellaStep, codice + ".stp"); - EsitoStep esito; - if (File.Exists(percorsoStp)) - { - File.Copy(percorsoStp, Path.Combine(cartellaStepFinali, codice + ".stp"), overwrite: true); - esito = EsitoStep.Creato; - } - else - { - esito = cadTrovati.ContainsKey(codice) ? EsitoStep.StepMancante : EsitoStep.ComponenteNonTrovato; - } - righeReport.Add((codice, descrizioni.GetValueOrDefault(codice, ""), esito)); - } - int creati = righeReport.Count(r => r.Esito == EsitoStep.Creato); - int stepMancanti = righeReport.Count(r => r.Esito == EsitoStep.StepMancante); - int nonTrovati = righeReport.Count(r => r.Esito == EsitoStep.ComponenteNonTrovato); - - ImpostaStatoImport( - $"STEP finali: {creati} copiati, {stepMancanti} da esportare (CAD presente), " - + $"{nonTrovati} componenti non nell'indice, su {righeReport.Count} totali. " - + $"Cartella: {cartellaStepFinali}.", - Color.DarkGreen); - - using var dialog = new ReportStepForm(righeReport, cartellaStepFinali); - dialog.ShowDialog(this); - } - - /// Svuota in un colpo solo le cartelle "raw", "step" e "step_finali" nella cartella - /// di lavoro, previa un'unica conferma. Non tocca l'indice CAD: solo le copie locali - /// generate dalla pipeline. + /// Svuota in un colpo solo le cartelle "raw" e "step" nella cartella di lavoro, + /// previa un'unica conferma. Non tocca l'indice CAD: solo le copie locali generate dalla + /// pipeline. private void PulisciRawEStep() { string radice = _cartellaLavoro!; - var cartelle = new[] { Path.Combine(radice, "raw"), Path.Combine(radice, "step"), Path.Combine(radice, "step_finali") } + var cartelle = new[] { Path.Combine(radice, "raw"), Path.Combine(radice, "step") } .Where(Directory.Exists) .ToList(); if (cartelle.Count == 0) { - ImpostaStatoImport($"Nessuna cartella 'raw', 'step' o 'step_finali' trovata in {radice}.", Color.DarkRed); + ImpostaStatoImport($"Nessuna cartella 'raw' o 'step' trovata in {radice}.", Color.DarkRed); return; } @@ -1081,7 +990,7 @@ public partial class Form1 : Form { using var dialog = new FolderBrowserDialog { - Description = "Seleziona la cartella di lavoro (CSV, raw, step, step_finali)", + Description = "Seleziona la cartella di lavoro (CSV, raw, step)", SelectedPath = _cartellaLavoro ?? string.Empty, }; if (dialog.ShowDialog(this) != DialogResult.OK) diff --git a/PrepStep/ReportStepForm.cs b/PrepStep/ReportStepForm.cs deleted file mode 100644 index b5b301b..0000000 --- a/PrepStep/ReportStepForm.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Diagnostics; - -namespace PrepStep; - -public enum EsitoStep -{ - /// File .stp trovato in "step" e copiato in "step_finali". - Creato, - /// Il componente è nell'indice CAD (asm/prt trovato), ma nessuno STEP esportato. - StepMancante, - /// Il componente non è nemmeno nell'indice CAD. - ComponenteNonTrovato, -} - -/// Mostra, per ogni componente della distinta base, se lo STEP corrispondente è stato -/// trovato in "step" e copiato in "step_finali", se manca solo lo STEP (il CAD sorgente c'è, -/// ma non è ancora stato esportato) o se manca anche il CAD sorgente nell'indice. -public class ReportStepForm : Form -{ - public ReportStepForm(List<(string Componente, string Descrizione, EsitoStep Esito)> righe, string cartellaStepFinali) - { - int creati = righe.Count(r => r.Esito == EsitoStep.Creato); - int stepMancanti = righe.Count(r => r.Esito == EsitoStep.StepMancante); - int nonTrovati = righe.Count(r => r.Esito == EsitoStep.ComponenteNonTrovato); - - Text = "Report STEP finali"; - ClientSize = new Size(720, 440); - StartPosition = FormStartPosition.CenterParent; - Font = new Font("Segoe UI", 9.5f); - - var lblInfo = new Label - { - Dock = DockStyle.Top, - AutoSize = true, - Padding = new Padding(12, 8, 12, 8), - Text = $"{creati} copiati, {stepMancanti} da esportare (CAD presente), " - + $"{nonTrovati} non nell'indice, su {righe.Count} totali. In \"{cartellaStepFinali}\".", - }; - - var grid = new DataGridView - { - Dock = DockStyle.Fill, - ReadOnly = true, - AllowUserToAddRows = false, - AllowUserToDeleteRows = false, - RowHeadersVisible = false, - SelectionMode = DataGridViewSelectionMode.FullRowSelect, - AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill, - }; - grid.Columns.Add("componente", "Componente"); - grid.Columns.Add("descrizione", "Descrizione"); - grid.Columns.Add("step", "STEP"); - grid.Columns["componente"]!.FillWeight = 20; - grid.Columns["descrizione"]!.FillWeight = 55; - grid.Columns["step"]!.FillWeight = 25; - - foreach (var (componente, descrizione, esito) in righe.OrderBy(r => r.Esito).ThenBy(r => r.Componente)) - { - var (testo, colore) = esito switch - { - EsitoStep.Creato => ("Creato", Color.DarkGreen), - EsitoStep.StepMancante => ("Da esportare (CAD presente)", Color.DarkOrange), - _ => ("Componente non trovato nel server", Color.DarkRed), - }; - int i = grid.Rows.Add(componente, descrizione, testo); - grid.Rows[i].DefaultCellStyle.ForeColor = colore; - } - - var btnApriCartella = new Button { Text = "Apri cartella step_finali", Dock = DockStyle.Bottom, Height = 34 }; - UiStile.Secondario(btnApriCartella); - btnApriCartella.Click += (_, _) => - { - try { Process.Start("explorer.exe", cartellaStepFinali); } - catch (Exception ex) - { - MessageBox.Show(this, $"Impossibile aprire Esplora risorse:\n{ex.Message}", "Errore", - MessageBoxButtons.OK, MessageBoxIcon.Error); - } - }; - - Controls.Add(grid); - Controls.Add(lblInfo); - Controls.Add(btnApriCartella); - } -} diff --git a/README.md b/README.md index 5f42b6b..9f68ad3 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,10 @@ passaggio, non lo sostituisce. esistente con **Apri DB...** o generarne uno nuovo con **Aggiorna indice**, che scansiona il disco (di default `X:\`, tutte le cartelle di primo livello che trova) e indicizza tutti i file. In questa fase si vede/cambia anche - la **cartella di lavoro**: dove finiscono il CSV e le cartelle `raw/`, `step/`, - `step_finali/`. Proposta automaticamente (ricordata da un avvio all'altro), - modificabile con **Cambia cartella...**. + la **cartella di lavoro**: dove finiscono il CSV e la cartella `raw/` (gli STEP + esportati con Creo vanno in `step/`, dentro la stessa cartella). Proposta + automaticamente (ricordata da un avvio all'altro), modificabile con + **Cambia cartella...**. 2. **Importa Distinta Base** — trascina (o scegli da file) l'estrazione `.xls`/`.xml` del gestionale (foglio "Distinta Base", colonne Componente/Descrizione): viene generato un CSV nella cartella di lavoro, con @@ -30,10 +31,10 @@ passaggio, non lo sostituisce. 4. **Trova componenti referenziati** — legge i metadati dei file `.asm` in `raw/` per trovare ricorsivamente i sotto-assiemi/parti che li compongono, copiandoli a loro volta in `raw/`. -5. **Verifica completezza assiemi** / **Report STEP realizzati** — confronta - la distinta con l'indice (per capire se manca qualche sotto-componente) - e con la cartella `step/` (per capire quali STEP sono già stati - realizzati). +5. **Verifica completezza assiemi** — confronta la distinta con l'indice per + capire se manca qualche sotto-componente, e mostra i file `.asm` della + distinta trascinabili su Creo/Esplora risorse per l'esportazione STEP con + Creo Distributed Batch. ## Requisiti diff --git a/docs/architettura.md b/docs/architettura.md index 050bafb..8ac39ce 100644 --- a/docs/architettura.md +++ b/docs/architettura.md @@ -12,15 +12,16 @@ copia in `raw/` vedi `docs/copia-raw-parallela.md`. Un solo eseguibile WinForms (nessuna CLI, nessun processo esterno): indicizza i file CAD di una share di rete in un DB SQLite locale, poi guida l'utente in un wizard a 5 fasi che, a partire da una distinta base esportata dal gestionale, raccoglie in locale (`raw/`) tutti i -file CAD dei componenti e dei loro sotto-assiemi, e verifica/raccoglie gli STEP corrispondenti -(`step_finali/`). +file CAD dei componenti e dei loro sotto-assiemi e verifica che l'indice li copra, come +pre-process prima dell'esportazione STEP con Creo Distributed Batch (manuale, fuori +dall'app: i file esportati finiscono in `step/`, dentro la cartella di lavoro). ``` Distinta (.xls/.xml) → CSV (componente;descrizione) → raw/ (CAD copiati dall'indice) │ scansione .asm ─────┘ (sotto-assiemi/parti mancanti) │ - step/ (esportati a mano da Creo) → step_finali/ (solo i codici distinta) + drag&drop .asm su Creo → Distributed Batch → step/ (esportazione manuale) ``` ## Entry point @@ -44,7 +45,7 @@ Distinta (.xls/.xml) → CSV (componente;descrizione) → raw/ (CAD copiati | 2 | Importa Distinta Base | selezione file → `ImportaDistinta` → `DistintaBaseImporter.ConvertiInCsv` | Xls/Xml gestionale → CSV componente;descrizione, scritto nella cartella di lavoro | | 3 | Crea cartella raw | "Crea cartella raw" → `CreaCartellaRaw` | `TrovaPercorsiCad` + `CopiaFileTrovati` (parallela) → `raw/` dentro la cartella di lavoro | | 4 | Trova componenti referenziati | "Trova componenti referenziati" → `TrovaPrtReferenziati` → `RisolviAlberoComponenti` | Legge i `.asm` in `raw/` con `AssemblyComponentScanner`, risolve ricorsivamente sotto-assiemi/parti nell'indice, li copia anch'essi in `raw/` | - | 5 | Verifica completezza e STEP | "Verifica completezza assiemi" → `VerificaCompletezzaAssiemi`; "Crea cartella step_finali" → `GeneraReportStep` | Completezza ricorsiva sui percorsi in indice; confronto con `step/` → `step_finali/` (entrambe dentro la cartella di lavoro). All'ingresso nella fase, `AggiornaAnteprimaAsm` mostra le icone trascinabili dei `.asm` della distinta già in `raw/` | + | 5 | Verifica completezza | "Verifica completezza assiemi" → `VerificaCompletezzaAssiemi` | Completezza ricorsiva sui percorsi in indice. All'ingresso nella fase, `AggiornaAnteprimaAsm` mostra le icone trascinabili dei `.asm` della distinta già in `raw/`, da trascinare su Creo per l'esportazione STEP (Distributed Batch) | Stato condiviso tra le fasi (campi privati di `Form1`): `_dbPath`, `_cartellaLavoro`, `_percorsoInputCorrente`, `_righeCorrenti` (righe del CSV), `_ultimaVerifica` (cache percorsi @@ -56,8 +57,8 @@ Distinta (.xls/.xml) → CSV (componente;descrizione) → raw/ (CAD copiati componenti sia da `AssemblyComponentScanner` per validare i token generici). - `CopiaFileTrovati` — copia (in parallelo, grado 6) i file trovati in `raw/`, saltando silenziosamente quelli irraggiungibili (share offline/permessi). - - `PulisciRawEStep` — svuota `raw/`, `step/`, `step_finali/` nella cartella di lavoro - (manutenzione, richiede conferma). + - `PulisciRawEStep` — svuota `raw/` e `step/` nella cartella di lavoro (manutenzione, + richiede conferma). - `InizializzaDatabase` / `ScegliDatabase` — localizzazione del DB (ultimo usato, salvato in `%AppData%/PrepStep/ultimo_db.txt`, o `cad_index.db` accanto all'eseguibile). - `InizializzaCartellaLavoro` / `ScegliCartellaLavoro` — stesso pattern per la cartella di @@ -126,9 +127,6 @@ Distinta (.xls/.xml) → CSV (componente;descrizione) → raw/ (CAD copiati positivi della scansione `.asm`). - **ReportCompletezzaForm.cs** — per ogni assieme della distinta, se tutti i suoi componenti (ricorsivamente fino ai PRT) sono nell'indice (✓/✗/? per "non trovato"). -- **ReportStepForm.cs** — per ogni componente della distinta, `EsitoStep`: `Creato` (STEP - trovato e copiato), `StepMancante` (CAD in indice ma STEP non esportato), - `ComponenteNonTrovato` (nemmeno il CAD è in indice). ## Persistenza @@ -140,8 +138,8 @@ Distinta (.xls/.xml) → CSV (componente;descrizione) → raw/ (CAD copiati (stesso meccanismo del DB sopra), proposta di default `AppContext.BaseDirectory` la prima volta; selezionabile/cambiabile con "Cambia cartella..." in fase 1. Tutti i file generati a valle ci finiscono dentro: il CSV della distinta, `raw/` (CAD dei componenti e - sotto-componenti), `step/` (STEP esportati a mano da Creo, input), `step_finali/` (STEP dei - soli codici della distinta, output). + sotto-componenti); `step/` non è scritta dall'app ma è dove l'utente esporta gli STEP a + mano con Creo Distributed Batch, a partire dai file trascinati da `raw/` in fase 5. ## Script standalone (`scripts/`)