Initial commit

This commit is contained in:
2025-11-28 10:59:10 +01:00
commit 14b3e965d0
540 changed files with 784121 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,22 @@
namespace Apollinare.Domain.Entities;
public class Articolo : BaseEntity
{
public string Codice { get; set; } = string.Empty;
public string Descrizione { get; set; } = string.Empty;
public int? TipoMaterialeId { get; set; }
public int? CategoriaId { get; set; }
public decimal? QtaDisponibile { get; set; }
public decimal? QtaStdA { get; set; }
public decimal? QtaStdB { get; set; }
public decimal? QtaStdS { get; set; }
public string? UnitaMisura { get; set; }
public byte[]? Immagine { get; set; }
public string? MimeType { get; set; }
public string? Note { get; set; }
public bool Attivo { get; set; } = true;
public TipoMateriale? TipoMateriale { get; set; }
public CodiceCategoria? Categoria { get; set; }
public ICollection<EventoDettaglioPrelievo> DettagliPrelievo { get; set; } = new List<EventoDettaglioPrelievo>();
}

View File

@@ -0,0 +1,10 @@
namespace Apollinare.Domain.Entities;
public abstract class BaseEntity
{
public int Id { get; set; }
public DateTime? CreatedAt { get; set; }
public string? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public string? UpdatedBy { get; set; }
}

View File

@@ -0,0 +1,20 @@
namespace Apollinare.Domain.Entities;
public class Cliente : BaseEntity
{
public string RagioneSociale { get; set; } = string.Empty;
public string? Indirizzo { get; set; }
public string? Cap { get; set; }
public string? Citta { get; set; }
public string? Provincia { get; set; }
public string? Telefono { get; set; }
public string? Email { get; set; }
public string? Pec { get; set; }
public string? CodiceFiscale { get; set; }
public string? PartitaIva { get; set; }
public string? CodiceDestinatario { get; set; }
public string? Note { get; set; }
public bool Attivo { get; set; } = true;
public ICollection<Evento> Eventi { get; set; } = new List<Evento>();
}

View File

@@ -0,0 +1,13 @@
namespace Apollinare.Domain.Entities;
public class CodiceCategoria : BaseEntity
{
public string Codice { get; set; } = string.Empty;
public string Descrizione { get; set; } = string.Empty;
public decimal CoeffA { get; set; } = 1;
public decimal CoeffB { get; set; } = 1;
public decimal CoeffS { get; set; } = 1;
public bool Attivo { get; set; } = true;
public ICollection<Articolo> Articoli { get; set; } = new List<Articolo>();
}

View File

@@ -0,0 +1,8 @@
namespace Apollinare.Domain.Entities;
public class Configurazione : BaseEntity
{
public string Chiave { get; set; } = string.Empty;
public string? Valore { get; set; }
public string? Descrizione { get; set; }
}

View File

@@ -0,0 +1,43 @@
using Apollinare.Domain.Enums;
namespace Apollinare.Domain.Entities;
public class Evento : BaseEntity
{
public string? Codice { get; set; }
public DateTime DataEvento { get; set; }
public TimeSpan? OraInizio { get; set; }
public TimeSpan? OraFine { get; set; }
public int? ClienteId { get; set; }
public int? LocationId { get; set; }
public int? TipoEventoId { get; set; }
public StatoEvento Stato { get; set; } = StatoEvento.Scheda;
public string? Descrizione { get; set; }
public int? NumeroOspiti { get; set; }
public int? NumeroOspitiAdulti { get; set; }
public int? NumeroOspitiBambini { get; set; }
public int? NumeroOspitiSeduti { get; set; }
public int? NumeroOspitiBuffet { get; set; }
public decimal? CostoTotale { get; set; }
public decimal? CostoPersona { get; set; }
public decimal? TotaleAcconti { get; set; }
public decimal? Saldo { get; set; }
public DateTime? DataScadenzaPreventivo { get; set; }
public string? NoteInterne { get; set; }
public string? NoteCliente { get; set; }
public string? NoteCucina { get; set; }
public string? NoteAllestimento { get; set; }
public bool Confermato { get; set; }
public Cliente? Cliente { get; set; }
public Location? Location { get; set; }
public TipoEvento? TipoEvento { get; set; }
public ICollection<EventoDettaglioOspiti> DettagliOspiti { get; set; } = new List<EventoDettaglioOspiti>();
public ICollection<EventoDettaglioPrelievo> DettagliPrelievo { get; set; } = new List<EventoDettaglioPrelievo>();
public ICollection<EventoDettaglioRisorsa> DettagliRisorse { get; set; } = new List<EventoDettaglioRisorsa>();
public ICollection<EventoAcconto> Acconti { get; set; } = new List<EventoAcconto>();
public ICollection<EventoAltroCosto> AltriCosti { get; set; } = new List<EventoAltroCosto>();
public ICollection<EventoAllegato> Allegati { get; set; } = new List<EventoAllegato>();
public ICollection<EventoDegustazione> Degustazioni { get; set; } = new List<EventoDegustazione>();
}

