Vai al contenuto

IMPMER - Criticità e problemi rilevati

Analisi critica del programma di importazione/esportazione merci


🔴 Criticità ALTE (rischio elevato)

1. Concorrenza: Nomi file temporanei fissi

Location: Righe 1648-1666

Problema:

string ext-tmp-dir delimited " "
       ext-os-slash "impmer.txt"
       delimited size into w-ris-name

string ext-tmp-dir delimited " "
       ext-os-slash "import." tm-file-ext
       delimited size     into w-seq-name

I file temporanei hanno nomi fissi senza identificativo univoco: - impmer.txt (log risultati) - import.{ext} (file import temporaneo) - merci.csv (file export) - Riga 9360

Impatto: - ❌ Due utenti che eseguono contemporaneamente il programma si sovrascrivono i file - ❌ Possibile corruzione dati o perdita di log - ❌ Race condition su sistemi multi-utente

Soluzione suggerita:

*> Aggiungere timestamp o PID al nome file
accept ws-timestamp from time
string ext-tmp-dir delimited " "
       ext-os-slash "impmer-" ws-timestamp ".txt"
       delimited size into w-ris-name

2. Buffer overflow: Mancanza controlli lunghezza record

Location: Righe 9394-9462

Problema:

move spaces to c-record
move 1      to c-pnt
*> ... costruzione record senza controllo overflow
move c-valore (1:c-siz) to c-record (c-pnt:c-siz)
add c-siz               to c-pnt

Mancanza: - ❌ Nessun controllo che c-pnt + c-siz < k-len-record (8000) - ❌ Se la somma dei campi supera 8000, buffer overflow silenzioso - ❌ Possibile corruzione memoria o crash

Impatto: - Esportazioni con molti campi lunghi possono causare errori - Troncamento dati non segnalato

Soluzione suggerita:

if c-pnt + c-siz > k-len-record
   move "S" to tm-errori
   string "Record troppo lungo alla riga " tm-r-l
      delimited size into ris-rec
   write ris-rec
   go to c-10-loop
end-if

3. Inconsistenza ubicazioni: Logica di cancellazione parziale

Location: Righe 6953-7026, Righe 7031-7104

Problema:

when k-mer-ubi1-piano
   *> ... aggiornamento piano ...
   if lgm-posizione = spaces
      perform del-coglgmer    *> Cancellazione solo qui!
   end-if

La cancellazione dell'ubicazione vuota avviene solo quando si aggiorna il campo PIANO (ultimo campo).

Scenario problematico: 1. File Excel aggiorna solo MER-UBI1-BOX = vuoto 2. Non viene eseguito il check lgm-posizione = spaces 3. Record ubicazione rimane con campi parziali inconsistenti

Impatto: - ❌ Ubicazioni parzialmente svuotate rimangono nel database - ❌ Dati inconsistenti (es. solo corsia/colonna senza box) - ❌ Query su ubicazioni possono restituire risultati errati

Soluzione suggerita: Aggiungere il controllo di cancellazione in tutti i campi separati, non solo nell'ultimo.


4. Assenza gestione transazionale

Location: Tutto il programma

Problema:

*> Nessun START TRANSACTION
perform b3-aggiorna  *> Aggiorna record
*> Nessun COMMIT/ROLLBACK

Mancanza: - ❌ Nessuna gestione transazioni esplicita - ❌ Se l'import si interrompe a metà, database in stato inconsistente - ❌ Solo 2 unlock all alle righe 9195, 9203 (insufficienti)

Impatto: - Import di 10.000 righe si interrompe alla 5.000 - Le prime 5.000 rimangono salvate → database semi-aggiornato - Impossibile fare rollback

Soluzione suggerita: Implementare gestione transazionale con commit periodici (es. ogni 100 righe) e rollback in caso di errori critici.


🟠 Criticità MEDIE (rischio moderato)

5. Limiti hardcoded insufficienti

Location: Righe 67-69

Problema:

78 k-max-campi    value 500.
78 k-len-record   value 8000.
78 k-len-ris-rec  value 256.

Limitazioni: - Max 500 campi nell'import (attualmente 121 dopo aggiunta campi COGMERA4, ma futuro?) - Max 8000 caratteri per riga CSV (insufficiente per record con molti campi lunghi) - Max 256 caratteri per messaggio di log (troppo corto per errori dettagliati)

Impatto: - ⚠️ Impossibile gestire file con più di 500 colonne - ⚠️ Troncamento messaggi di errore nel log


6. Catena IF lunga e fragile per validazione campi

Location: Righe 1998-2130

Problema:

