-
This commit is contained in:
96
src/Apollinare.Domain/Entities/Warehouse/ArticleBarcode.cs
Normal file
96
src/Apollinare.Domain/Entities/Warehouse/ArticleBarcode.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
namespace Apollinare.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/Apollinare.Domain/Entities/Warehouse/ArticleBatch.cs
Normal file
145
src/Apollinare.Domain/Entities/Warehouse/ArticleBatch.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
namespace Apollinare.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/Apollinare.Domain/Entities/Warehouse/ArticleSerial.cs
Normal file
129
src/Apollinare.Domain/Entities/Warehouse/ArticleSerial.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
namespace Apollinare.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/Apollinare.Domain/Entities/Warehouse/InventoryCount.cs
Normal file
236
src/Apollinare.Domain/Entities/Warehouse/InventoryCount.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
namespace Apollinare.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
|
||||
}
|
||||
65
src/Apollinare.Domain/Entities/Warehouse/MovementReason.cs
Normal file
65
src/Apollinare.Domain/Entities/Warehouse/MovementReason.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
namespace Apollinare.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/Apollinare.Domain/Entities/Warehouse/StockLevel.cs
Normal file
72
src/Apollinare.Domain/Entities/Warehouse/StockLevel.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
namespace Apollinare.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/Apollinare.Domain/Entities/Warehouse/StockMovement.cs
Normal file
201
src/Apollinare.Domain/Entities/Warehouse/StockMovement.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
namespace Apollinare.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 Apollinare.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/Apollinare.Domain/Entities/Warehouse/StockValuation.cs
Normal file
153
src/Apollinare.Domain/Entities/Warehouse/StockValuation.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
namespace Apollinare.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; }
|
||||
}
|
||||
237
src/Apollinare.Domain/Entities/Warehouse/WarehouseArticle.cs
Normal file
237
src/Apollinare.Domain/Entities/Warehouse/WarehouseArticle.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
namespace Apollinare.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)
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <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,72 @@
|
||||
namespace Apollinare.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Categoria articoli magazzino con struttura gerarchica
|
||||
/// </summary>
|
||||
public class WarehouseArticleCategory : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice categoria
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <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>();
|
||||
}
|
||||
113
src/Apollinare.Domain/Entities/Warehouse/WarehouseLocation.cs
Normal file
113
src/Apollinare.Domain/Entities/Warehouse/WarehouseLocation.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
namespace Apollinare.Domain.Entities.Warehouse;
|
||||
|
||||
/// <summary>
|
||||
/// Rappresenta un magazzino fisico o logico
|
||||
/// </summary>
|
||||
public class WarehouseLocation : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Codice univoco del magazzino (es. "MAG01", "CENTRALE")
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <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