View File

@@ -0,0 +1,18 @@
namespace Apollinare.Domain.Entities;
public class EventoAcconto : BaseEntity
{
public int EventoId { get; set; }
public DateTime? DataPagamento { get; set; }
public decimal Importo { get; set; }
public int Ordine { get; set; } = 0;
public bool AConferma { get; set; } = false;
public string? Descrizione { get; set; }
public string? MetodoPagamento { get; set; }
public string? Note { get; set; }
// Calculated property - pagato se ha data
public bool Pagato => DataPagamento.HasValue;
public Evento? Evento { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace Apollinare.Domain.Entities;
public class EventoAllegato : BaseEntity
{
public int EventoId { get; set; }
public string NomeFile { get; set; } = string.Empty;
public string? MimeType { get; set; }
public byte[]? Contenuto { get; set; }
public string? Note { get; set; }
public Evento? Evento { get; set; }
}

View File

@@ -0,0 +1,18 @@
namespace Apollinare.Domain.Entities;
public class EventoAltroCosto : BaseEntity
{
public int EventoId { get; set; }
public string Descrizione { get; set; } = string.Empty;
public decimal CostoUnitario { get; set; }
public decimal Quantita { get; set; } = 1;
public int Ordine { get; set; } = 0;
public bool ApplicaIva { get; set; } = true;
public decimal AliquotaIva { get; set; } = 10; // Default 10% IVA
// Calculated properties
public decimal Totale => CostoUnitario * Quantita;
public decimal TotaleConIva => ApplicaIva ? Totale * (1 + AliquotaIva / 100) : Totale;
public Evento? Evento { get; set; }
}

View File

@@ -0,0 +1,21 @@
namespace Apollinare.Domain.Entities;
public class EventoDegustazione : BaseEntity
{
public int EventoId { get; set; }
public DateTime DataDegustazione { get; set; }
public TimeSpan? Ora { get; set; }
public int? NumeroPersone { get; set; }
public int? NumeroPaganti { get; set; }
public decimal? CostoDegustazione { get; set; }
public bool Detraibile { get; set; } = true;
public string? Menu { get; set; }
public string? Luogo { get; set; }
public string? Note { get; set; }
public bool Completata { get; set; }
// Calculated property - costo totale degustazione (se detraibile)
public decimal CostoTotale => Detraibile ? (NumeroPaganti ?? 0) * (CostoDegustazione ?? 0) : 0;
public Evento? Evento { get; set; }
}

View File

@@ -0,0 +1,18 @@
namespace Apollinare.Domain.Entities;
public class EventoDettaglioOspiti : BaseEntity
{
public int EventoId { get; set; }
public int TipoOspiteId { get; set; }
public int Numero { get; set; }
public decimal? CostoUnitario { get; set; }
public decimal? Sconto { get; set; } = 0; // Percentuale sconto
public int Ordine { get; set; } = 0;
public string? Note { get; set; }
// Calculated properties
public decimal CostoTotale => Numero * (CostoUnitario ?? 0) * (1 - (Sconto ?? 0) / 100);
public Evento? Evento { get; set; }
public TipoOspite? TipoOspite { get; set; }
}

View File

@@ -0,0 +1,14 @@
namespace Apollinare.Domain.Entities;
public class EventoDettaglioPrelievo : BaseEntity
{
public int EventoId { get; set; }
public int ArticoloId { get; set; }
public decimal? QtaRichiesta { get; set; }
public decimal? QtaCalcolata { get; set; }
public decimal? QtaEffettiva { get; set; }
public string? Note { get; set; }
public Evento? Evento { get; set; }
public Articolo? Articolo { get; set; }
}

View File

@@ -0,0 +1,16 @@
namespace Apollinare.Domain.Entities;
public class EventoDettaglioRisorsa : BaseEntity
{
public int EventoId { get; set; }
public int RisorsaId { get; set; }
public decimal? OreLavoro { get; set; }
public decimal? Costo { get; set; }
public TimeSpan? OraInizio { get; set; }
public TimeSpan? OraFine { get; set; }
public string? Ruolo { get; set; }
public string? Note { get; set; }
public Evento? Evento { get; set; }
public Risorsa? Risorsa { get; set; }
}

View File

@@ -0,0 +1,18 @@
namespace Apollinare.Domain.Entities;
public class Location : BaseEntity
{
public string Nome { get; set; } = string.Empty;
public string? Indirizzo { get; set; }
public string? Cap { get; set; }
public string? Citta { get; set; }
public string? Provincia { get; set; }
public string? Telefono { get; set; }
public string? Email { get; set; }
public string? Referente { get; set; }
public decimal? DistanzaKm { get; set; }
public string? Note { get; set; }
public bool Attivo { get; set; } = true;
public ICollection<Evento> Eventi { get; set; } = new List<Evento>();
}

View File

@@ -0,0 +1,33 @@
namespace Apollinare.Domain.Entities;
/// <summary>
/// Font personalizzato caricato dall'utente per i report
/// </summary>
public class ReportFont : BaseEntity
{
public string Nome { get; set; } = string.Empty;
/// <summary>
/// Nome famiglia font (es. "Roboto", "Open Sans")
/// </summary>
public string FontFamily { get; set; } = string.Empty;
/// <summary>
/// Stile font (Regular, Bold, Italic, BoldItalic)
/// </summary>
public string FontStyle { get; set; } = "Regular";
/// <summary>
/// File font (TTF, OTF, WOFF)
/// </summary>
public byte[] FontData { get; set; } = Array.Empty<byte>();
public string MimeType { get; set; } = "font/ttf";
/// <summary>
/// Dimensione file in bytes
/// </summary>
public long FileSize { get; set; }
public bool Attivo { get; set; } = true;
}

View File

@@ -0,0 +1,38 @@
namespace Apollinare.Domain.Entities;
/// <summary>
/// Immagine caricata dall'utente per i report (loghi, sfondi, etc.)
/// </summary>
public class ReportImage : BaseEntity
{
public string Nome { get; set; } = string.Empty;
/// <summary>
/// Categoria immagine (Logo, Sfondo, Icona, etc.)
/// </summary>
public string Categoria { get; set; } = "Generale";
/// <summary>
/// Dati immagine (PNG, JPG, SVG)
/// </summary>
public byte[] ImageData { get; set; } = Array.Empty<byte>();
public string MimeType { get; set; } = "image/png";
/// <summary>
/// Larghezza originale in pixel
/// </summary>
public int Width { get; set; }
/// <summary>
/// Altezza originale in pixel
/// </summary>
public int Height { get; set; }
/// <summary>
/// Dimensione file in bytes
/// </summary>
public long FileSize { get; set; }
public bool Attivo { get; set; } = true;
}

View File

@@ -0,0 +1,39 @@
namespace Apollinare.Domain.Entities;
/// <summary>
/// Template per la generazione di report PDF
/// Contiene il metalinguaggio APRT (Apollinare Report Template)
/// </summary>
public class ReportTemplate : BaseEntity
{
public string Nome { get; set; } = string.Empty;
public string? Descrizione { get; set; }
/// <summary>
/// Categoria del template (Evento, Cliente, Articoli, etc.)
/// </summary>
public string Categoria { get; set; } = "Generale";
/// <summary>
/// Il template in formato JSON (metalinguaggio APRT)
/// </summary>
public string TemplateJson { get; set; } = "{}";
/// <summary>
/// Preview thumbnail del template (PNG base64)
/// </summary>
public byte[]? Thumbnail { get; set; }
public string? ThumbnailMimeType { get; set; }
/// <summary>
/// Dimensioni pagina (A4, A3, Letter, etc.)
/// </summary>
public string PageSize { get; set; } = "A4";
/// <summary>
/// Orientamento (portrait, landscape)
/// </summary>
public string Orientation { get; set; } = "portrait";
public bool Attivo { get; set; } = true;
}

View File

@@ -0,0 +1,15 @@
namespace Apollinare.Domain.Entities;
public class Risorsa : BaseEntity
{
public string Nome { get; set; } = string.Empty;
public string? Cognome { get; set; }
public string? Telefono { get; set; }
public string? Email { get; set; }
public int? TipoRisorsaId { get; set; }
public string? Note { get; set; }
public bool Attivo { get; set; } = true;
public TipoRisorsa? TipoRisorsa { get; set; }
public ICollection<EventoDettaglioRisorsa> DettagliRisorse { get; set; } = new List<EventoDettaglioRisorsa>();
}

View File

@@ -0,0 +1,12 @@
namespace Apollinare.Domain.Entities;
public class TipoEvento : BaseEntity
{
public string Codice { get; set; } = string.Empty;
public string Descrizione { get; set; } = string.Empty;
public int? TipoPastoId { get; set; }
public bool Attivo { get; set; } = true;
public TipoPasto? TipoPasto { get; set; }
public ICollection<Evento> Eventi { get; set; } = new List<Evento>();
}

View File

@@ -0,0 +1,10 @@
namespace Apollinare.Domain.Entities;
public class TipoMateriale : BaseEntity
{
public string Codice { get; set; } = string.Empty;
public string Descrizione { get; set; } = string.Empty;
public bool Attivo { get; set; } = true;
public ICollection<Articolo> Articoli { get; set; } = new List<Articolo>();
}

View File

@@ -0,0 +1,10 @@
namespace Apollinare.Domain.Entities;
public class TipoOspite : BaseEntity
{
public string Codice { get; set; } = string.Empty;
public string Descrizione { get; set; } = string.Empty;
public bool Attivo { get; set; } = true;
public ICollection<EventoDettaglioOspiti> DettagliOspiti { get; set; } = new List<EventoDettaglioOspiti>();
}

View File

@@ -0,0 +1,10 @@
namespace Apollinare.Domain.Entities;
public class TipoPasto : BaseEntity
{
public string Codice { get; set; } = string.Empty;
public string Descrizione { get; set; } = string.Empty;
public bool Attivo { get; set; } = true;
public ICollection<TipoEvento> TipiEvento { get; set; } = new List<TipoEvento>();
}

View File

@@ -0,0 +1,10 @@
namespace Apollinare.Domain.Entities;
public class TipoRisorsa : BaseEntity
{
public string Codice { get; set; } = string.Empty;
public string Descrizione { get; set; } = string.Empty;
public bool Attivo { get; set; } = true;
public ICollection<Risorsa> Risorse { get; set; } = new List<Risorsa>();
}

View File

@@ -0,0 +1,12 @@
namespace Apollinare.Domain.Entities;
public class Utente : BaseEntity
{
public string Username { get; set; } = string.Empty;
public string? Nome { get; set; }
public string? Cognome { get; set; }
public string? Email { get; set; }
public bool SolaLettura { get; set; }
public bool Attivo { get; set; } = true;
public string? Ruolo { get; set; }
}

View File

@@ -0,0 +1,234 @@
namespace Apollinare.Domain.Entities;
/// <summary>
/// Dataset virtuale creato dall'utente combinando più dataset con relazioni e filtri.
/// Permette di creare "viste" composite che appaiono come dataset normali nel report designer.
/// </summary>
public class VirtualDataset : BaseEntity
{
/// <summary>
/// Nome identificativo del dataset virtuale (usato come ID)
/// </summary>
public string Nome { get; set; } = string.Empty;
/// <summary>
/// Nome visualizzato nell'interfaccia
/// </summary>
public string DisplayName { get; set; } = string.Empty;
/// <summary>
/// Descrizione del dataset
/// </summary>
public string? Descrizione { get; set; }
/// <summary>
/// Icona per l'interfaccia (nome icona Material-UI)
/// </summary>
public string Icon { get; set; } = "dataset";
/// <summary>
/// Categoria del dataset (per raggruppamento)
/// </summary>
public string Categoria { get; set; } = "Personalizzato";
/// <summary>
/// Configurazione JSON del dataset virtuale
/// Contiene: sources, relationships, filters, outputFields
/// </summary>
public string ConfigurationJson { get; set; } = "{}";
/// <summary>
/// Se il dataset è attivo e disponibile per la selezione
/// </summary>
public bool Attivo { get; set; } = true;
}
/// <summary>
/// Modello per la configurazione del dataset virtuale (serializzato in ConfigurationJson)
/// </summary>
public class VirtualDatasetConfiguration
{
/// <summary>
/// Dataset sorgente (tabelle base)
/// </summary>
public List<VirtualDatasetSource> Sources { get; set; } = new();
/// <summary>
/// Relazioni tra i dataset sorgente (JOIN)
/// </summary>
public List<VirtualDatasetRelationship> Relationships { get; set; } = new();
/// <summary>
/// Filtri globali applicati al dataset
/// </summary>
public List<VirtualDatasetFilter> Filters { get; set; } = new();
/// <summary>
/// Campi di output selezionati (se vuoto, tutti i campi)
/// </summary>
public List<VirtualDatasetOutputField> OutputFields { get; set; } = new();
/// <summary>
/// Dataset primario (root) da cui partire
/// </summary>
public string? PrimarySourceId { get; set; }
}
/// <summary>
/// Dataset sorgente incluso nel dataset virtuale
/// </summary>
public class VirtualDatasetSource
{
/// <summary>
/// ID univoco della sorgente nel contesto del virtual dataset
/// </summary>
public string Id { get; set; } = string.Empty;
/// <summary>
/// ID del dataset base (es. "evento", "cliente", "articolo")
/// </summary>
public string DatasetId { get; set; } = string.Empty;
/// <summary>
/// Alias per riferirsi a questo dataset nelle espressioni
/// </summary>
public string Alias { get; set; } = string.Empty;
/// <summary>
/// Se è il dataset principale (root)
/// </summary>
public bool IsPrimary { get; set; }
}
/// <summary>
/// Relazione tra due dataset sorgente (JOIN)
/// </summary>
public class VirtualDatasetRelationship
{
/// <summary>
/// ID univoco della relazione
/// </summary>
public string Id { get; set; } = string.Empty;
/// <summary>
/// ID sorgente del lato sinistro (from)
/// </summary>
public string FromSourceId { get; set; } = string.Empty;
/// <summary>
/// Campo chiave del lato sinistro
/// </summary>
public string FromField { get; set; } = string.Empty;
/// <summary>
/// ID sorgente del lato destro (to)
/// </summary>
public string ToSourceId { get; set; } = string.Empty;
/// <summary>
/// Campo chiave del lato destro
/// </summary>
public string ToField { get; set; } = string.Empty;
/// <summary>
/// Tipo di JOIN: inner, left, right
/// </summary>
public string JoinType { get; set; } = "left";
/// <summary>
/// Nome descrittivo della relazione
/// </summary>
public string? Label { get; set; }
}
/// <summary>
/// Filtro applicato al dataset virtuale
/// </summary>
public class VirtualDatasetFilter
{
/// <summary>
/// ID univoco del filtro
/// </summary>
public string Id { get; set; } = string.Empty;
/// <summary>
/// ID della sorgente a cui applicare il filtro
/// </summary>
public string SourceId { get; set; } = string.Empty;
/// <summary>
/// Campo su cui filtrare
/// </summary>
public string Field { get; set; } = string.Empty;
/// <summary>
/// Operatore: eq, neq, gt, gte, lt, lte, contains, startsWith, endsWith, isNull, isNotNull
/// </summary>
public string Operator { get; set; } = "eq";
/// <summary>
/// Valore di confronto (può essere statico o parametrico {{param}})
/// </summary>
public string? Value { get; set; }
/// <summary>
/// Tipo del valore: static, parameter, field
/// </summary>
public string ValueType { get; set; } = "static";
/// <summary>
/// Operatore logico con il filtro successivo: and, or
/// </summary>
public string LogicalOperator { get; set; } = "and";
/// <summary>
/// Se il filtro è attivo
/// </summary>
public bool Enabled { get; set; } = true;
}
/// <summary>
/// Campo di output selezionato per il dataset virtuale
/// </summary>
public class VirtualDatasetOutputField
{
/// <summary>
/// ID univoco del campo output
/// </summary>
public string Id { get; set; } = string.Empty;
/// <summary>
/// ID della sorgente da cui proviene il campo
/// </summary>
public string SourceId { get; set; } = string.Empty;
/// <summary>
/// Nome del campo sorgente
/// </summary>
public string FieldName { get; set; } = string.Empty;
/// <summary>
/// Alias per il campo nell'output (se diverso dal nome originale)
/// </summary>
public string? Alias { get; set; }
/// <summary>
/// Label visualizzata
/// </summary>
public string? Label { get; set; }
/// <summary>
/// Gruppo logico per organizzazione UI
/// </summary>
public string? Group { get; set; }
/// <summary>
/// Ordine di visualizzazione
/// </summary>
public int Order { get; set; }
/// <summary>
/// Se includere il campo nell'output
/// </summary>
public bool Included { get; set; } = true;
}

View File

@@ -0,0 +1,8 @@
namespace Apollinare.Domain.Enums;
public enum StatoEvento
{
Scheda = 0,
Preventivo = 10,
Confermato = 20
}