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 legacyBooking*). Path pilota: creazione di un appuntamento sullo schedulerSchedule.ascxdiBookCenterWeb. Backend OracleINFOCAD_TEST38, accesso via stored procedure ODP.NETBOOK_INSERTDEMAND(nessun ORM). L'entità è persistita nella tabellaBOOK_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 diBOOK_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 schedulerSchedule.ascxdiBookCenterWeb. - Operatore import massivo — path alternativo Excel
ImportScheduleFromExcel.aspx→BookBulkLoader(bulk load di prenotazioni storiche/pianificate). - Oracle
INFOCAD_TEST38— hub anagrafico; proceduraBOOK_INSERTDEMAND, sequenzaSEQ_BOOK_ID_DEMAND, tabelleBOOK_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-behindSchedule.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 cone.Cancel = truee alert client (Schedule.ascx.cs:579-601).
Sequenza principale (main sequence)
- L'utente crea un appuntamento sullo scheduler e conferma; RadScheduler solleva
AppointmentInsert. schedBook_AppointmentInsert(Schedule.ascx.cs:577) valida presenza di entità (GroupEntity) e tipo orario (GroupTime); se mancanti → alert +e.Cancel = true(:579-601).- Carica gli
Scheduleesistenti dell'entità (ctrl.GetScheduleByEntity,:603) e verifica sovrapposizioni di orario sulle occorrenze (ricorrenti o singola) — in caso di overlap alert +e.Cancel(:607-652). - Popola un
DemandDTOdai dati dell'appuntamento e di sessione:Username,Subject,Description,Entity,IdEntity,IdTimeType,RecurrenceRule,BookingTable(:654-665). - Chiama il controller:
demand.IdDemand = ctrl.InsertDemand(demand)(Schedule.ascx.cs:666). BookController.InsertDemand(BookController.cs:259) inoltra al DAO:((IBook)base.DAO).InsertDemand(request)(:261) — DAO risolto daDaoActivate(enControllers.Ctrl_Book)nel costruttore (BookController.cs:15) →BookDAL(DAOFactory.cs:17).BookDAL.InsertDemand(BookDAL.cs:1664) apre unDataLayer(ConnectionName), prepara i parametriPTABLE,PSUBJECT,PDESCRIPTION,PRECURRENCE_RULE,PID_TIME_TYPE,PENTITY,PID_ENTITY,PID_USER,PID_CDP(IN) ePIDDEMAND(OUT), quindi invocadl.ExecuteNonQueryStoredProcedure("BOOK_INSERTDEMAND")(:1693).- 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.
- genera l'id:
- Il DAO legge
PIDDEMANDe lo ritorna comeidDemand(BookDAL.cs:1694); su fallimentoExecuteNonQueryritorna-1(:1696). - Il code-behind aggancia l'id (
schedule.IdDemand = demand.IdDemand,:667) e per ogni occorrenza chiamactrl.InsertScheduleWithElement(schedule)(:688/:697) — path collegato (vedi Side effects), poischedBook_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 DLLDescor.Book.BookControllers/BookDAL). - Path programmatico equivalente:
BookBulkLoader.InsertObject(BookBulkLoader.vb:373) usa lo stessoInsertDemand(:389) — qui il campoCtrlè direttamente unBook.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 OUTPIDDEMAND(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 (viaBOOK_GETSCHEDULEBYENTITY, per il controllo overlap a monte dell'insert). LaBOOK_INSERTDEMANDin sé non effettua letture (nessuna SELECT nel sorgente).
Tabelle modificate (write)
INFOCAD_TEST38:BOOK_DEMAND(RW — tabella-radice della richiesta di prenotazione corrente:INSERTdiID_DEMAND, SUBJECT, DESCRIPTION, RECURRENCE_RULE, ID_TIME_TYPE, ENTITY, ID_ENTITY, ID_USER, ID_CDPquandoPTABLE = 1; VERIFIED su sorgenteUSER_SOURCEe suUSER_TAB_COLUMNS).INFOCAD_TEST38:BOOK_DEMAND_HISTORY(RW — variante storica, ramoPTABLE = 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) oBOOK_SCHEDULE_HISTORY+BOOK_SCHEDULE_WF_INTERFACE(PTABLE=2) viaBOOK_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_INSERTDEMANDnon contiene validazioni condizionali oltre allo switchPTABLE(1/2); nessuna DML eseguita sePTABLEnon è 1 né 2. Vincoli di integrità impliciti:ID_DEMAND,ID_USER,ID_CDPsonoNOT NULLinBOOK_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 inBOOK_SCHEDULEe nella tabella di interfaccia workflowBOOK_SCHEDULE_WF_INTERFACE; la SP usaSAVEPOINT/ROLLBACKconRAISE(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.aspx→BookBulkLoader.InsertObject(BookBulkLoader.vb:373) risolveIdEntityda codice (GetIdEntityByCode,:386) e chiamaInsertDemand(:389) +InsertSchedule(:398) — stessaBOOK_INSERTDEMAND. In caso di eccezione, log + alert riga eReturn False(:400-405). - Errore DB:
ExecuteNonQueryStoredProcedure= false ⇒BookDAL.InsertDemandritorna-1(BookDAL.cs:1696); eccezioni loggate conExceptionLogger.LogExceptione ri-sollevate (:1699-1702). - Aggiornamento:
BOOK_UPDATEDEMAND(BookDAL.cs:1615); cancellazione:BOOK_DELETEDEMANDBYID(BookDAL.cs:1482) — controprove non distruttive sulla stessa tabellaBOOK_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.InsertObject → InsertDemand |
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_DEPENDENCIESsuBOOK_DEMAND) elencaBOOK_INSERTDEMANDtra 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.csilDemandDTOvalorizzaUsernamema nonIdUser/IdCdpprima diInsertDemand(:654-666); poichéBOOK_DEMAND.ID_USER/ID_CDPsonoNOT NULL, i valori effettivi passati (PID_USER/PID_CDP) sarebbero i defaultint = 0a meno di valorizzazioni non individuate (es. costruttoreDemandDTOo proprietà derivata daUsername). Da verificare. - La colonna
CREATED_ATdiBOOK_DEMANDnon è valorizzata daBOOK_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*.