if tc-inf (n-tc) <> k-mer-gru          and
   tc-inf (n-tc) <> k-mer-sot          and
   tc-inf (n-tc) <> k-mer-cod          and
   tc-inf (n-tc) <> k-mer-descr        and
   *> ... 117+ condizioni in AND ...
   tc-inf (n-tc) <> k-mer-pua
   move "S"      to b1-campo-errato
end-if

Problemi: - ❌ 117+ condizioni in AND su singolo IF (difficilissimo da mantenere) - ❌ Se si aggiunge un nuovo campo, si deve ricordare di aggiornare questo IF - ❌ Errore umano facile: dimenticare un campo → campo valido rifiutato - ❌ Performance: O(n) per ogni campo di ogni riga

Impatto: - Manutenibilità pessima - Rischio alto di regressioni

Soluzione suggerita:

*> Usare tabella campi validi
set b1-campo-trovato to false
perform varying i-campo from 1 by 1
   until i-campo > n-campi-validi or b1-campo-trovato
   if tc-inf (n-tc) = tab-campi-validi (i-campo)
      set b1-campo-trovato to true
   end-if
end-perform
if not b1-campo-trovato
   move "S" to b1-campo-errato
end-if

7. Dipendenza da programma esterno per Excel

Location: Righe 1699-1706

Problema:

if function lower-case(tm-file-ext) = "xls" or "xlsx"
   call "ESTRXLS" using stringhe util-estrxls
   cancel "ESTRXLS"
end-if

Criticità: - ⚠️ Dipendenza forte da programma esterno ESTRXLS - ⚠️ Se ESTRXLS fallisce, nessun controllo dello stato di ritorno - ⚠️ Nessuna gestione errore se conversione fallisce

Impatto: - File Excel corrotto → conversione fallisce silenziosamente - Utente riceve errore generico "Archivio non aperto"


8. 251 GO TO nel programma

Location: Tutto il programma

Problema: Il programma contiene 251 istruzioni GO TO, rendendo il flusso molto difficile da seguire.

Esempi: - Riga 1687: go to a-tm-file - Riga 1788: go to b-10-loop - Riga 2079: go to a4

Impatto: - ⚠️ Manutenibilità ridotta - ⚠️ Difficile debugging - ⚠️ Rischio di loop infiniti o flussi errati

Best practice: Preferire PERFORM strutturato


🟡 Criticità BASSE (miglioramenti consigliati)

9. Mancanza validazioni campi obbligatori

Location: Sezione b3-aggiorna

Problema: Non ci sono controlli espliciti per campi obbligatori come: - MER-GRU (gruppo) - MER-SOT (sottogruppo) - MER-COD (codice) - MER-DESCR (descrizione)

Impatto: - Possibile creazione merci incomplete - Errori scoperti solo in fase di utilizzo


10. Logging insufficiente

Location: File impmer.txt

Problema: - ⚠️ Log messaggi troncati a 256 caratteri - ⚠️ Nessun livello di log (INFO/WARNING/ERROR) - ⚠️ Timestamp mancante nei messaggi - ⚠️ Nessuna statistica finale (record OK/KO)

Impatto: - Difficile debug di problemi complessi - Log non analizzabili automaticamente


11. Performance: Lettura sequenziale completa per export

Location: Righe 9478-9540

Problema:

c-10-loop.
   move "Leggi" to u16-ope
   perform z-u16
   *> Legge TUTTE le merci sequenzialmente

Criticità: - Esportazione di 100.000 articoli legge tutto l'archivio - Nessuna paginazione o batch processing - Filtri applicati dopo la lettura (non in query)

Impatto: - Performance scarse su archivi grandi - Memoria occupata per buffering


12. Assenza controllo versione formato file

Location: Nessuna

Problema: - ❌ Nessun controllo di versione nel formato import/export - ❌ Se cambia struttura file, vecchi file non riconoscibili - ❌ Nessun header con metadati (versione, data export, ecc.)

Impatto: - Import di file vecchi potrebbe causare errori silenti - Impossibile gestire retrocompatibilità


13. Thin client: Path hardcoded

Location: Righe 869-879

Problema:

if ext-thin-client = "S"
   *> Sostituzioni path server/client hardcoded
   move function lower-case(ext-server-path) to us-pub-target
   move function lower-case(ext-client-path) to us-pub-source
end-if

Criticità: - Path client/server configurati altrove ma logica qui - Sostituzione stringhe fragile


14. Gestione ubicazioni: Formato stringa vs campi separati

Location: Sezione ubicazioni

