changed name from Apollinare to Zentral
This commit is contained in:
85
src/backend/Zentral.Domain/Entities/AppModule.cs
Normal file
85
src/backend/Zentral.Domain/Entities/AppModule.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Rappresenta un modulo dell'applicazione (es. Magazzino, Acquisti, Vendite).
|
||||
/// I moduli possono essere attivati/disattivati per gestire licenze e funzionalità.
|
||||
/// </summary>
|
||||
public class AppModule : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice univoco del modulo (es. "warehouse", "purchases", "sales")
|
||||
/// </summary>
|
||||
public required string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nome visualizzato del modulo (es. "Magazzino", "Acquisti")
|
||||
/// </summary>
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione estesa delle funzionalità del modulo
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nome dell'icona Material UI (es. "Warehouse", "ShoppingCart")
|
||||
/// </summary>
|
||||
public string? Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prezzo base annuale del modulo in EUR
|
||||
/// </summary>
|
||||
public decimal BasePrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Moltiplicatore per abbonamento mensile (es. 1.2 = 20% in più rispetto all'annuale/12)
|
||||
/// </summary>
|
||||
public decimal MonthlyMultiplier { get; set; } = 1.2m;
|
||||
|
||||
/// <summary>
|
||||
/// Ordine di visualizzazione nel menu (più basso = prima)
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, il modulo fa parte del core e non può essere disattivato
|
||||
/// </summary>
|
||||
public bool IsCore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Lista di codici modulo prerequisiti separati da virgola (es. "warehouse,purchases")
|
||||
/// </summary>
|
||||
public string? Dependencies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path base per le route frontend del modulo (es. "/warehouse")
|
||||
/// </summary>
|
||||
public string? RoutePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se false, il modulo è nascosto e non disponibile per l'acquisto
|
||||
/// </summary>
|
||||
public bool IsAvailable { get; set; } = true;
|
||||
|
||||
// Navigation property
|
||||
public ModuleSubscription? Subscription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce la lista dei codici modulo prerequisiti
|
||||
/// </summary>
|
||||
public IEnumerable<string> GetDependencies()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Dependencies))
|
||||
return Enumerable.Empty<string>();
|
||||
|
||||
return Dependencies.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcola il prezzo mensile basato su BasePrice e MonthlyMultiplier
|
||||
/// </summary>
|
||||
public decimal GetMonthlyPrice()
|
||||
{
|
||||
return Math.Round((BasePrice / 12) * MonthlyMultiplier, 2);
|
||||
}
|
||||
}
|
||||
31
src/backend/Zentral.Domain/Entities/Articolo.cs
Normal file
31
src/backend/Zentral.Domain/Entities/Articolo.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
public class Articolo : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice articolo - generato automaticamente
|
||||
/// </summary>
|
||||
public string Codice { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Codice alternativo (opzionale, inserito dall'utente)
|
||||
/// </summary>
|
||||
public string? CodiceAlternativo { get; set; }
|
||||
|
||||
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>();
|
||||
}
|
||||
117
src/backend/Zentral.Domain/Entities/AutoCode.cs
Normal file
117
src/backend/Zentral.Domain/Entities/AutoCode.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Configurazione per la generazione automatica di codici.
|
||||
/// Ogni entità può avere la propria configurazione con pattern personalizzabile.
|
||||
///
|
||||
/// Pattern supportati:
|
||||
/// - {SEQ:n} - Sequenza numerica con n cifre (es. {SEQ:5} → 00001)
|
||||
/// - {YEAR} o {YYYY} - Anno corrente a 4 cifre
|
||||
/// - {YY} - Anno corrente a 2 cifre
|
||||
/// - {MONTH} o {MM} - Mese corrente a 2 cifre
|
||||
/// - {DAY} o {DD} - Giorno corrente a 2 cifre
|
||||
/// - {PREFIX} - Usa il prefisso definito
|
||||
/// - Testo statico (es. "ART-", "-", "/")
|
||||
///
|
||||
/// Esempi di pattern:
|
||||
/// - "ART-{YYYY}-{SEQ:5}" → ART-2025-00001
|
||||
/// - "{PREFIX}{YY}{MM}{SEQ:4}" → MAG2511-0001
|
||||
/// - "CLI/{YYYY}/{SEQ:6}" → CLI/2025/000001
|
||||
/// </summary>
|
||||
public class AutoCode : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice univoco dell'entità (es. "warehouse_article", "warehouse_location", "cliente")
|
||||
/// </summary>
|
||||
public string EntityCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Nome visualizzato dell'entità (es. "Articolo Magazzino", "Magazzino", "Cliente")
|
||||
/// </summary>
|
||||
public string EntityName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Prefisso opzionale da usare nel pattern con {PREFIX}
|
||||
/// </summary>
|
||||
public string? Prefix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pattern per la generazione del codice
|
||||
/// </summary>
|
||||
public string Pattern { get; set; } = "{PREFIX}{SEQ:5}";
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo numero di sequenza utilizzato (per {SEQ:n})
|
||||
/// </summary>
|
||||
public long LastSequence { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Se true, la sequenza viene resettata ogni anno
|
||||
/// </summary>
|
||||
public bool ResetSequenceYearly { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Se true, la sequenza viene resettata ogni mese
|
||||
/// </summary>
|
||||
public bool ResetSequenceMonthly { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Anno dell'ultimo reset della sequenza
|
||||
/// </summary>
|
||||
public int? LastResetYear { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Mese dell'ultimo reset della sequenza (se ResetSequenceMonthly)
|
||||
/// </summary>
|
||||
public int? LastResetMonth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, la generazione automatica è abilitata
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Se true, il codice non può essere modificato manualmente
|
||||
/// </summary>
|
||||
public bool IsReadOnly { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Modulo di appartenenza (es. "core", "warehouse", "purchases")
|
||||
/// </summary>
|
||||
public string? ModuleCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione della configurazione
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ordine di visualizzazione nel pannello admin
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Esempio di codice generato (calcolato, non persistito)
|
||||
/// </summary>
|
||||
public string GetExampleCode()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
return Pattern
|
||||
.Replace("{PREFIX}", Prefix ?? "")
|
||||
.Replace("{YEAR}", now.Year.ToString())
|
||||
.Replace("{YYYY}", now.Year.ToString())
|
||||
.Replace("{YY}", now.Year.ToString().Substring(2))
|
||||
.Replace("{MONTH}", now.Month.ToString("D2"))
|
||||
.Replace("{MM}", now.Month.ToString("D2"))
|
||||
.Replace("{DAY}", now.Day.ToString("D2"))
|
||||
.Replace("{DD}", now.Day.ToString("D2"))
|
||||
.Replace("{SEQ:1}", "X")
|
||||
.Replace("{SEQ:2}", "XX")
|
||||
.Replace("{SEQ:3}", "XXX")
|
||||
.Replace("{SEQ:4}", "XXXX")
|
||||
.Replace("{SEQ:5}", "XXXXX")
|
||||
.Replace("{SEQ:6}", "XXXXXX")
|
||||
.Replace("{SEQ:7}", "XXXXXXX")
|
||||
.Replace("{SEQ:8}", "XXXXXXXX");
|
||||
}
|
||||
}
|
||||
15
src/backend/Zentral.Domain/Entities/BaseEntity.cs
Normal file
15
src/backend/Zentral.Domain/Entities/BaseEntity.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace Zentral.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; }
|
||||
|
||||
/// <summary>
|
||||
/// Stores custom field values as JSON: {"birthday": "2023-01-01", "vip_status": "gold"}
|
||||
/// </summary>
|
||||
public string? CustomFieldsJson { get; set; }
|
||||
}
|
||||
31
src/backend/Zentral.Domain/Entities/Cliente.cs
Normal file
31
src/backend/Zentral.Domain/Entities/Cliente.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
public class Cliente : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice cliente - generato automaticamente
|
||||
/// </summary>
|
||||
public string Codice { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Codice alternativo (opzionale, inserito dall'utente)
|
||||
/// </summary>
|
||||
public string? CodiceAlternativo { get; set; }
|
||||
|
||||
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>();
|
||||
public ICollection<Zentral.Domain.Entities.Sales.SalesOrder> SalesOrders { get; set; } = new List<Zentral.Domain.Entities.Sales.SalesOrder>();
|
||||
}
|
||||
13
src/backend/Zentral.Domain/Entities/CodiceCategoria.cs
Normal file
13
src/backend/Zentral.Domain/Entities/CodiceCategoria.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
8
src/backend/Zentral.Domain/Entities/Configurazione.cs
Normal file
8
src/backend/Zentral.Domain/Entities/Configurazione.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
public class Configurazione : BaseEntity
|
||||
{
|
||||
public string Chiave { get; set; } = string.Empty;
|
||||
public string? Valore { get; set; }
|
||||
public string? Descrizione { get; set; }
|
||||
}
|
||||
19
src/backend/Zentral.Domain/Entities/CustomFieldDefinition.cs
Normal file
19
src/backend/Zentral.Domain/Entities/CustomFieldDefinition.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Zentral.Domain.Enums;
|
||||
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
public class CustomFieldDefinition : BaseEntity
|
||||
{
|
||||
public required string EntityName { get; set; } // e.g. "Cliente", "WarehouseArticle"
|
||||
public required string FieldName { get; set; } // Internal name, e.g. "birthday"
|
||||
public required string Label { get; set; } // Display name, e.g. "Birthday"
|
||||
public CustomFieldType Type { get; set; }
|
||||
public bool IsRequired { get; set; }
|
||||
public string? DefaultValue { get; set; }
|
||||
public string? OptionsJson { get; set; } // For Select/MultiSelect: ["Option A", "Option B"]
|
||||
public int SortOrder { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public string? ValidationRegex { get; set; }
|
||||
public string? Placeholder { get; set; }
|
||||
}
|
||||
43
src/backend/Zentral.Domain/Entities/Evento.cs
Normal file
43
src/backend/Zentral.Domain/Entities/Evento.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Zentral.Domain.Enums;
|
||||
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
18
src/backend/Zentral.Domain/Entities/EventoAcconto.cs
Normal file
18
src/backend/Zentral.Domain/Entities/EventoAcconto.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Zentral.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; }
|
||||
}
|
||||
12
src/backend/Zentral.Domain/Entities/EventoAllegato.cs
Normal file
12
src/backend/Zentral.Domain/Entities/EventoAllegato.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Zentral.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; }
|
||||
}
|
||||
18
src/backend/Zentral.Domain/Entities/EventoAltroCosto.cs
Normal file
18
src/backend/Zentral.Domain/Entities/EventoAltroCosto.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Zentral.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; }
|
||||
}
|
||||
21
src/backend/Zentral.Domain/Entities/EventoDegustazione.cs
Normal file
21
src/backend/Zentral.Domain/Entities/EventoDegustazione.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace Zentral.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; }
|
||||
}
|
||||
18
src/backend/Zentral.Domain/Entities/EventoDettaglioOspiti.cs
Normal file
18
src/backend/Zentral.Domain/Entities/EventoDettaglioOspiti.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Zentral.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; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Zentral.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; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Zentral.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; }
|
||||
}
|
||||
18
src/backend/Zentral.Domain/Entities/Location.cs
Normal file
18
src/backend/Zentral.Domain/Entities/Location.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
108
src/backend/Zentral.Domain/Entities/ModuleSubscription.cs
Normal file
108
src/backend/Zentral.Domain/Entities/ModuleSubscription.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di abbonamento per un modulo
|
||||
/// </summary>
|
||||
public enum SubscriptionType
|
||||
{
|
||||
/// <summary>Nessun abbonamento attivo</summary>
|
||||
None = 0,
|
||||
/// <summary>Abbonamento mensile</summary>
|
||||
Monthly = 1,
|
||||
/// <summary>Abbonamento annuale</summary>
|
||||
Annual = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rappresenta lo stato di abbonamento/attivazione di un modulo per questa istanza dell'applicazione.
|
||||
/// Ogni ModuleSubscription è collegata 1:1 con un AppModule.
|
||||
/// </summary>
|
||||
public class ModuleSubscription : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// ID del modulo associato
|
||||
/// </summary>
|
||||
public int ModuleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, il modulo è attualmente attivo e accessibile
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di abbonamento corrente
|
||||
/// </summary>
|
||||
public SubscriptionType SubscriptionType { get; set; } = SubscriptionType.None;
|
||||
|
||||
/// <summary>
|
||||
/// Data di inizio dell'abbonamento corrente
|
||||
/// </summary>
|
||||
public DateTime? StartDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data di scadenza dell'abbonamento (null = nessuna scadenza, es. licenza perpetua)
|
||||
/// </summary>
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, l'abbonamento si rinnova automaticamente alla scadenza
|
||||
/// </summary>
|
||||
public bool AutoRenew { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note aggiuntive sull'abbonamento (es. codice ordine, riferimento contratto)
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data dell'ultimo rinnovo effettuato
|
||||
/// </summary>
|
||||
public DateTime? LastRenewalDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prezzo pagato per l'abbonamento corrente (può differire da BasePrice per sconti)
|
||||
/// </summary>
|
||||
public decimal? PaidPrice { get; set; }
|
||||
|
||||
// Navigation property
|
||||
public AppModule Module { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Verifica se l'abbonamento è attualmente valido (attivo e non scaduto)
|
||||
/// </summary>
|
||||
public bool IsValid()
|
||||
{
|
||||
if (!IsEnabled)
|
||||
return false;
|
||||
|
||||
// Se non c'è data di scadenza, è valido (licenza perpetua o core module)
|
||||
if (!EndDate.HasValue)
|
||||
return true;
|
||||
|
||||
return EndDate.Value >= DateTime.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcola i giorni rimanenti alla scadenza (null se nessuna scadenza)
|
||||
/// </summary>
|
||||
public int? GetDaysRemaining()
|
||||
{
|
||||
if (!EndDate.HasValue)
|
||||
return null;
|
||||
|
||||
var remaining = (EndDate.Value - DateTime.UtcNow).Days;
|
||||
return remaining < 0 ? 0 : remaining;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica se l'abbonamento sta per scadere (entro i prossimi N giorni)
|
||||
/// </summary>
|
||||
public bool IsExpiringSoon(int daysThreshold = 30)
|
||||
{
|
||||
if (!EndDate.HasValue)
|
||||
return false;
|
||||
|
||||
var daysRemaining = GetDaysRemaining();
|
||||
return daysRemaining.HasValue && daysRemaining.Value <= daysThreshold && daysRemaining.Value > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Production;
|
||||
|
||||
public class BillOfMaterials : BaseEntity
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
// The article that is produced
|
||||
public int ArticleId { get; set; }
|
||||
public WarehouseArticle Article { get; set; } = null!;
|
||||
|
||||
// Quantity produced by this BOM (usually 1)
|
||||
public decimal Quantity { get; set; } = 1;
|
||||
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
public ICollection<BillOfMaterialsComponent> Components { get; set; } = new List<BillOfMaterialsComponent>();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Production;
|
||||
|
||||
public class BillOfMaterialsComponent : BaseEntity
|
||||
{
|
||||
public int BillOfMaterialsId { get; set; }
|
||||
public BillOfMaterials BillOfMaterials { get; set; } = null!;
|
||||
|
||||
// The raw material
|
||||
public int ComponentArticleId { get; set; }
|
||||
public WarehouseArticle ComponentArticle { get; set; } = null!;
|
||||
|
||||
public decimal Quantity { get; set; }
|
||||
|
||||
// Scrap percentage
|
||||
public decimal ScrapPercentage { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Production;
|
||||
|
||||
public class MrpSuggestion : BaseEntity
|
||||
{
|
||||
public DateTime CalculationDate { get; set; }
|
||||
|
||||
public int ArticleId { get; set; }
|
||||
public WarehouseArticle Article { get; set; } = null!;
|
||||
|
||||
public MrpSuggestionType Type { get; set; }
|
||||
|
||||
public decimal Quantity { get; set; }
|
||||
public DateTime SuggestionDate { get; set; }
|
||||
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
|
||||
public bool IsProcessed { get; set; }
|
||||
}
|
||||
|
||||
public enum MrpSuggestionType
|
||||
{
|
||||
Production = 0,
|
||||
Purchase = 1
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Production;
|
||||
|
||||
public class ProductionCycle : BaseEntity
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
|
||||
public int ArticleId { get; set; }
|
||||
public WarehouseArticle Article { get; set; } = null!;
|
||||
|
||||
public bool IsDefault { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
public ICollection<ProductionCyclePhase> Phases { get; set; } = new List<ProductionCyclePhase>();
|
||||
}
|
||||
|
||||
public class ProductionCyclePhase : BaseEntity
|
||||
{
|
||||
public int ProductionCycleId { get; set; }
|
||||
public ProductionCycle ProductionCycle { get; set; } = null!;
|
||||
|
||||
public int Sequence { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
|
||||
public int WorkCenterId { get; set; }
|
||||
public WorkCenter WorkCenter { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Duration in minutes per unit produced
|
||||
/// </summary>
|
||||
public int DurationPerUnitMinutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fixed setup time in minutes
|
||||
/// </summary>
|
||||
public int SetupTimeMinutes { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Production;
|
||||
|
||||
public class ProductionOrder : BaseEntity
|
||||
{
|
||||
public string Code { get; set; } = string.Empty; // Auto-generated
|
||||
|
||||
public int ArticleId { get; set; }
|
||||
public WarehouseArticle Article { get; set; } = null!;
|
||||
|
||||
public decimal Quantity { get; set; }
|
||||
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
public DateTime DueDate { get; set; }
|
||||
|
||||
public ProductionOrderStatus Status { get; set; } = ProductionOrderStatus.Draft;
|
||||
|
||||
public string? Notes { get; set; }
|
||||
|
||||
public ICollection<ProductionOrderComponent> Components { get; set; } = new List<ProductionOrderComponent>();
|
||||
public ICollection<ProductionOrderPhase> Phases { get; set; } = new List<ProductionOrderPhase>();
|
||||
|
||||
// Hierarchy
|
||||
public int? ParentProductionOrderId { get; set; }
|
||||
public ProductionOrder? ParentProductionOrder { get; set; }
|
||||
public ICollection<ProductionOrder> ChildProductionOrders { get; set; } = new List<ProductionOrder>();
|
||||
}
|
||||
|
||||
public enum ProductionOrderStatus
|
||||
{
|
||||
Draft = 0,
|
||||
Planned = 1,
|
||||
Released = 2,
|
||||
InProgress = 3,
|
||||
Completed = 4,
|
||||
Cancelled = 5
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Production;
|
||||
|
||||
public class ProductionOrderComponent : BaseEntity
|
||||
{
|
||||
public int ProductionOrderId { get; set; }
|
||||
public ProductionOrder ProductionOrder { get; set; } = null!;
|
||||
|
||||
public int ArticleId { get; set; }
|
||||
public WarehouseArticle Article { get; set; } = null!;
|
||||
|
||||
public decimal RequiredQuantity { get; set; }
|
||||
public decimal ConsumedQuantity { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Production;
|
||||
|
||||
public class ProductionOrderPhase : BaseEntity
|
||||
{
|
||||
public int ProductionOrderId { get; set; }
|
||||
public ProductionOrder ProductionOrder { get; set; } = null!;
|
||||
|
||||
public int Sequence { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public int WorkCenterId { get; set; }
|
||||
public WorkCenter WorkCenter { get; set; } = null!;
|
||||
|
||||
public ProductionPhaseStatus Status { get; set; } = ProductionPhaseStatus.Pending;
|
||||
|
||||
public DateTime? StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
||||
public decimal QuantityCompleted { get; set; }
|
||||
public decimal QuantityScrapped { get; set; }
|
||||
|
||||
public int EstimatedDurationMinutes { get; set; }
|
||||
public int ActualDurationMinutes { get; set; }
|
||||
}
|
||||
|
||||
public enum ProductionPhaseStatus
|
||||
{
|
||||
Pending = 0,
|
||||
InProgress = 1,
|
||||
Completed = 2,
|
||||
Paused = 3
|
||||
}
|
||||
12
src/backend/Zentral.Domain/Entities/Production/WorkCenter.cs
Normal file
12
src/backend/Zentral.Domain/Entities/Production/WorkCenter.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Production;
|
||||
|
||||
public class WorkCenter : BaseEntity
|
||||
{
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public decimal CostPerHour { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Zentral.Domain.Entities;
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Purchases;
|
||||
|
||||
/// <summary>
|
||||
/// Ordine di acquisto a fornitore
|
||||
/// </summary>
|
||||
public class PurchaseOrder : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Numero ordine (generato automaticamente)
|
||||
/// </summary>
|
||||
public string OrderNumber { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Data ordine
|
||||
/// </summary>
|
||||
public DateTime OrderDate { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Data consegna prevista
|
||||
/// </summary>
|
||||
public DateTime? ExpectedDeliveryDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID Fornitore
|
||||
/// </summary>
|
||||
public int SupplierId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stato dell'ordine
|
||||
/// </summary>
|
||||
public PurchaseOrderStatus Status { get; set; } = PurchaseOrderStatus.Draft;
|
||||
|
||||
/// <summary>
|
||||
/// ID Magazzino di destinazione (opzionale, se null usa il default)
|
||||
/// </summary>
|
||||
public int? DestinationWarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note interne
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Totale imponibile (calcolato)
|
||||
/// </summary>
|
||||
public decimal TotalNet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Totale tasse (calcolato)
|
||||
/// </summary>
|
||||
public decimal TotalTax { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Totale lordo (calcolato)
|
||||
/// </summary>
|
||||
public decimal TotalGross { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public Supplier? Supplier { get; set; }
|
||||
public WarehouseLocation? DestinationWarehouse { get; set; }
|
||||
public ICollection<PurchaseOrderLine> Lines { get; set; } = new List<PurchaseOrderLine>();
|
||||
}
|
||||
|
||||
public enum PurchaseOrderStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Bozza
|
||||
/// </summary>
|
||||
Draft = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Confermato/Inviato al fornitore
|
||||
/// </summary>
|
||||
Confirmed = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Ricevuto parzialmente
|
||||
/// </summary>
|
||||
PartiallyReceived = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Ricevuto completamente
|
||||
/// </summary>
|
||||
Received = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Annullato
|
||||
/// </summary>
|
||||
Cancelled = 4
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using Zentral.Domain.Entities;
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Purchases;
|
||||
|
||||
/// <summary>
|
||||
/// Riga ordine di acquisto
|
||||
/// </summary>
|
||||
public class PurchaseOrderLine : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// ID Ordine di acquisto
|
||||
/// </summary>
|
||||
public int PurchaseOrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID Articolo di magazzino
|
||||
/// </summary>
|
||||
public int WarehouseArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione (default da articolo, ma modificabile)
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Quantità ordinata
|
||||
/// </summary>
|
||||
public decimal Quantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità ricevuta
|
||||
/// </summary>
|
||||
public decimal ReceivedQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prezzo unitario
|
||||
/// </summary>
|
||||
public decimal UnitPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Aliquota IVA (percentuale)
|
||||
/// </summary>
|
||||
public decimal TaxRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sconto (percentuale)
|
||||
/// </summary>
|
||||
public decimal DiscountPercent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Totale riga (netto)
|
||||
/// </summary>
|
||||
public decimal LineTotal { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public PurchaseOrder? PurchaseOrder { get; set; }
|
||||
public WarehouseArticle? WarehouseArticle { get; set; }
|
||||
}
|
||||
93
src/backend/Zentral.Domain/Entities/Purchases/Supplier.cs
Normal file
93
src/backend/Zentral.Domain/Entities/Purchases/Supplier.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System.Collections.Generic;
|
||||
using Zentral.Domain.Entities;
|
||||
|
||||
namespace Zentral.Domain.Entities.Purchases;
|
||||
|
||||
/// <summary>
|
||||
/// Fornitore di beni o servizi
|
||||
/// </summary>
|
||||
public class Supplier : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice fornitore (generato automaticamente o manuale)
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Ragione sociale o nome
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Partita IVA
|
||||
/// </summary>
|
||||
public string? VatNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Codice Fiscale
|
||||
/// </summary>
|
||||
public string? FiscalCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indirizzo
|
||||
/// </summary>
|
||||
public string? Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Città
|
||||
/// </summary>
|
||||
public string? City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Provincia
|
||||
/// </summary>
|
||||
public string? Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CAP
|
||||
/// </summary>
|
||||
public string? ZipCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nazione
|
||||
/// </summary>
|
||||
public string? Country { get; set; } = "Italia";
|
||||
|
||||
/// <summary>
|
||||
/// Email principale
|
||||
/// </summary>
|
||||
public string? Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PEC
|
||||
/// </summary>
|
||||
public string? Pec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Telefono
|
||||
/// </summary>
|
||||
public string? Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sito web
|
||||
/// </summary>
|
||||
public string? Website { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Termini di pagamento (descrizione testuale o riferimento a tabella pagamenti)
|
||||
/// </summary>
|
||||
public string? PaymentTerms { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note interne
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se attivo, il fornitore può essere utilizzato
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
// Navigation properties
|
||||
public ICollection<PurchaseOrder> PurchaseOrders { get; set; } = new List<PurchaseOrder>();
|
||||
}
|
||||
33
src/backend/Zentral.Domain/Entities/ReportFont.cs
Normal file
33
src/backend/Zentral.Domain/Entities/ReportFont.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace Zentral.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;
|
||||
}
|
||||
38
src/backend/Zentral.Domain/Entities/ReportImage.cs
Normal file
38
src/backend/Zentral.Domain/Entities/ReportImage.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
namespace Zentral.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;
|
||||
}
|
||||
39
src/backend/Zentral.Domain/Entities/ReportTemplate.cs
Normal file
39
src/backend/Zentral.Domain/Entities/ReportTemplate.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Template per la generazione di report PDF
|
||||
/// Contiene il metalinguaggio APRT (Zentral 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;
|
||||
}
|
||||
15
src/backend/Zentral.Domain/Entities/Risorsa.cs
Normal file
15
src/backend/Zentral.Domain/Entities/Risorsa.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
94
src/backend/Zentral.Domain/Entities/Sales/SalesOrder.cs
Normal file
94
src/backend/Zentral.Domain/Entities/Sales/SalesOrder.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Zentral.Domain.Entities;
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Sales;
|
||||
|
||||
/// <summary>
|
||||
/// Ordine di vendita a cliente
|
||||
/// </summary>
|
||||
public class SalesOrder : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Numero ordine (generato automaticamente)
|
||||
/// </summary>
|
||||
public string OrderNumber { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Data ordine
|
||||
/// </summary>
|
||||
public DateTime OrderDate { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Data consegna prevista
|
||||
/// </summary>
|
||||
public DateTime? ExpectedDeliveryDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID Cliente
|
||||
/// </summary>
|
||||
public int CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stato dell'ordine
|
||||
/// </summary>
|
||||
public SalesOrderStatus Status { get; set; } = SalesOrderStatus.Draft;
|
||||
|
||||
/// <summary>
|
||||
/// Note interne
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Totale imponibile (calcolato)
|
||||
/// </summary>
|
||||
public decimal TotalNet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Totale tasse (calcolato)
|
||||
/// </summary>
|
||||
public decimal TotalTax { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Totale lordo (calcolato)
|
||||
/// </summary>
|
||||
public decimal TotalGross { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public Cliente? Customer { get; set; }
|
||||
public ICollection<SalesOrderLine> Lines { get; set; } = new List<SalesOrderLine>();
|
||||
}
|
||||
|
||||
public enum SalesOrderStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Bozza
|
||||
/// </summary>
|
||||
Draft = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Confermato
|
||||
/// </summary>
|
||||
Confirmed = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Spedito parzialmente
|
||||
/// </summary>
|
||||
PartiallyShipped = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Spedito completamente
|
||||
/// </summary>
|
||||
Shipped = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Fatturato
|
||||
/// </summary>
|
||||
Invoiced = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Annullato
|
||||
/// </summary>
|
||||
Cancelled = 5
|
||||
}
|
||||
59
src/backend/Zentral.Domain/Entities/Sales/SalesOrderLine.cs
Normal file
59
src/backend/Zentral.Domain/Entities/Sales/SalesOrderLine.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using Zentral.Domain.Entities;
|
||||
using Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
namespace Zentral.Domain.Entities.Sales;
|
||||
|
||||
/// <summary>
|
||||
/// Riga ordine di vendita
|
||||
/// </summary>
|
||||
public class SalesOrderLine : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// ID Ordine di vendita
|
||||
/// </summary>
|
||||
public int SalesOrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID Articolo di magazzino
|
||||
/// </summary>
|
||||
public int WarehouseArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione (default da articolo, ma modificabile)
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Quantità ordinata
|
||||
/// </summary>
|
||||
public decimal Quantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità spedita
|
||||
/// </summary>
|
||||
public decimal ShippedQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prezzo unitario
|
||||
/// </summary>
|
||||
public decimal UnitPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Aliquota IVA (percentuale)
|
||||
/// </summary>
|
||||
public decimal TaxRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sconto (percentuale)
|
||||
/// </summary>
|
||||
public decimal DiscountPercent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Totale riga (netto)
|
||||
/// </summary>
|
||||
public decimal LineTotal { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public SalesOrder? SalesOrder { get; set; }
|
||||
public WarehouseArticle? WarehouseArticle { get; set; }
|
||||
}
|
||||
12
src/backend/Zentral.Domain/Entities/TipoEvento.cs
Normal file
12
src/backend/Zentral.Domain/Entities/TipoEvento.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
10
src/backend/Zentral.Domain/Entities/TipoMateriale.cs
Normal file
10
src/backend/Zentral.Domain/Entities/TipoMateriale.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
10
src/backend/Zentral.Domain/Entities/TipoOspite.cs
Normal file
10
src/backend/Zentral.Domain/Entities/TipoOspite.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
10
src/backend/Zentral.Domain/Entities/TipoPasto.cs
Normal file
10
src/backend/Zentral.Domain/Entities/TipoPasto.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
10
src/backend/Zentral.Domain/Entities/TipoRisorsa.cs
Normal file
10
src/backend/Zentral.Domain/Entities/TipoRisorsa.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Zentral.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>();
|
||||
}
|
||||
12
src/backend/Zentral.Domain/Entities/Utente.cs
Normal file
12
src/backend/Zentral.Domain/Entities/Utente.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Zentral.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; }
|
||||
}
|
||||
234
src/backend/Zentral.Domain/Entities/VirtualDataset.cs
Normal file
234
src/backend/Zentral.Domain/Entities/VirtualDataset.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
namespace Zentral.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;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Codici a barre aggiuntivi per un articolo (multi-barcode support)
|
||||
/// </summary>
|
||||
public class ArticleBarcode : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Articolo di riferimento
|
||||
/// </summary>
|
||||
public int ArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Codice a barre
|
||||
/// </summary>
|
||||
public string Barcode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Tipo codice a barre
|
||||
/// </summary>
|
||||
public BarcodeType Type { get; set; } = BarcodeType.EAN13;
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione (es. "Confezione da 6", "Pallet")
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità associata al barcode (es. 6 per confezione da 6)
|
||||
/// </summary>
|
||||
public decimal Quantity { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Se è il barcode principale
|
||||
/// </summary>
|
||||
public bool IsPrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se attivo
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseArticle? Article { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di codice a barre
|
||||
/// </summary>
|
||||
public enum BarcodeType
|
||||
{
|
||||
/// <summary>
|
||||
/// EAN-13 (European Article Number)
|
||||
/// </summary>
|
||||
EAN13 = 0,
|
||||
|
||||
/// <summary>
|
||||
/// EAN-8
|
||||
/// </summary>
|
||||
EAN8 = 1,
|
||||
|
||||
/// <summary>
|
||||
/// UPC-A (Universal Product Code)
|
||||
/// </summary>
|
||||
UPCA = 2,
|
||||
|
||||
/// <summary>
|
||||
/// UPC-E
|
||||
/// </summary>
|
||||
UPCE = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Code 128
|
||||
/// </summary>
|
||||
Code128 = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Code 39
|
||||
/// </summary>
|
||||
Code39 = 5,
|
||||
|
||||
/// <summary>
|
||||
/// QR Code
|
||||
/// </summary>
|
||||
QRCode = 6,
|
||||
|
||||
/// <summary>
|
||||
/// DataMatrix
|
||||
/// </summary>
|
||||
DataMatrix = 7,
|
||||
|
||||
/// <summary>
|
||||
/// Codice interno
|
||||
/// </summary>
|
||||
Internal = 8
|
||||
}
|
||||
145
src/backend/Zentral.Domain/Entities/Warehouse/ArticleBatch.cs
Normal file
145
src/backend/Zentral.Domain/Entities/Warehouse/ArticleBatch.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Partita/Lotto di un articolo
|
||||
/// </summary>
|
||||
public class ArticleBatch : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Articolo di riferimento
|
||||
/// </summary>
|
||||
public int ArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Codice partita/lotto
|
||||
/// </summary>
|
||||
public string BatchNumber { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Data di produzione
|
||||
/// </summary>
|
||||
public DateTime? ProductionDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data di scadenza
|
||||
/// </summary>
|
||||
public DateTime? ExpiryDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Lotto fornitore
|
||||
/// </summary>
|
||||
public string? SupplierBatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID fornitore di origine
|
||||
/// </summary>
|
||||
public int? SupplierId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costo specifico della partita
|
||||
/// </summary>
|
||||
public decimal? UnitCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità iniziale del lotto
|
||||
/// </summary>
|
||||
public decimal InitialQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità corrente disponibile
|
||||
/// </summary>
|
||||
public decimal CurrentQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità riservata
|
||||
/// </summary>
|
||||
public decimal ReservedQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stato della partita
|
||||
/// </summary>
|
||||
public BatchStatus Status { get; set; } = BatchStatus.Available;
|
||||
|
||||
/// <summary>
|
||||
/// Risultato controllo qualità
|
||||
/// </summary>
|
||||
public QualityStatus? QualityStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data ultimo controllo qualità
|
||||
/// </summary>
|
||||
public DateTime? LastQualityCheckDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Certificazioni associate (JSON array)
|
||||
/// </summary>
|
||||
public string? Certifications { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note sulla partita
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseArticle? Article { get; set; }
|
||||
public ICollection<StockLevel> StockLevels { get; set; } = new List<StockLevel>();
|
||||
public ICollection<StockMovementLine> MovementLines { get; set; } = new List<StockMovementLine>();
|
||||
public ICollection<ArticleSerial> Serials { get; set; } = new List<ArticleSerial>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stato della partita/lotto
|
||||
/// </summary>
|
||||
public enum BatchStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Disponibile per utilizzo
|
||||
/// </summary>
|
||||
Available = 0,
|
||||
|
||||
/// <summary>
|
||||
/// In quarantena (in attesa controllo qualità)
|
||||
/// </summary>
|
||||
Quarantine = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Bloccato (non utilizzabile)
|
||||
/// </summary>
|
||||
Blocked = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Scaduto
|
||||
/// </summary>
|
||||
Expired = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Esaurito
|
||||
/// </summary>
|
||||
Depleted = 4
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stato qualità della partita
|
||||
/// </summary>
|
||||
public enum QualityStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Non controllato
|
||||
/// </summary>
|
||||
NotChecked = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Approvato
|
||||
/// </summary>
|
||||
Approved = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Respinto
|
||||
/// </summary>
|
||||
Rejected = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Approvato con riserva
|
||||
/// </summary>
|
||||
ConditionallyApproved = 3
|
||||
}
|
||||
129
src/backend/Zentral.Domain/Entities/Warehouse/ArticleSerial.cs
Normal file
129
src/backend/Zentral.Domain/Entities/Warehouse/ArticleSerial.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Seriale/Matricola di un articolo
|
||||
/// </summary>
|
||||
public class ArticleSerial : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Articolo di riferimento
|
||||
/// </summary>
|
||||
public int ArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Partita di appartenenza (opzionale)
|
||||
/// </summary>
|
||||
public int? BatchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Numero seriale/matricola
|
||||
/// </summary>
|
||||
public string SerialNumber { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Seriale del produttore (se diverso)
|
||||
/// </summary>
|
||||
public string? ManufacturerSerial { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data di produzione
|
||||
/// </summary>
|
||||
public DateTime? ProductionDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data di scadenza garanzia
|
||||
/// </summary>
|
||||
public DateTime? WarrantyExpiryDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino corrente
|
||||
/// </summary>
|
||||
public int? CurrentWarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stato del seriale
|
||||
/// </summary>
|
||||
public SerialStatus Status { get; set; } = SerialStatus.Available;
|
||||
|
||||
/// <summary>
|
||||
/// Costo specifico del seriale
|
||||
/// </summary>
|
||||
public decimal? UnitCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID fornitore di origine
|
||||
/// </summary>
|
||||
public int? SupplierId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID cliente (se venduto)
|
||||
/// </summary>
|
||||
public int? CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data di vendita
|
||||
/// </summary>
|
||||
public DateTime? SoldDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Riferimento documento di vendita
|
||||
/// </summary>
|
||||
public string? SalesReference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attributi aggiuntivi (JSON)
|
||||
/// </summary>
|
||||
public string? Attributes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseArticle? Article { get; set; }
|
||||
public ArticleBatch? Batch { get; set; }
|
||||
public WarehouseLocation? CurrentWarehouse { get; set; }
|
||||
public ICollection<StockMovementLine> MovementLines { get; set; } = new List<StockMovementLine>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stato del seriale
|
||||
/// </summary>
|
||||
public enum SerialStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Disponibile in magazzino
|
||||
/// </summary>
|
||||
Available = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Riservato (impegnato per ordine)
|
||||
/// </summary>
|
||||
Reserved = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Venduto
|
||||
/// </summary>
|
||||
Sold = 2,
|
||||
|
||||
/// <summary>
|
||||
/// In riparazione
|
||||
/// </summary>
|
||||
InRepair = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Difettoso/Danneggiato
|
||||
/// </summary>
|
||||
Defective = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Restituito
|
||||
/// </summary>
|
||||
Returned = 5,
|
||||
|
||||
/// <summary>
|
||||
/// Dismesso
|
||||
/// </summary>
|
||||
Disposed = 6
|
||||
}
|
||||
236
src/backend/Zentral.Domain/Entities/Warehouse/InventoryCount.cs
Normal file
236
src/backend/Zentral.Domain/Entities/Warehouse/InventoryCount.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Testata inventario fisico
|
||||
/// </summary>
|
||||
public class InventoryCount : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice inventario
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione inventario
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Data inventario
|
||||
/// </summary>
|
||||
public DateTime InventoryDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino (null = tutti i magazzini)
|
||||
/// </summary>
|
||||
public int? WarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Categoria articoli (null = tutte)
|
||||
/// </summary>
|
||||
public int? CategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di inventario
|
||||
/// </summary>
|
||||
public InventoryType Type { get; set; } = InventoryType.Full;
|
||||
|
||||
/// <summary>
|
||||
/// Stato inventario
|
||||
/// </summary>
|
||||
public InventoryStatus Status { get; set; } = InventoryStatus.Draft;
|
||||
|
||||
/// <summary>
|
||||
/// Data inizio conteggio
|
||||
/// </summary>
|
||||
public DateTime? StartDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data fine conteggio
|
||||
/// </summary>
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data conferma
|
||||
/// </summary>
|
||||
public DateTime? ConfirmedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Utente che ha confermato
|
||||
/// </summary>
|
||||
public string? ConfirmedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID movimento di rettifica generato
|
||||
/// </summary>
|
||||
public int? AdjustmentMovementId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore differenze positive
|
||||
/// </summary>
|
||||
public decimal? PositiveDifferenceValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore differenze negative
|
||||
/// </summary>
|
||||
public decimal? NegativeDifferenceValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseLocation? Warehouse { get; set; }
|
||||
public WarehouseArticleCategory? Category { get; set; }
|
||||
public StockMovement? AdjustmentMovement { get; set; }
|
||||
public ICollection<InventoryCountLine> Lines { get; set; } = new List<InventoryCountLine>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Riga dettaglio inventario
|
||||
/// </summary>
|
||||
public class InventoryCountLine : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Inventario padre
|
||||
/// </summary>
|
||||
public int InventoryCountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Articolo
|
||||
/// </summary>
|
||||
public int ArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino
|
||||
/// </summary>
|
||||
public int WarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Partita (se gestito a lotti)
|
||||
/// </summary>
|
||||
public int? BatchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ubicazione
|
||||
/// </summary>
|
||||
public string? LocationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità teorica (da sistema)
|
||||
/// </summary>
|
||||
public decimal TheoreticalQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità contata
|
||||
/// </summary>
|
||||
public decimal? CountedQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Differenza = CountedQuantity - TheoreticalQuantity
|
||||
/// </summary>
|
||||
public decimal? Difference => CountedQuantity.HasValue
|
||||
? CountedQuantity.Value - TheoreticalQuantity
|
||||
: null;
|
||||
|
||||
/// <summary>
|
||||
/// Costo unitario per valorizzazione differenza
|
||||
/// </summary>
|
||||
public decimal? UnitCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore differenza
|
||||
/// </summary>
|
||||
public decimal? DifferenceValue => Difference.HasValue && UnitCost.HasValue
|
||||
? Difference.Value * UnitCost.Value
|
||||
: null;
|
||||
|
||||
/// <summary>
|
||||
/// Data/ora del conteggio
|
||||
/// </summary>
|
||||
public DateTime? CountedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Utente che ha effettuato il conteggio
|
||||
/// </summary>
|
||||
public string? CountedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Secondo conteggio (per verifica discrepanze)
|
||||
/// </summary>
|
||||
public decimal? SecondCountQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Utente secondo conteggio
|
||||
/// </summary>
|
||||
public string? SecondCountBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note riga
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public InventoryCount? InventoryCount { get; set; }
|
||||
public WarehouseArticle? Article { get; set; }
|
||||
public WarehouseLocation? Warehouse { get; set; }
|
||||
public ArticleBatch? Batch { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di inventario
|
||||
/// </summary>
|
||||
public enum InventoryType
|
||||
{
|
||||
/// <summary>
|
||||
/// Inventario completo
|
||||
/// </summary>
|
||||
Full = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Inventario parziale (per categoria/ubicazione)
|
||||
/// </summary>
|
||||
Partial = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Inventario rotativo (ciclico)
|
||||
/// </summary>
|
||||
Cyclic = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Inventario a campione
|
||||
/// </summary>
|
||||
Sample = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stato dell'inventario
|
||||
/// </summary>
|
||||
public enum InventoryStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Bozza
|
||||
/// </summary>
|
||||
Draft = 0,
|
||||
|
||||
/// <summary>
|
||||
/// In corso
|
||||
/// </summary>
|
||||
InProgress = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Completato (in attesa conferma)
|
||||
/// </summary>
|
||||
Completed = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Confermato (rettifiche applicate)
|
||||
/// </summary>
|
||||
Confirmed = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Annullato
|
||||
/// </summary>
|
||||
Cancelled = 4
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Causale movimento di magazzino
|
||||
/// </summary>
|
||||
public class MovementReason : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice causale
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione causale
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Tipo movimento associato
|
||||
/// </summary>
|
||||
public MovementType MovementType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Segno del movimento sulla giacenza (+1 carico, -1 scarico)
|
||||
/// </summary>
|
||||
public int StockSign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, richiede riferimento documento esterno
|
||||
/// </summary>
|
||||
public bool RequiresExternalReference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, richiede valorizzazione
|
||||
/// </summary>
|
||||
public bool RequiresValuation { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Se true, aggiorna il costo medio
|
||||
/// </summary>
|
||||
public bool UpdatesAverageCost { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Se true, è una causale di sistema (non modificabile)
|
||||
/// </summary>
|
||||
public bool IsSystem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se attiva
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Ordine visualizzazione
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public ICollection<StockMovement> Movements { get; set; } = new List<StockMovement>();
|
||||
}
|
||||
72
src/backend/Zentral.Domain/Entities/Warehouse/StockLevel.cs
Normal file
72
src/backend/Zentral.Domain/Entities/Warehouse/StockLevel.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Giacenza articolo per magazzino, partita
|
||||
/// </summary>
|
||||
public class StockLevel : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Articolo
|
||||
/// </summary>
|
||||
public int ArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino
|
||||
/// </summary>
|
||||
public int WarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Partita (opzionale, se gestito a lotti)
|
||||
/// </summary>
|
||||
public int? BatchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità fisica in giacenza
|
||||
/// </summary>
|
||||
public decimal Quantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità riservata (impegnata per ordini)
|
||||
/// </summary>
|
||||
public decimal ReservedQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità disponibile = Quantity - ReservedQuantity
|
||||
/// </summary>
|
||||
public decimal AvailableQuantity => Quantity - ReservedQuantity;
|
||||
|
||||
/// <summary>
|
||||
/// Quantità in ordine (in arrivo)
|
||||
/// </summary>
|
||||
public decimal OnOrderQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore totale della giacenza (calcolato)
|
||||
/// </summary>
|
||||
public decimal? StockValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costo unitario medio per questa giacenza
|
||||
/// </summary>
|
||||
public decimal? UnitCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data ultimo movimento
|
||||
/// </summary>
|
||||
public DateTime? LastMovementDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data ultimo inventario
|
||||
/// </summary>
|
||||
public DateTime? LastInventoryDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ubicazione specifica nel magazzino (scaffale, corridoio, etc.)
|
||||
/// </summary>
|
||||
public string? LocationCode { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseArticle? Article { get; set; }
|
||||
public WarehouseLocation? Warehouse { get; set; }
|
||||
public ArticleBatch? Batch { get; set; }
|
||||
}
|
||||
201
src/backend/Zentral.Domain/Entities/Warehouse/StockMovement.cs
Normal file
201
src/backend/Zentral.Domain/Entities/Warehouse/StockMovement.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Testata movimento di magazzino (carico, scarico, trasferimento, rettifica)
|
||||
/// </summary>
|
||||
public class StockMovement : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Numero documento movimento
|
||||
/// </summary>
|
||||
public string DocumentNumber { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Data movimento
|
||||
/// </summary>
|
||||
public DateTime MovementDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tipo movimento
|
||||
/// </summary>
|
||||
public MovementType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Causale movimento
|
||||
/// </summary>
|
||||
public int? ReasonId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino di origine (per scarichi e trasferimenti)
|
||||
/// </summary>
|
||||
public int? SourceWarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino di destinazione (per carichi e trasferimenti)
|
||||
/// </summary>
|
||||
public int? DestinationWarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Riferimento documento esterno (DDT, fattura, ordine)
|
||||
/// </summary>
|
||||
public string? ExternalReference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tipo documento esterno
|
||||
/// </summary>
|
||||
public ExternalDocumentType? ExternalDocumentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID fornitore (per carichi da acquisto)
|
||||
/// </summary>
|
||||
public int? SupplierId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID cliente (per scarichi per vendita)
|
||||
/// </summary>
|
||||
public int? CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stato del movimento
|
||||
/// </summary>
|
||||
public MovementStatus Status { get; set; } = MovementStatus.Draft;
|
||||
|
||||
/// <summary>
|
||||
/// Data conferma movimento
|
||||
/// </summary>
|
||||
public DateTime? ConfirmedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Utente che ha confermato
|
||||
/// </summary>
|
||||
public string? ConfirmedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore totale movimento
|
||||
/// </summary>
|
||||
public decimal? TotalValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note movimento
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseLocation? SourceWarehouse { get; set; }
|
||||
public WarehouseLocation? DestinationWarehouse { get; set; }
|
||||
public MovementReason? Reason { get; set; }
|
||||
public ICollection<StockMovementLine> Lines { get; set; } = new List<StockMovementLine>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di movimento magazzino
|
||||
/// </summary>
|
||||
public enum MovementType
|
||||
{
|
||||
/// <summary>
|
||||
/// Carico (aumento giacenza)
|
||||
/// </summary>
|
||||
Inbound = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Scarico (diminuzione giacenza)
|
||||
/// </summary>
|
||||
Outbound = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Trasferimento tra magazzini
|
||||
/// </summary>
|
||||
Transfer = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Rettifica inventariale (positiva o negativa)
|
||||
/// </summary>
|
||||
Adjustment = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Produzione (carico da ciclo produttivo)
|
||||
/// </summary>
|
||||
Production = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Consumo (scarico per produzione)
|
||||
/// </summary>
|
||||
Consumption = 5,
|
||||
|
||||
/// <summary>
|
||||
/// Reso a fornitore
|
||||
/// </summary>
|
||||
SupplierReturn = 6,
|
||||
|
||||
/// <summary>
|
||||
/// Reso da cliente
|
||||
/// </summary>
|
||||
CustomerReturn = 7
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stato del movimento
|
||||
/// </summary>
|
||||
public enum MovementStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Bozza (non ancora confermato)
|
||||
/// </summary>
|
||||
Draft = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Confermato (giacenze aggiornate)
|
||||
/// </summary>
|
||||
Confirmed = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Annullato
|
||||
/// </summary>
|
||||
Cancelled = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipo documento esterno collegato
|
||||
/// </summary>
|
||||
public enum ExternalDocumentType
|
||||
{
|
||||
/// <summary>
|
||||
/// Ordine fornitore
|
||||
/// </summary>
|
||||
PurchaseOrder = 0,
|
||||
|
||||
/// <summary>
|
||||
/// DDT entrata
|
||||
/// </summary>
|
||||
InboundDeliveryNote = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Fattura acquisto
|
||||
/// </summary>
|
||||
PurchaseInvoice = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Ordine cliente
|
||||
/// </summary>
|
||||
SalesOrder = 3,
|
||||
|
||||
/// <summary>
|
||||
/// DDT uscita
|
||||
/// </summary>
|
||||
OutboundDeliveryNote = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Fattura vendita
|
||||
/// </summary>
|
||||
SalesInvoice = 5,
|
||||
|
||||
/// <summary>
|
||||
/// Ordine di produzione
|
||||
/// </summary>
|
||||
ProductionOrder = 6,
|
||||
|
||||
/// <summary>
|
||||
/// Documento inventario
|
||||
/// </summary>
|
||||
InventoryDocument = 7
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Riga dettaglio movimento di magazzino
|
||||
/// </summary>
|
||||
public class StockMovementLine : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Movimento padre
|
||||
/// </summary>
|
||||
public int MovementId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Numero riga
|
||||
/// </summary>
|
||||
public int LineNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Articolo
|
||||
/// </summary>
|
||||
public int ArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Partita (se gestito a lotti)
|
||||
/// </summary>
|
||||
public int? BatchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Seriale (se gestito a seriali) - per movimenti di singoli pezzi
|
||||
/// </summary>
|
||||
public int? SerialId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità movimentata
|
||||
/// </summary>
|
||||
public decimal Quantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unità di misura
|
||||
/// </summary>
|
||||
public string UnitOfMeasure { get; set; } = "PZ";
|
||||
|
||||
/// <summary>
|
||||
/// Costo unitario (per valorizzazione)
|
||||
/// </summary>
|
||||
public decimal? UnitCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore totale riga
|
||||
/// </summary>
|
||||
public decimal? LineValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ubicazione origine (per prelievi specifici)
|
||||
/// </summary>
|
||||
public string? SourceLocationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ubicazione destinazione (per posizionamenti specifici)
|
||||
/// </summary>
|
||||
public string? DestinationLocationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Riferimento riga documento esterno
|
||||
/// </summary>
|
||||
public string? ExternalLineReference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note riga
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public StockMovement? Movement { get; set; }
|
||||
public WarehouseArticle? Article { get; set; }
|
||||
public ArticleBatch? Batch { get; set; }
|
||||
public ArticleSerial? Serial { get; set; }
|
||||
}
|
||||
153
src/backend/Zentral.Domain/Entities/Warehouse/StockValuation.cs
Normal file
153
src/backend/Zentral.Domain/Entities/Warehouse/StockValuation.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Storico valorizzazione magazzino per periodo
|
||||
/// </summary>
|
||||
public class StockValuation : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Data della valorizzazione
|
||||
/// </summary>
|
||||
public DateTime ValuationDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Periodo di riferimento (YYYYMM)
|
||||
/// </summary>
|
||||
public int Period { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Articolo
|
||||
/// </summary>
|
||||
public int ArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino (null = totale tutti i magazzini)
|
||||
/// </summary>
|
||||
public int? WarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità a fine periodo
|
||||
/// </summary>
|
||||
public decimal Quantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di valorizzazione usato
|
||||
/// </summary>
|
||||
public ValuationMethod Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costo unitario calcolato
|
||||
/// </summary>
|
||||
public decimal UnitCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore totale = Quantity * UnitCost
|
||||
/// </summary>
|
||||
public decimal TotalValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità in carico nel periodo
|
||||
/// </summary>
|
||||
public decimal InboundQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore carichi nel periodo
|
||||
/// </summary>
|
||||
public decimal InboundValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità in scarico nel periodo
|
||||
/// </summary>
|
||||
public decimal OutboundQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore scarichi nel periodo
|
||||
/// </summary>
|
||||
public decimal OutboundValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se è una chiusura definitiva (non più modificabile)
|
||||
/// </summary>
|
||||
public bool IsClosed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data chiusura
|
||||
/// </summary>
|
||||
public DateTime? ClosedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Utente che ha chiuso
|
||||
/// </summary>
|
||||
public string? ClosedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseArticle? Article { get; set; }
|
||||
public WarehouseLocation? Warehouse { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dettaglio valorizzazione FIFO/LIFO per layer
|
||||
/// </summary>
|
||||
public class StockValuationLayer : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Articolo
|
||||
/// </summary>
|
||||
public int ArticleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino
|
||||
/// </summary>
|
||||
public int WarehouseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Partita (opzionale)
|
||||
/// </summary>
|
||||
public int? BatchId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data del layer (data carico originale)
|
||||
/// </summary>
|
||||
public DateTime LayerDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Movimento di carico che ha creato il layer
|
||||
/// </summary>
|
||||
public int? SourceMovementId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità originale del layer
|
||||
/// </summary>
|
||||
public decimal OriginalQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità residua nel layer
|
||||
/// </summary>
|
||||
public decimal RemainingQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costo unitario del layer
|
||||
/// </summary>
|
||||
public decimal UnitCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore residuo = RemainingQuantity * UnitCost
|
||||
/// </summary>
|
||||
public decimal RemainingValue => RemainingQuantity * UnitCost;
|
||||
|
||||
/// <summary>
|
||||
/// Se il layer è esaurito
|
||||
/// </summary>
|
||||
public bool IsExhausted { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseArticle? Article { get; set; }
|
||||
public WarehouseLocation? Warehouse { get; set; }
|
||||
public ArticleBatch? Batch { get; set; }
|
||||
public StockMovement? SourceMovement { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Articolo del modulo magazzino con gestione completa di partite e seriali
|
||||
/// </summary>
|
||||
public class WarehouseArticle : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice univoco articolo (SKU) - generato automaticamente
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Codice alternativo (opzionale, inserito dall'utente)
|
||||
/// </summary>
|
||||
public string? AlternativeCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione articolo
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione breve per etichette
|
||||
/// </summary>
|
||||
public string? ShortDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Codice a barre principale (EAN/UPC)
|
||||
/// </summary>
|
||||
public string? Barcode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Codice fornitore/produttore
|
||||
/// </summary>
|
||||
public string? ManufacturerCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Categoria articolo
|
||||
/// </summary>
|
||||
public int? CategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unità di misura principale (es. PZ, KG, LT, MT)
|
||||
/// </summary>
|
||||
public string UnitOfMeasure { get; set; } = "PZ";
|
||||
|
||||
/// <summary>
|
||||
/// Unità di misura secondaria per conversione
|
||||
/// </summary>
|
||||
public string? SecondaryUnitOfMeasure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fattore di conversione tra UoM primaria e secondaria
|
||||
/// </summary>
|
||||
public decimal? UnitConversionFactor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di gestione magazzino
|
||||
/// </summary>
|
||||
public StockManagementType StockManagement { get; set; } = StockManagementType.Standard;
|
||||
|
||||
/// <summary>
|
||||
/// Se true, l'articolo è gestito a partite (lotti)
|
||||
/// </summary>
|
||||
public bool IsBatchManaged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, l'articolo è gestito a seriali
|
||||
/// </summary>
|
||||
public bool IsSerialManaged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, l'articolo ha scadenza
|
||||
/// </summary>
|
||||
public bool HasExpiry { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Giorni di preavviso scadenza
|
||||
/// </summary>
|
||||
public int? ExpiryWarningDays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Scorta minima (sotto questo livello scatta alert)
|
||||
/// </summary>
|
||||
public decimal? MinimumStock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Scorta massima
|
||||
/// </summary>
|
||||
public decimal? MaximumStock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Punto di riordino
|
||||
/// </summary>
|
||||
public decimal? ReorderPoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quantità di riordino standard
|
||||
/// </summary>
|
||||
public decimal? ReorderQuantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Lead time in giorni per approvvigionamento
|
||||
/// </summary>
|
||||
public int? LeadTimeDays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di valorizzazione per questo articolo (override del default)
|
||||
/// </summary>
|
||||
public ValuationMethod? ValuationMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costo standard (per valorizzazione a costo standard)
|
||||
/// </summary>
|
||||
public decimal? StandardCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo costo di acquisto
|
||||
/// </summary>
|
||||
public decimal? LastPurchaseCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costo medio ponderato corrente
|
||||
/// </summary>
|
||||
public decimal? WeightedAverageCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prezzo di vendita base
|
||||
/// </summary>
|
||||
public decimal? BaseSellingPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Peso in Kg
|
||||
/// </summary>
|
||||
public decimal? Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Volume in metri cubi
|
||||
/// </summary>
|
||||
public decimal? Volume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Larghezza in cm
|
||||
/// </summary>
|
||||
public decimal? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Altezza in cm
|
||||
/// </summary>
|
||||
public decimal? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profondità in cm
|
||||
/// </summary>
|
||||
public decimal? Depth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Immagine principale
|
||||
/// </summary>
|
||||
public byte[]? Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Mime type immagine
|
||||
/// </summary>
|
||||
public string? ImageMimeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se attivo, l'articolo può essere movimentato
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Note aggiuntive
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseArticleCategory? Category { get; set; }
|
||||
public ICollection<StockLevel> StockLevels { get; set; } = new List<StockLevel>();
|
||||
public ICollection<StockMovementLine> MovementLines { get; set; } = new List<StockMovementLine>();
|
||||
public ICollection<ArticleBatch> Batches { get; set; } = new List<ArticleBatch>();
|
||||
public ICollection<ArticleSerial> Serials { get; set; } = new List<ArticleSerial>();
|
||||
public ICollection<ArticleBarcode> Barcodes { get; set; } = new List<ArticleBarcode>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di gestione magazzino per l'articolo
|
||||
/// </summary>
|
||||
public enum StockManagementType
|
||||
{
|
||||
/// <summary>
|
||||
/// Gestione standard (quantità)
|
||||
/// </summary>
|
||||
Standard = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Non gestito a magazzino (servizi, ecc.)
|
||||
/// </summary>
|
||||
NotManaged = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Gestione a peso variabile
|
||||
/// </summary>
|
||||
VariableWeight = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Kit/Distinta base
|
||||
/// </summary>
|
||||
Kit = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di valorizzazione magazzino
|
||||
/// </summary>
|
||||
public enum ValuationMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// Costo medio ponderato
|
||||
/// </summary>
|
||||
WeightedAverage = 0,
|
||||
|
||||
/// <summary>
|
||||
/// First In First Out
|
||||
/// </summary>
|
||||
FIFO = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Last In First Out
|
||||
/// </summary>
|
||||
LIFO = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Costo standard
|
||||
/// </summary>
|
||||
StandardCost = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Costo specifico (per partita/seriale)
|
||||
/// </summary>
|
||||
SpecificCost = 4
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Categoria articoli magazzino con struttura gerarchica
|
||||
/// </summary>
|
||||
public class WarehouseArticleCategory : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice categoria - generato automaticamente
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Codice alternativo (opzionale, inserito dall'utente)
|
||||
/// </summary>
|
||||
public string? AlternativeCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nome categoria
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID categoria padre (per gerarchia)
|
||||
/// </summary>
|
||||
public int? ParentCategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Livello nella gerarchia (0 = root)
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path completo codici (es. "001.002.003")
|
||||
/// </summary>
|
||||
public string? FullPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Icona categoria (nome icona MUI)
|
||||
/// </summary>
|
||||
public string? Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Colore categoria (hex)
|
||||
/// </summary>
|
||||
public string? Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di valorizzazione default per articoli di questa categoria
|
||||
/// </summary>
|
||||
public ValuationMethod? DefaultValuationMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ordine di visualizzazione
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se attiva
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Note
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public WarehouseArticleCategory? ParentCategory { get; set; }
|
||||
public ICollection<WarehouseArticleCategory> ChildCategories { get; set; } = new List<WarehouseArticleCategory>();
|
||||
public ICollection<WarehouseArticle> Articles { get; set; } = new List<WarehouseArticle>();
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
namespace Zentral.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Rappresenta un magazzino fisico o logico
|
||||
/// </summary>
|
||||
public class WarehouseLocation : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice univoco del magazzino - generato automaticamente
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Codice alternativo (opzionale, inserito dall'utente)
|
||||
/// </summary>
|
||||
public string? AlternativeCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nome descrittivo del magazzino
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione estesa
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indirizzo del magazzino
|
||||
/// </summary>
|
||||
public string? Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Città
|
||||
/// </summary>
|
||||
public string? City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Provincia
|
||||
/// </summary>
|
||||
public string? Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CAP
|
||||
/// </summary>
|
||||
public string? PostalCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nazione
|
||||
/// </summary>
|
||||
public string? Country { get; set; } = "Italia";
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di magazzino (fisico, logico, transito, reso, etc.)
|
||||
/// </summary>
|
||||
public WarehouseType Type { get; set; } = WarehouseType.Physical;
|
||||
|
||||
/// <summary>
|
||||
/// Se true, è il magazzino predefinito per carichi/scarichi
|
||||
/// </summary>
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se attivo può ricevere movimenti
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Ordine di visualizzazione
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note aggiuntive
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public ICollection<StockLevel> StockLevels { get; set; } = new List<StockLevel>();
|
||||
public ICollection<StockMovement> SourceMovements { get; set; } = new List<StockMovement>();
|
||||
public ICollection<StockMovement> DestinationMovements { get; set; } = new List<StockMovement>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di magazzino
|
||||
/// </summary>
|
||||
public enum WarehouseType
|
||||
{
|
||||
/// <summary>
|
||||
/// Magazzino fisico standard
|
||||
/// </summary>
|
||||
Physical = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino logico (virtuale)
|
||||
/// </summary>
|
||||
Logical = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino di transito
|
||||
/// </summary>
|
||||
Transit = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino resi
|
||||
/// </summary>
|
||||
Returns = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino scarti/difettosi
|
||||
/// </summary>
|
||||
Defective = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Magazzino conto lavoro
|
||||
/// </summary>
|
||||
Subcontract = 5
|
||||
}
|
||||
Reference in New Issue
Block a user