Vai al contenuto

# Triggers Database

Questa cartella contiene la documentazione di tutti i 19 triggers del database (esclusi quelli di sistema APEX).

## Triggers Generazione ID

Questi triggers generano automaticamente gli ID tramite sequence.

Trigger | Tabella | Sequence | Evento
--- | --- | --- | ---
EVENTI_TRG | EVENTI | EVENTI_SEQ | BEFORE INSERT
EVENTI_DET_PREL_TRG | EVENTI_DET_PREL | EVENTI_DET_PREL_SEQ | BEFORE INSERT
EVENTI_DET_RIS_TRG | EVENTI_DET_RIS | EVENTI_DET_RIS_SEQ | BEFORE INSERT
EVENTI_DET_DEGUST_TRG | EVENTI_DET_DEGUST | EVENTI_DET_DEGUST_SEQ | BEFORE INSERT
EVENTI_ACCONTI_TRG | EVENTI_ACCONTI | EVENTI_ACCONTI_SEQ | BEFORE INSERT
EVENTI_ALTRICOSTI_TRG | EVENTI_ALTRICOSTI | EVENTI_ALTRICOSTI_SEQ | BEFORE INSERT
EVENTI_ALLEG_TRG | EVENTI_ALLEG | EVENTI_ALLEG_SEQ | BEFORE INSERT
CLIENTI_TRG | CLIENTI | CLIENTI_SEQ2 | BEFORE INSERT
LOCATION_TRG | LOCATION | LOCATION_SEQ | BEFORE INSERT
RISORSE_TRG | RISORSE | RISORSE_SEQ | BEFORE INSERT
ARTICOLI_DET_REGOLE_TRG | ARTICOLI_DET_REGOLE | ARTICOLI_DET_REGOLE_SEQ | BEFORE INSERT
TB_TIPI_PASTO_TRG | TB_TIPI_PASTO | TB_TIPI_PASTO_SEQ | BEFORE INSERT

## Triggers Business Logic

Trigger | Tabella | Descrizione
--- | --- | ---
EVENTI_TRG | EVENTI | Inizializza STATO=100, DATA_DOC, VERS_TOKEN
EVENTI_AI_TRG | EVENTI | Crea 4 record ospiti default (AFTER INSERT)
EVENTI_DET_OSPITI_TRG_AI | EVENTI_DET_OSPITI | Gestione aggiornamento ospiti
EVENTI_DET_PREL_QTA_TOT_TRG | EVENTI_DET_PREL | Calcola QTA totale su UPDATE

## Triggers Ordinamento

Trigger | Tabella | Descrizione
--- | --- | ---
ADD_COD_STEP | TB_TIPI_MAT | Assegna COD_STEP progressivo
ON_DELETE_REORDER | TB_TIPI_MAT | Riordina COD_STEP dopo DELETE

## Triggers Sistema

Trigger | Tabella | Descrizione
--- | --- | ---
BI_GL_SCHEMA_CHANGES | GL_SCHEMA_CHANGES | Log modifiche schema
XLIB_LOGS_BI_TRG | XLIB_LOGS | Timestamp log

## Dettaglio Triggers Critici

### EVENTI_TRG

    BEFORE INSERT ON EVENTI FOR EACH ROW

Logica: 1. Genera ID da sequence 2. Imposta `DATA_DOC = SYSDATE` 3. Se INSERT: - `STATO = NVL(:NEW.STATO, 100)` - Se `VERS_NUMBER = 0`: genera `VERS_TOKEN` random

### EVENTI_AI_TRG

    AFTER INSERT ON EVENTI FOR EACH ROW

Logica: Inserisce automaticamente i 4 tipi ospiti: - COD_TIPO_OSPITE = 8 (Adulti), ORDINE = 1 - COD_TIPO_OSPITE = 5 (Kinder), ORDINE = 2 - COD_TIPO_OSPITE = 6 (Baby), ORDINE = 3 - COD_TIPO_OSPITE = 7 (Staff), ORDINE = 4

### EVENTI_DET_PREL_QTA_TOT_TRG

    BEFORE UPDATE ON EVENTI_DET_PREL FOR EACH ROW

Logica:

    :NEW.QTA := :NEW.QTA_APE + :NEW.QTA_SEDU + :NEW.QTA_BUFDOL
              + :NEW.QTA_MAN_APE + :NEW.QTA_MAN_SEDU + :NEW.QTA_MAN_BUFDOL

## Migrazione .NET

### Sostituzione Sequence → Identity

    // Entity Framework Configuration
    modelBuilder.Entity<Evento>()
        .Property(e => e.Id)
        .UseIdentityColumn();

### Sostituzione Trigger → SaveChanges Interceptor

    public class EventiSaveChangesInterceptor : SaveChangesInterceptor
    {
        public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
            DbContextEventData eventData,
            InterceptionResult<int> result,
            CancellationToken cancellationToken = default)
        {
            var context = eventData.Context;

            foreach (var entry in context.ChangeTracker.Entries<Evento>())
            {
                if (entry.State == EntityState.Added)
                {
                    // Logica EVENTI_TRG
                    entry.Entity.Stato ??= 100;
                    entry.Entity.DataDoc = DateTime.Now;
                    if (entry.Entity.VersNumber == 0)
                    {
                        entry.Entity.VersToken = GenerateRandomToken();
                    }
                }
                else if (entry.State == EntityState.Modified)
                {
                    entry.Entity.DataDoc = DateTime.Now;
                }
            }

            // Logica EVENTI_DET_PREL_QTA_TOT_TRG
            foreach (var entry in context.ChangeTracker.Entries<EventiDetPrel>())
            {
                if (entry.State == EntityState.Modified || entry.State == EntityState.Added)
                {
                    entry.Entity.Qta = entry.Entity.CalcolaQuantitaTotale();
                }
            }

            return base.SavingChangesAsync(eventData, result, cancellationToken);
        }
    }

### Creazione Ospiti Default

    public override async Task<int> SaveChangesAsync(CancellationToken ct = default)
    {
        var newEvents = ChangeTracker.Entries<Evento>()
            .Where(e => e.State == EntityState.Added)
            .Select(e => e.Entity)
            .ToList();

        var result = await base.SaveChangesAsync(ct);

        // Logica EVENTI_AI_TRG
        foreach (var evento in newEvents)
        {
            var tipiOspiti = new[] { (8, 1), (5, 2), (6, 3), (7, 4) };
            foreach (var (tipo, ordine) in tipiOspiti)
            {
                EventiDetOspiti.Add(new EventiDetOspiti
                {
                    IdEvento = evento.Id,
                    CodTipoOspite = tipo.ToString(),
                    Numero = 0,
                    Ordine = ordine
                });
            }
            await base.SaveChangesAsync(ct);
        }

        return result;
    }