Table of Contents

FLOW-ACC-001 — Emissione di uno Stato Avanzamento Lavori (SAL) — Contabilità lavori

Flusso end-to-end di creazione/aggiornamento di uno SAL (Stato Avanzamento Lavori) del modulo Contabilità lavori (WorkAccounting). Path pilota: wizard SalPageWizard.aspx del WorkAccountingWeb (compilazione interattiva da parte di un operatore di contabilità lavori). Backend Oracle INFOCAD_TEST38, accesso via stored procedure ODP.NET WRKACC_INSERTSAL (nessun ORM). L'entità è persistita nella tabella-radice WORK_ACC_SAL con le righe di dettaglio in WORK_ACC_SAL_DETAILS e le allocazioni su WORK_ACC_FINANCING_DET_ALLOC / WORK_ACC_BDG_COSTS_DET_ALLOC.

  • Flow ID: FLOW-ACC-001
  • Repository: InfocadWeb (ASP.NET Web Forms, C#, WorkAccountingWeb sotto CASSANDRA) + InfocadServer (WorkAccountingControllersWorkAccountingDAL, C#)
  • Confidence complessiva: VERIFIED (catena UI → code-behind → controller → DAO → stored procedure, confermata su codice E su sorgente DB USER_SOURCE; tabelle scritte confermate su USER_DEPENDENCIES + sorgente della procedura + trigger di identity)

Obiettivo di business

Consentire a un operatore della Contabilità lavori di emettere uno Stato Avanzamento Lavori (SAL) per un anno fiscale/contratto: selezionare le voci di costo da pagare, i finanziamenti che le coprono, compilare la testata (contratto, firmatario, aliquota IVA, descrizione, data, flag storno) e salvare. Al termine lo SAL esiste in WORK_ACC_SAL con un progressivo per anno fiscale, le sue righe di dettaglio in WORK_ACC_SAL_DETAILS, e le allocazioni verso finanziamenti e costi di budget aggiornate in WORK_ACC_FINANCING_DET_ALLOC e WORK_ACC_BDG_COSTS_DET_ALLOC.

Attori

  • Operatore Contabilità lavori (utente autenticato Cassandra) — path interattivo wizard SalPageWizard.aspx (la code-behind eredita da Cassandra.InfocadSecurity.CassandraPage, SalPageWizard.aspx.cs:17).
  • WorkAccountingController (server) — proxy verso il DAO ospitato dal servizio Infocad.
  • Oracle INFOCAD_TEST38 — procedura standalone WRKACC_INSERTSAL (upsert transazionale dello SAL); sequenza SEQ_WORK_ACC_SAL + trigger di identity sulla tabella WORK_ACC_SAL.

Trigger

Click sul pulsante Avanti/Fine del wizard sull'ultimo step: evento RadWizard1_NextButtonClick (SalPageWizard.aspx.cs:107, dichiarato in markup OnNextButtonClick="RadWizard1_NextButtonClick", SalPageWizard.aspx:161). Il salvataggio effettivo avviene quando lo step attivo è RadWizardStep5 (SalPageWizard.aspx.cs:185).

Frontend entry point

  • Pagina wizard: WebMachine/CASSANDRA/WorkAccountingWeb/WindowsPage/SalPageWizard.aspx (telerik:RadWizard a 5 step: scelta voci → finanziamenti → testata → salvataggio → completa, SalPageWizard.aspx:156-181).
  • UserControl di step: SalCostsPage.ascx, SalFinancingsPage.ascx, SalHeaderPage.ascx (i dati intermedi transitano in Session["SALPAYMENTS"], Session["EXPENSECHART"], Session["SUMMARYSAL"]).
  • Contesto: la pagina è invocata come finestra (query string salID, fiscalYearID, salType, SalPageWizard.aspx.cs:76-97); salID>0 ⇒ modifica di uno SAL esistente, altrimenti nuovo.

Sequenza principale (main sequence)

  1. Operatore percorre gli step del wizard: sceglie le voci di costo (RadWizardStep1/2), i finanziamenti (RadWizardStep3) con controlli di quadratura importi (SalPayments vs ExpenseChart, SalPageWizard.aspx.cs:160-169), compila la testata (RadWizardStep4).
  2. Sull'ultimo passaggio (step attivo RadWizardStep5), RadWizard1_NextButtonClick (:107) entra nel ramo if (rws.ID == "RadWizardStep5") (:185).
  3. La code-behind costruisce l'oggetto WorkAccountingSal dai controlli della testata (rcbContract, rcbSignFrom, rcbTaxRate, rtbDescription, rtbNote, rdpDataSal, cbReversalSal; :219-230) e le liste parallele di dettaglio dalla DataTable di sessione SALPAYMENTS: idsCostFinancing(IDBCD), idsFinancing(IDFD), financingsAmount, descriptions (:232-239) e l'aggregazione per costo idsCost/costsAmount (:242-249).
  4. Chiama il controller in-process _wacCtrl.InsertSal(sal, idsFinancing, financingsAmount, idsCostFinancing, idsCost, costsAmount, descriptions) (:253).
  5. WorkAccountingController.InsertSal (WorkAccountingController.cs:164) inoltra al DAO: ((IWorkAccounting)this.DAO).InsertSal(...) (:166). Il DAO è risolto in Ctrl_Base.DaoActivateDAOFactory.CreateDAO via .NET Remoting (Activator.GetObject(typeof(IWorkAccounting), ...), DAOFactory.cs:16), quindi la chiamata è marshalata al servizio Infocad che ospita WorkAccounting_DAL.
  6. WorkAccounting_DAL.InsertSal (WorkAccounting_DAL.cs:1023):
    • apre DataLayer(ConnectionName) (:1033);
    • costruisce i parametri scalari di testata (PIDSAL, PIDCONTR, PIDFY, PIDSIGN, PIDRATE, PDESCRIPTION, PNOTE, PDATASAL, PREVERSAL; :1035-1043);
    • costruisce i parametri array PL/SQL (PIDFIN, FINAMOUNT, PIDCOSTFIN, PIDCOST, COSTAMOUNT, DESCRIPTION) come PLSQLAssociativeArray (:1045-1070);
    • aggiunge il parametro OUT POUT (:1052);
    • invoca dl.ExecuteNonQueryStoredProcedure("WRKACC_INSERTSAL") (:1092) e restituisce ((OracleDecimal)pout.Value).ToInt32() (:1094).
  7. Oracle WRKACC_INSERTSAL (INFOCAD_TEST38, procedura standalone; transazione unica):
    • forza le NLS numeriche di sessione (ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ".,", src:26);
    • decide create vs update su PIDSAL:
      • UPDATE (PIDSAL > 0, src:30-45): cancella i dettagli/allocazioni esistenti (DELETE WORK_ACC_SAL_DETAILS/WORK_ACC_FINANCING_DET_ALLOC/WORK_ACC_BDG_COSTS_DET_ALLOC WHERE IDSAL = :id) e aggiorna la testata (UPDATE WORK_ACC_SAL SET ... MODIFIED = SYSDATE);
      • INSERT (altrimenti, src:46-58): calcola il progressivo di anno fiscale (SELECT NVL(MAX(PROGRSAL),0) ... WHERE IDFY = PIDFY), esegue INSERT INTO WORK_ACC_SAL (...) VALUES (..., PROGRSAL+1) e legge il nuovo id con PSALID := SEQ_WORK_ACC_SAL.CURRVAL (src:57; l'IDSAL è valorizzato dal trigger, vedi sotto);
    • ciclo dettagli su PIDCOSTFIN.FIRST..LAST (src:63-76): per ogni riga inserisce in WORK_ACC_SAL_DETAILS (IDSAL, IDBCD, IDFD, DESCRIPTION, AMOUNT) e in WORK_ACC_FINANCING_DET_ALLOC (IDFD, IDSAL, ALLOCATED_AMOUNT);
    • ciclo costi di periodo su PIDCOST.FIRST..LAST (src:80-101): legge l'aliquota IVA (JOIN WORK_ACC_BUDGET_COSTS_DETAILS / WORK_ACC_TAXRATE), scorpora l'IVA (TEMPCOSTAMOUNT/(1+RATE)) e inserisce l'allocazione in WORK_ACC_BDG_COSTS_DET_ALLOC;
    • COMMIT e POUT := 1 (successo, src:104-108); in EXCEPTION WHEN OTHERS fa ROLLBACK e POUT := 0 (src:110-116).
  8. Trigger di identity WORK_ACC_SAL (INSERT, ENABLED): se :new.IDSAL IS NULL assegna SEQ_WORK_ACC_SAL.NEXTVAL; blocca l'update di IDSAL — da cui il CURRVAL letto dalla procedura è coerente con l'id appena generato (VERIFIED su USER_TRIGGERS).
  9. Il DAL propaga POUT (1/0) al controller e alla code-behind (int ret, :253).
  10. Post-salvataggio: la code-behind rimuove le sessioni SALPAYMENTS/EXPENSECHART/SUMMARYSAL (:257-259) e chiude la finestra client (CloseWindow(), :262).

API / service

  • Path interattivo: nessun servizio SOAP/WCF esposto lato web — postback ASP.NET Web Forms diretto sul wizard.
  • Path server: il controller comunica col DAO tramite .NET Remoting (Activator.GetObject, canale/indirizzo da Descor.Common.Configuration.SettingsManager.CHANNEL/SERVERADDRESS, DAOFactory.cs:16), non via WCF. Nel caso di co-hosting il proxy risolve comunque l'interfaccia IWorkAccounting.

Backend

  • UI/Code-behind: SalPageWizard.aspx (wizard) + SalPageWizard.aspx.cs.
  • Controller server: Descor.WorkAccounting.WorkAccountingControllers.WorkAccountingController (WorkAccountingController.cs), erede di Ctrl_Base (Ctrl_Base.cs:9), che espone DAO (Ctrl_Base.cs:13) risolto in DaoActivateDAOFactory.CreateDAO (Ctrl_Base.cs:19-21).
  • DAO: Descor.WorkAccounting.WorkAccountingDAL.OracleODP.WorkAccounting_DAL (WorkAccounting_DAL.cs:17, implementa IWorkAccounting), connessione da Properties.Settings.Default.ConnectionName (:19-23).
  • Pattern DAL: using (DataLayer dl = new DataLayer(ConnectionName))dl.Parameters.Add(OracleParameter...) (scalari + PLSQLAssociativeArray per gli array) → dl.ExecuteNonQueryStoredProcedure("WRKACC_INSERTSAL"); esito via parametro OUT POUT.

Query / stored procedure

Passo Stored procedure (Oracle) Chiamata da (DAL)
Upsert SAL (INSERT/UPDATE testata + dettagli + allocazioni) INFOCAD_TEST38.WRKACC_INSERTSAL (OUT POUT NUMBER: 1 ok / 0 errore) WorkAccounting_DAL.cs:1092
Lettura aliquota IVA per scorporo (dentro la proc) SELECT WORK_ACC_TAXRATE.RATE JOIN WORK_ACC_BUDGET_COSTS_DETAILS WRKACC_INSERTSAL src:84-89
Load testata SAL (READ-ONLY, per la modifica) INFOCAD_TEST38.WRKACC_GETHEADERSALBYID WorkAccounting_DAL.cs:951
Load dettagli SAL (READ-ONLY) INFOCAD_TEST38.WRKACC_GETDETAILSSALBYID WorkAccounting_DAL.cs:1007
Chiusura/emissione SAL (path correlato) INFOCAD_TEST38.WRKACC_CLOSESAL WorkAccounting_DAL.cs:1236
Cancellazione SAL (path alternativo) INFOCAD_TEST38.WRKACC_DELETESAL WorkAccounting_DAL.cs:979

Tabelle lette (read)

  • INFOCAD_TEST38: WORK_ACC_BUDGET_COSTS_DETAILS, WORK_ACC_TAXRATE (lettura aliquota per lo scorporo IVA, src:84-89); WORK_ACC_SAL (calcolo MAX(PROGRSAL) per anno fiscale, src:48-51); SEQ_WORK_ACC_SAL (CURRVAL, src:57); DUAL.
  • Da USER_DEPENDENCIES di WRKACC_INSERTSAL: HELPERS (tipi tabella PL/SQL NUMBERLIST/STRINGLIST), SEQ_WORK_ACC_SAL, DUAL, oltre alle tabelle sopra.

Tabelle modificate (write)

  • INFOCAD_TEST38: WORK_ACC_SAL (RW — testata SAL: INSERT con progressivo PROGRSAL+1 e IDSAL da trigger/sequenza, oppure UPDATE WHERE IDSAL = :id; VERIFIED su sorgente, USER_DEPENDENCIES e USER_TAB_COLUMNS), WORK_ACC_SAL_DETAILS (RW — righe di dettaglio: DELETE+reinsert su update, INSERT in ciclo), WORK_ACC_FINANCING_DET_ALLOC (RW — allocazioni sui finanziamenti: DELETE+reinsert / INSERT), WORK_ACC_BDG_COSTS_DET_ALLOC (RW — allocazioni sui costi di budget scorporate IVA: DELETE+reinsert / INSERT).

Validazione

  • Lato UI (wizard): quadratura tra pagamenti SAL ed esborsi (totSal != totExpenseNotifyMessage e ritorno allo step precedente, SalPageWizard.aspx.cs:160-169); presenza di almeno una voce di spesa (countExpense == 0, :117-125); presenza di pagamenti (countSalPayments == 0, :138-143); corrispondenza tra righe EXPENSECHART e SALPAYMENTS (:146-157); con EnabledServiceSAP controllo di un solo fornitore per SAL (:190-198). Validazione ASP.NET ValidationGroup="headersave" sugli step testata (SalPageWizard.aspx:170,173).
  • Lato DB: la procedura è transazionale — l'intero upsert (testata + dettagli + allocazioni) è racchiuso tra l'implicito BEGIN e il COMMIT finale; ogni eccezione provoca ROLLBACK e POUT = 0 (src:104,110-116), quindi nessuna riga viene persistita in caso di errore. Su update i dettagli/allocazioni precedenti vengono cancellati prima di reinserire (idempotenza dello SAL, src:34-41).

Side effects

  • Generazione dell'identity IDSAL tramite SEQ_WORK_ACC_SAL.NEXTVAL (trigger di INSERT su WORK_ACC_SAL).
  • Progressivo SAL per anno fiscale (PROGRSAL = MAX+1, src:48-56).
  • Stamping temporale (CREATED/MODIFIED = SYSDATE) e reset flag ISCANCELLED = 0 (src:44,54,56,69,...).
  • Alterazione delle NLS numeriche di sessione (NLS_NUMERIC_CHARACTERS = ".,", src:26) senza ripristino esplicito (l'alter vale per la sessione corrente del pool).
  • Scorporo IVA sulle allocazioni di costo (AMOUNT/(1+RATE), src:91-92).
  • Pulizia delle variabili di sessione web (SALPAYMENTS/EXPENSECHART/SUMMARYSAL, :257-259).

Percorsi alternativi / di errore

  • Modifica SAL esistente: stessa procedura con PIDSAL > 0 (ramo UPDATE): DELETE dei dettagli/allocazioni
    • UPDATE testata, poi reinserimento dei dettagli (src:30-45).
  • Errore DB / eccezione: WHEN OTHERSROLLBACK + POUT = 0 (src:110-116); il DAL restituisce 0 al controller; la code-behind non distingue l'errore (vedi Open questions).
  • Chiusura/emissione: WRKACC_CLOSESAL (WorkAccounting_DAL.cs:1236) — path separato che marca lo SAL come emesso/chiuso.
  • Cancellazione: WRKACC_DELETESAL (WorkAccounting_DAL.cs:979) — controprova non distruttiva sul dominio.
  • Verifiche di eliminabilità/emissione: WRKACC_CANSALTOBEDEL / WRKACC_CANSALTOBEISSUED (WorkAccounting_DAL.cs:1938,1963).

Diagramma di sequenza

sequenceDiagram
    actor Op as Operatore Contabilità lavori
    participant UI as SalPageWizard.aspx (RadWizard)
    participant CB as SalPageWizard.aspx.cs (NextButtonClick)
    participant WC as WorkAccountingController.InsertSal
    participant DAO as WorkAccounting_DAL.InsertSal
    participant DB as Oracle INFOCAD_TEST38 (WRKACC_INSERTSAL)

    Op->>UI: percorre wizard (voci, finanziamenti, testata) + Fine
    UI->>CB: RadWizard1_NextButtonClick (step RadWizardStep5)
    CB->>CB: build WorkAccountingSal + liste dettaglio (da Session)
    CB->>WC: InsertSal(sal, idsFinancing, financingsAmount, idsCostFin, idsCost, costsAmount, descriptions)
    WC->>DAO: (IWorkAccounting via .NET Remoting) InsertSal(...)
    DAO->>DB: WRKACC_INSERTSAL (scalari + array PL/SQL, OUT POUT)
    alt PIDSAL = 0 (nuovo SAL)
        DB->>DB: INSERT WORK_ACC_SAL (PROGRSAL+1) -> trigger SEQ_WORK_ACC_SAL.NEXTVAL
        DB->>DB: loop INSERT WORK_ACC_SAL_DETAILS + WORK_ACC_FINANCING_DET_ALLOC
        DB->>DB: loop INSERT WORK_ACC_BDG_COSTS_DET_ALLOC (scorporo IVA)
    else PIDSAL > 0 (modifica)
        DB->>DB: DELETE dettagli/allocazioni + UPDATE WORK_ACC_SAL
        DB->>DB: reinserimento dettagli/allocazioni
    end
    DB->>DB: COMMIT
    DB-->>DAO: POUT = 1 (ok) | 0 (errore, ROLLBACK)
    DAO-->>WC: int (1/0)
    WC-->>CB: ret
    CB-->>Op: pulizia Session + CloseWindow()

Matrice di tracciabilità

Layer Artefatto Evidenza (file:riga)
UI SalPageWizard.aspx (RadWizard 5 step) WorkAccountingWeb/WindowsPage/SalPageWizard.aspx:156-181
UI (trigger) OnNextButtonClick="RadWizard1_NextButtonClick" SalPageWizard.aspx:161
Code-behind RadWizard1_NextButtonClick → ramo RadWizardStep5 SalPageWizard.aspx.cs:107,185
Code-behind build WorkAccountingSal + liste dettaglio SalPageWizard.aspx.cs:219-249
Code-behind _wacCtrl.InsertSal(...) SalPageWizard.aspx.cs:253
Controller WorkAccountingController.InsertSalDAO WorkAccountingController.cs:164,166
Controller (wiring) Ctrl_Base.DAO / DaoActivateDAOFactory.CreateDAO (.NET Remoting) Ctrl_Base.cs:13,19-21; DAOFactory.cs:16
DAO WorkAccounting_DAL.InsertSal (params + array PL/SQL) WorkAccounting_DAL.cs:1023,1035-1070,1052
DAO → DB ExecuteNonQueryStoredProcedure("WRKACC_INSERTSAL") + return POUT WorkAccounting_DAL.cs:1092,1094
DB WRKACC_INSERTSAL firma USER_SOURCE WRKACC_INSERTSAL src:1-16
DB decisione INSERT/UPDATE su PIDSAL src:29-59
DB INSERT WORK_ACC_SAL + progressivo src:48-57
DB ciclo dettagli WORK_ACC_SAL_DETAILS / WORK_ACC_FINANCING_DET_ALLOC src:63-76
DB ciclo allocazioni costo WORK_ACC_BDG_COSTS_DET_ALLOC + scorporo IVA src:80-101
DB COMMIT/POUT=1; EXCEPTION/ROLLBACK/POUT=0 src:104-116
DB (trigger) identity IDSAL da SEQ_WORK_ACC_SAL.NEXTVAL USER_TRIGGERS WORK_ACC_SAL (INSERT, ENABLED)
DB (schema) WORK_ACC_SAL colonne IDSAL,IDCONTR,IDFY,IDSIGN,IDTR,DESCRIPTION,NOTE,DATASAL,CREATED,MODIFIED,ISCANCELLED,ISCLOSED,ISREVERSAL,DATAISSUE,PROGRSAL USER_TAB_COLUMNS

Reverse trace (dal DB/DAL ai chiamanti)

  • WRKACC_INSERTSAL è invocata solo da WorkAccounting_DAL.InsertSal (WorkAccounting_DAL.cs:1092; unica occorrenza in repo).
  • WorkAccounting_DAL.InsertSal implementa IWorkAccounting.InsertSal (IWorkAccounting.cs:65), esposta da WorkAccountingController.InsertSal (WorkAccountingController.cs:164).
  • WorkAccountingController.InsertSal è chiamata solo dal wizard SalPageWizard.aspx.cs:253 (unica occorrenza \.InsertSal( in WorkAccountingWeb).
  • USER_DEPENDENCIES di WRKACC_INSERTSAL elenca le tabelle scritte/lette (WORK_ACC_SAL, WORK_ACC_SAL_DETAILS, WORK_ACC_FINANCING_DET_ALLOC, WORK_ACC_BDG_COSTS_DET_ALLOC, WORK_ACC_BUDGET_COSTS_DETAILS, WORK_ACC_TAXRATE) + SEQ_WORK_ACC_SAL
    • HELPERS — coerente al 100% con il sorgente della procedura.
  • Forward e reverse concordano (wizard → InsertSalWRKACC_INSERTSALWORK_ACC_SAL(_DETAILS)
    • allocazioni) → NO CONFLICTING.
  • Semantica create vs update pilotata da PIDSAL (0/NULL ⇒ INSERT; >0 ⇒ UPDATE con delete+reinsert dei dettagli) — WRKACC_INSERTSAL src:29-59.
  • Progressivo SAL per anno fiscale (PROGRSAL) calcolato come MAX(PROGRSAL WHERE IDFY)+1 — non sequenziale globale ma per IDFY (src:48-56).
  • Identity IDSAL gestita da trigger + SEQ_WORK_ACC_SAL (non nella INSERT list; CURRVAL riletto dopo).
  • Gli importi arrivano come stringhe e vengono normalizzati con REPLACE(...,',','.') + NLS_NUMERIC_CHARACTERS='.,' (locale-safe, src:26,69,74,91,97).
  • Le allocazioni di costo sono registrate al netto IVA (scorporo con l'aliquota da WORK_ACC_TAXRATE, src:84-97), mentre le allocazioni di finanziamento sono al lordo dell'importo indicato.

Evidenza (file:line)

Punti chiave (codice): SalPageWizard.aspx:156-181,161; SalPageWizard.aspx.cs:17,76-97,107,185,219-249,253,257-262; WorkAccountingController.cs:13-16,164,166; Ctrl_Base.cs:9,13,19-21; DAOFactory.cs:10-16; IWorkAccounting.cs:65; WorkAccounting_DAL.cs:17,19-23,1023,1033,1035-1070,1052,1092,1094.

Punti chiave (DB, INFOCAD_TEST38, letti in sola lettura via USER_SOURCE/USER_DEPENDENCIES/USER_TAB_COLUMNS/USER_TRIGGERS): WRKACC_INSERTSAL è PROCEDURE standalone VALID (118 righe di sorgente); firma src:1-16; NLS src:26; decisione INSERT/UPDATE src:29-59; INSERT WORK_ACC_SAL + progressivo src:48-57; ciclo dettagli/finanziamenti src:63-76; ciclo costi + scorporo IVA src:80-101; COMMIT/POUT=1 src:104-108; EXCEPTION/ROLLBACK/POUT=0 src:110-116. Dipendenze (USER_DEPENDENCIES): tabelle WORK_ACC_SAL, WORK_ACC_SAL_DETAILS, WORK_ACC_FINANCING_DET_ALLOC, WORK_ACC_BDG_COSTS_DET_ALLOC, WORK_ACC_BUDGET_COSTS_DETAILS, WORK_ACC_TAXRATE; sequenza SEQ_WORK_ACC_SAL; package HELPERS; synonym DUAL. Trigger di INSERT su WORK_ACC_SAL (ENABLED) che assegna SEQ_WORK_ACC_SAL.NEXTVAL a IDSAL.

Confidence

  • VERIFIED: catena UI → code-behind → controller → DAO → nome stored procedure (letta sui sorgenti) e sorgente della procedura WRKACC_INSERTSAL (INSERT/UPDATE su WORK_ACC_SAL + dettagli/allocazioni) letto da USER_SOURCE; tabelle scritte confermate da USER_DEPENDENCIES + sorgente; identity da USER_TRIGGERS; colonne da USER_TAB_COLUMNS. (≥3 tipi di evidenza indipendenti: codice C#, sorgente PL/SQL, cataloghi Oracle).
  • SUPPORTED: semantica esatta dello scorporo IVA e del progressivo per anno fiscale (confermata da sorgente ma senza esecuzione runtime).
  • INFERRED: comportamento del ramo UPDATE lato UI (la pagina passa salID in query string, ma il percorso interattivo pilotato è la creazione; l'update condivide la stessa procedura).

Open questions

  • Il valore restituito POUT è 1/0 (successo/errore), NON il nuovo IDSAL: la code-behind assegna int ret = _wacCtrl.InsertSal(...) ma non lo usa per notificare l'esito all'operatore (SalPageWizard.aspx.cs:253) — comportamento in caso di POUT=0 (errore DB) non gestito a UI.
  • L'ALTER SESSION SET NLS_NUMERIC_CHARACTERS (src:26) non viene ripristinato: possibile effetto collaterale sul connection pool per chiamate successive.
  • Ruolo esatto di PDATASAL/DATAISSUE/ISCLOSED nel ciclo di vita SAL (emissione via WRKACC_CLOSESAL non tracciata in dettaglio in questo flusso).
  • Grant/permessi Cassandra applicati prima del salvataggio (la pagina eredita da CassandraPage ma il gate di autorizzazione specifico per l'operazione SAL non è stato ispezionato).
  • Comportamento in configurazioni PROD (osservato solo ambiente TEST38).