Problema architetturale: Supporto di due formati alternativi per ubicazioni: 1. Stringa unica: MER-UBICAZIONE = "A-12-05-03" 2. Campi separati: BOX, CORSIA, COLONNA, PIANO

Criticità: - ⚠️ Se file Excel mescola i due formati, comportamento indefinito - ⚠️ Nessun controllo di mutua esclusione - ⚠️ Documentazione insufficiente per l'utente

Scenario problematico:

MER-COD,MER-UBICAZIONE,MER-UBI1-BOX
00123,A-12-05-03,B

→ Cosa succede? Si sovrascrive o si aggiunge?

Soluzione: Validare che non vengano usati entrambi i formati per la stessa ubicazione.


📊 Riepilogo criticità

Livello Problema Impatto Priorità fix
🔴 ALTA Nomi file temporanei fissi Concorrenza ⭐⭐⭐⭐⭐
🔴 ALTA Buffer overflow export Sicurezza/Stabilità ⭐⭐⭐⭐⭐
🔴 ALTA Inconsistenza ubicazioni Integrità dati ⭐⭐⭐⭐
🔴 ALTA Assenza transazioni Integrità dati ⭐⭐⭐⭐
🟠 MEDIA Limiti hardcoded Scalabilità ⭐⭐⭐
🟠 MEDIA Catena IF lunghissima Manutenibilità ⭐⭐⭐
🟠 MEDIA Dipendenza ESTRXLS Affidabilità ⭐⭐⭐
🟠 MEDIA 251 GO TO Manutenibilità ⭐⭐
🟡 BASSA Validazioni insufficienti Qualità dati ⭐⭐
🟡 BASSA Logging migliorabile Supportabilità ⭐⭐
🟡 BASSA Performance export Performance
🟡 BASSA Versioning formato Evoluzione

🛠️ Raccomandazioni prioritarie

Immediato (settimane)

  1. Fix nomi file temporanei: Aggiungere PID/timestamp
  2. Aggiungere controlli buffer overflow: Validare c-pnt prima di scrivere
  3. Fix logica cancellazione ubicazioni: Estendere a tutti i campi

Breve termine (mesi)

  1. Implementare gestione transazionale: Commit batch + rollback
  2. Aumentare limiti: k-len-record a 16000, k-len-ris-rec a 1024
  3. Refactoring validazione campi: Usare tabella invece di IF gigante

Medio termine (trimestri)

  1. Ridurre GO TO: Ristrutturare flusso con PERFORM
  2. Aggiungere validazioni business: Campi obbligatori, vincoli
  3. Migliorare logging: Livelli, timestamp, statistiche

Lungo termine (anni)

  1. Ottimizzare performance export: Query con filtri, paginazione
  2. Aggiungere versioning formato: Header file con metadati
  3. Documentazione utente: Guida completa formato file

🧪 Suggerimenti per testing

Test di concorrenza

# Lanciare 5 importazioni simultanee
for i in {1..5}; do
  impmer input$i.xlsx &
done
wait
# Verificare che non ci siano corruzioni

Test limiti

# Creare file con 600 colonne (> k-max-campi)
# Creare riga CSV > 8000 caratteri
# Verificare gestione errore

Test rollback

# Import con 1000 righe, interrompere a metà
# Verificare stato database
# Dovrebbero esserci solo le prime N righe

📝 Note finali

Nonostante le criticità evidenziate, il programma IMPMER: - ✅ Funziona correttamente per casi d'uso standard - ✅ Ha una copertura funzionale molto ampia (117 campi) - ✅ Gestisce situazioni complesse (thin client, consorzi, ecc.)

Le criticità sono principalmente legate a: - Scenari limite (concorrenza, file molto grandi) - Robustezza e recovery da errori - Manutenibilità del codice

Un programma di refactoring graduale può risolvere le criticità più gravi mantenendo la compatibilità con gli usi esistenti.


Casistica problemi noti

Descrizioni aggiuntive con "a capo"

  • Sintomo: In esportazione, se le descrizioni aggiuntive contengono caratteri di "a capo", la riga di esportazione risulta malformata. In alcuni ambienti il processo termina silenziosamente per timeout del runtime.
  • Causa: IMPMER e GESSTR00 non sanificavano i newline nelle descrizioni aggiuntive. Il carattere spezzava la riga del tracciato di output. Nei clienti con molti articoli, l'elaborazione superava il timeout del thin client.
  • Correzione: Sanificazione dei newline prima dell'esportazione in IMPMER e GESSTR00. Aggiunta C$SLEEP ogni 10 record per prevenire il timeout.
  • Riferimento: dettaglioClickUp 8697w9zgp