Table of Contents

FLOW-BK-001 — Creazione di una richiesta di prenotazione (Demand) — Book

Flusso end-to-end di inserimento di una richiesta di prenotazione (entità Demand) del modulo Book (prenotazione/pianificazione risorse spaziali — distinto dal modulo legacy Booking*). Path pilota: creazione di un appuntamento sullo scheduler Schedule.ascx di BookCenterWeb. Backend Oracle INFOCAD_TEST38, accesso via stored procedure ODP.NET BOOK_INSERTDEMAND (nessun ORM). L'entità è persistita nella tabella BOOK_DEMAND.

  • Flow ID: FLOW-BK-001
  • Repository: InfocadWeb (BookCenterWeb, ASP.NET Web Forms + Telerik RadScheduler, code-behind C#) + InfocadServer (BookControllers/BookDAL, C#)
  • Operazione documentata: InsertDemand (WRITE autonomo — insert di BOOK_DEMAND)
  • Confidence complessiva: VERIFIED (catena UI → code-behind → controller → DAO → stored procedure, confermata su codice E su sorgente DB USER_SOURCE; forward/reverse concordi)

Obiettivo di business

Consentire a un utente autenticato di creare una richiesta di prenotazione (Demand) per una entità spaziale (es. una sala/vano) su un determinato tipo di orario, indicando oggetto, descrizione ed eventuale regola di ricorrenza. La Demand è il contenitore logico della prenotazione: alla sua creazione seguono una o più occorrenze temporali (Schedule) collegate. Al termine esiste una nuova riga in BOOK_DEMAND con id generato da sequenza, restituito al chiamante per agganciare gli Schedule.

Attori

  • Utente prenotante (autenticato, sessione WS.SessionLogin) — path interattivo scheduler Schedule.ascx di BookCenterWeb.
  • Operatore import massivo — path alternativo Excel ImportScheduleFromExcel.aspxBookBulkLoader (bulk load di prenotazioni storiche/pianificate).
  • Oracle INFOCAD_TEST38 — hub anagrafico; procedura BOOK_INSERTDEMAND, sequenza SEQ_BOOK_ID_DEMAND, tabelle BOOK_DEMAND (corrente) / BOOK_DEMAND_HISTORY (storico).

Trigger

Salvataggio di un nuovo appuntamento sul telerik:RadScheduler ID="schedBook": evento OnAppointmentInsert="schedBook_AppointmentInsert" (Schedule.ascx:73), gestito dal code-behind schedBook_AppointmentInsert (Schedule.ascx.cs:577).

Frontend entry point

  • Shell/UserControl: BookCenterWeb/UserControl/Schedule.ascx (scheduler prenotazioni) e relativo code-behind Schedule.ascx.cs.
  • Gate d'uso: l'appuntamento richiede la scelta di una entità spaziale (groupEntity) e di un tipo di orario (groupTime); in assenza il salvataggio è annullato con e.Cancel = true e alert client (Schedule.ascx.cs:579-601).

Sequenza principale (main sequence)

  1. L'utente crea un appuntamento sullo scheduler e conferma; RadScheduler solleva AppointmentInsert.
  2. schedBook_AppointmentInsert (Schedule.ascx.cs:577) valida presenza di entità (GroupEntity) e tipo orario (GroupTime); se mancanti → alert + e.Cancel = true (:579-601).
  3. Carica gli Schedule esistenti dell'entità (ctrl.GetScheduleByEntity, :603) e verifica sovrapposizioni di orario sulle occorrenze (ricorrenti o singola) — in caso di overlap alert + e.Cancel (:607-652).
  4. Popola un DemandDTO dai dati dell'appuntamento e di sessione: Username, Subject, Description, Entity, IdEntity, IdTimeType, RecurrenceRule, BookingTable (:654-665).
  5. Chiama il controller: demand.IdDemand = ctrl.InsertDemand(demand) (Schedule.ascx.cs:666).
  6. BookController.InsertDemand (BookController.cs:259) inoltra al DAO: ((IBook)base.DAO).InsertDemand(request) (:261) — DAO risolto da DaoActivate(enControllers.Ctrl_Book) nel costruttore (BookController.cs:15) → BookDAL (DAOFactory.cs:17).
  7. BookDAL.InsertDemand (BookDAL.cs:1664) apre un DataLayer(ConnectionName), prepara i parametri PTABLE, PSUBJECT, PDESCRIPTION, PRECURRENCE_RULE, PID_TIME_TYPE, PENTITY, PID_ENTITY, PID_USER, PID_CDP (IN) e PIDDEMAND (OUT), quindi invoca dl.ExecuteNonQueryStoredProcedure("BOOK_INSERTDEMAND") (:1693).
  8. Oracle BOOK_INSERTDEMAND (INFOCAD_TEST38):
    • genera l'id: PIDDEMAND := SEQ_BOOK_ID_DEMAND.NEXTVAL (src:13);
    • se PTABLE = 1 (CURRENT) → INSERT INTO BOOK_DEMAND (...) (src:15-21);
    • se PTABLE = 2 (HISTORY) → INSERT INTO BOOK_DEMAND_HISTORY (...) (src:26-32);
    • restituisce il nuovo id in PIDDEMAND.
  9. Il DAO legge PIDDEMAND e lo ritorna come idDemand (BookDAL.cs:1694); su fallimento ExecuteNonQuery ritorna -1 (:1696).
  10. Il code-behind aggancia l'id (schedule.IdDemand = demand.IdDemand, :667) e per ogni occorrenza chiama ctrl.InsertScheduleWithElement(schedule) (:688/:697) — path collegato (vedi Side effects), poi schedBook_Binding() per il refresh (:699).

API / service

  • Path interattivo: nessun servizio SOAP/WCF — postback ASP.NET Web Forms diretto sull'evento server-side del RadScheduler. Il BookController è invocato in-process (referenza a DLL Descor.Book.BookControllers / BookDAL).
  • Path programmatico equivalente: BookBulkLoader.InsertObject (BookBulkLoader.vb:373) usa lo stesso InsertDemand (:389) — qui il campo Ctrl è direttamente un Book.BookDAL.BookDAL (BookBulkLoader.vb:46-52), bypassando il controller.

Backend

  • UI/Code-behind: Schedule.ascx.cs (schedBook_AppointmentInsert).
  • Controller server: Descor.Book.BookControllers.BookController (BookController.cs), IBook (IBook.cs:66).
  • DAO/DAL: Descor.Book.BookDAL.BookDAL (BookDAL.cs).
  • Pattern DAL: using (DataLayer dl = new DataLayer(Properties.Settings.Default.ConnectionName))dl.Parameters.Add(new OracleParameter(...))dl.ExecuteNonQueryStoredProcedure("BOOK_INSERTDEMAND"); identity restituita via parametro OUT PIDDEMAND (NUMBER).

Query / stored procedure

Passo Stored procedure (Oracle) Chiamata da (DAL)
Insert richiesta prenotazione (INSERT su BOOK_DEMAND/BOOK_DEMAND_HISTORY, id da sequenza, OUT PIDDEMAND) INFOCAD_TEST38.BOOK_INSERTDEMAND BookDAL.cs:1693
Verifica sovrapposizioni orario (READ) INFOCAD_TEST38.BOOK_GETSCHEDULEBYENTITY BookDAL.cs:33 (via Schedule.ascx.cs:603)
Insert occorrenza collegata (path seguente) INFOCAD_TEST38.BOOK_INSERTSCHEDULEWITHELEMENT BookDAL.cs:875 (via Schedule.ascx.cs:688/697)

Tabelle lette (read)

  • INFOCAD_TEST38: BOOK_SCHEDULE/viste correlate (via BOOK_GETSCHEDULEBYENTITY, per il controllo overlap a monte dell'insert). La BOOK_INSERTDEMAND in sé non effettua letture (nessuna SELECT nel sorgente).

Tabelle modificate (write)

  • INFOCAD_TEST38: BOOK_DEMAND (RW — tabella-radice della richiesta di prenotazione corrente: INSERT di ID_DEMAND, SUBJECT, DESCRIPTION, RECURRENCE_RULE, ID_TIME_TYPE, ENTITY, ID_ENTITY, ID_USER, ID_CDP quando PTABLE = 1; VERIFIED su sorgente USER_SOURCE e su USER_TAB_COLUMNS).
  • INFOCAD_TEST38: BOOK_DEMAND_HISTORY (RW — variante storica, ramo PTABLE = 2; VERIFIED su sorgente).
  • Effetto indiretto: consumo di SEQ_BOOK_ID_DEMAND (NEXTVAL) per la PK (VERIFIED — sequenza esistente).
  • Nel path seguente (occorrenze): BOOK_SCHEDULE + BOOK_SCHEDULE_WF_INTERFACE (PTABLE=1) o BOOK_SCHEDULE_HISTORY + BOOK_SCHEDULE_WF_INTERFACE (PTABLE=2) via BOOK_INSERTSCHEDULEWITHELEMENT.

Validazione

  • Lato UI: obbligo di entità spaziale e tipo orario (Schedule.ascx.cs:579-601); controllo anti-sovrapposizione delle occorrenze sull'entità (:607-652, ExistsOccurenceInRangeDates); per le ricorrenze, verifica che la data inizio non superi la fine ricorrenza (:612-621).
  • Lato DB: BOOK_INSERTDEMAND non contiene validazioni condizionali oltre allo switch PTABLE (1/2); nessuna DML eseguita se PTABLE non è 1 né 2. Vincoli di integrità impliciti: ID_DEMAND, ID_USER, ID_CDP sono NOT NULL in BOOK_DEMAND (USER_TAB_COLUMNS).

Side effects

  • Generazione PK da SEQ_BOOK_ID_DEMAND.
  • Path collegato immediato: per ogni occorrenza dell'appuntamento il code-behind crea uno Schedule (InsertScheduleWithElement, Schedule.ascx.cs:688/697) che inserisce in BOOK_SCHEDULE e nella tabella di interfaccia workflow BOOK_SCHEDULE_WF_INTERFACE; la SP usa SAVEPOINT/ROLLBACK con RAISE (BOOK_INSERTSCHEDULEWITHELEMENT src:13,48-50).
  • Refresh dello scheduler lato UI (schedBook_Binding(), Schedule.ascx.cs:699).

Percorsi alternativi / di errore

  • Import massivo Excel: ImportScheduleFromExcel.aspxBookBulkLoader.InsertObject (BookBulkLoader.vb:373) risolve IdEntity da codice (GetIdEntityByCode, :386) e chiama InsertDemand (:389) + InsertSchedule (:398) — stessa BOOK_INSERTDEMAND. In caso di eccezione, log + alert riga e Return False (:400-405).
  • Errore DB: ExecuteNonQueryStoredProcedure = false ⇒ BookDAL.InsertDemand ritorna -1 (BookDAL.cs:1696); eccezioni loggate con ExceptionLogger.LogException e ri-sollevate (:1699-1702).
  • Aggiornamento: BOOK_UPDATEDEMAND (BookDAL.cs:1615); cancellazione: BOOK_DELETEDEMANDBYID (BookDAL.cs:1482) — controprove non distruttive sulla stessa tabella BOOK_DEMAND.

Diagramma di sequenza

sequenceDiagram
    actor Op as Utente prenotante
    participant UI as Schedule.ascx (RadScheduler)
    participant CB as Schedule.ascx.cs (schedBook_AppointmentInsert)
    participant BC as BookController.InsertDemand
    participant DAL as BookDAL.InsertDemand
    participant DB as Oracle INFOCAD_TEST38 (BOOK_INSERTDEMAND)

    Op->>UI: crea appuntamento + conferma
    UI->>CB: AppointmentInsert(e)
    CB->>CB: valida entità + tipo orario
    CB->>DB: GetScheduleByEntity (check overlap)
    CB->>CB: popola DemandDTO
    CB->>BC: InsertDemand(demand)
    BC->>DAL: ((IBook)DAO).InsertDemand(demand)
    DAL->>DB: BOOK_INSERTDEMAND (PTABLE, ..., OUT PIDDEMAND)
    alt PTABLE = 1 (CURRENT)
        DB->>DB: PIDDEMAND = SEQ_BOOK_ID_DEMAND.NEXTVAL
        DB->>DB: INSERT INTO BOOK_DEMAND (...)
    else PTABLE = 2 (HISTORY)
        DB->>DB: INSERT INTO BOOK_DEMAND_HISTORY (...)
    end
    DB-->>DAL: PIDDEMAND (nuovo id)
    DAL-->>BC: idDemand
    BC-->>CB: idDemand
    CB->>DB: InsertScheduleWithElement per occorrenza (BOOK_SCHEDULE)
    CB->>UI: schedBook_Binding() (refresh)

Matrice di tracciabilità (file:riga)

Livello Artefatto Riferimento
UI markup Wiring evento scheduler InfocadWeb/.../BookCenterWeb/UserControl/Schedule.ascx:73
Code-behind Handler schedBook_AppointmentInsert InfocadWeb/.../BookCenterWeb/UserControl/Schedule.ascx.cs:577
Code-behind Popolamento DTO + InsertDemand Schedule.ascx.cs:654-666
Interface IBook.InsertDemand InfocadServer/BookInterface/IBook.cs:66
Controller BookController.InsertDemand InfocadServer/BookControllers/BookController.cs:259-262
Controller DaoActivate(Ctrl_Book) BookController.cs:15 ; BookControllers/DAOFactory.cs:17
DAO/DAL BookDAL.InsertDemand (parametri + exec) InfocadServer/BookDAL/OracleODP/BookDAL.cs:1664-1704
DAL exec ExecuteNonQueryStoredProcedure("BOOK_INSERTDEMAND") BookDAL.cs:1693
DB (SP) BOOK_INSERTDEMAND (INSERT BOOK_DEMAND) USER_SOURCE BOOK_INSERTDEMAND src:13,17-20
DB (tabella) Colonne BOOK_DEMAND USER_TAB_COLUMNS
DB (reverse) Writer di BOOK_DEMAND USER_DEPENDENCIES
Path alt BookBulkLoader.InsertObjectInsertDemand InfocadServer/BulkLoaderManager/BookBulkLoader.vb:389

Evidenza (INLINE)

Vedi la sezione evidence_markdown restituita dal worker (estratti verbatim di codice e sorgente DB con file:riga).

Confidence

  • VERIFIED per la catena UI → code-behind → controller → DAO → SP → tabella: confermata sia sul codice (Schedule.ascx.cs, BookController.cs, BookDAL.cs) sia sul sorgente DB (USER_SOURCE.BOOK_INSERTDEMAND) e sul catalogo (USER_TAB_COLUMNS, USER_SEQUENCES, USER_DEPENDENCIES).
  • Forward/Reverse concordi: il forward arriva a BOOK_INSERTDEMAND/BOOK_DEMAND; il reverse (USER_DEPENDENCIES su BOOK_DEMAND) elenca BOOK_INSERTDEMAND tra i writer.
  • has_standalone_write = true: InsertDemand è un WRITE autonomo e pulito (insert di una entità radice senza dipendenze di orchestrazione lato SP).

Open questions

  • In Schedule.ascx.cs il DemandDTO valorizza Username ma non IdUser/IdCdp prima di InsertDemand (:654-666); poiché BOOK_DEMAND.ID_USER/ID_CDP sono NOT NULL, i valori effettivi passati (PID_USER/PID_CDP) sarebbero i default int = 0 a meno di valorizzazioni non individuate (es. costruttore DemandDTO o proprietà derivata da Username). Da verificare.
  • La colonna CREATED_AT di BOOK_DEMAND non è valorizzata da BOOK_INSERTDEMAND (assente dall'INSERT); presumibilmente NULL o gestita da trigger/BOOK_INSERTDEMANDPUTIDDEMAND. Non ispezionato.
  • Significato del modulo Book: confermato come sottosistema di prenotazione/pianificazione risorse (Demand = richiesta, Schedule = occorrenza, ConfortClass, workflow) — distinto dal legacy Booking*.