// // This is here so CodeMaid doesn't reorganize this document // namespace EgwCoreLib.Lux.Data.DbModel.Sales { [Table("sales_order_row")] public class OrderRowModel { /// /// ID del record /// [Key] public int OrderRowID { get; set; } /// /// Riferimento Ordine /// public int OrderID { get; set; } /// /// Riga Ordine (per ordinamento) /// public int RowNum { get; set; } = 0; /// /// Environment della richiesta /// public EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS Envir { get; set; } = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW; /// /// Enum stato Riga Ordine x assegnazione/pianificazione /// public OrderStates OrderRowState { get; set; } = OrderStates.Created; /// /// Campo salvato dell'UID da codice DataMatrix calcolato /// inizia per SOR = SalesOfferRow /// public string OrderRowUID { get; set; } = "POR.25.0123ABCD"; /// /// Codice calcolato Ordine ANNO.NUMERO /// inizia per PO = PurchaseOrder /// [NotMapped] public string OrderRowCode { get => $"POR.{Inserted:yy}.{OrderRowID:X8}"; } /// /// ID dell'articolo di vendita Orderto /// public int? SellingItemID { get; set; } /// /// Riferimento (opzionale) al template da cui è derivato /// public int? TemplateRowID { get; set; } = null; /// /// Quantità della risorsa /// public double Qty { get; set; } = 1; /// /// Costo dei componeti BOM (RockBottom) /// public double BomCost { get; set; } = 0; /// /// Prezzo dei componeti BOM (scontabile) /// public double BomPrice { get; set; } = 0; /// /// Costo produzione Fase/Step (RockBottom) /// public double StepCost { get; set; } = 0; /// /// Prezzo produzione Fase/Step (scontabile) /// public double StepPrice { get; set; } = 0; /// /// LeadTime puro (tempo di lavorazione): somma dei LeadTime da ItemSteps /// public double StepLeadTime { get; set; } = 0; /// /// FlowTime totale (tempo di attraversamento): somma dei FlowTime da ItemSteps /// public double StepFlowTime { get; set; } = 0; /// /// Costo Totale Risorsa (BOM + Fase) /// [NotMapped] public double UnitCost { get => BomCost + StepCost; } /// /// Costo Totale Risorsa (BOM + Fase) /// [NotMapped] public double UnitPrice { get => BomPrice + StepPrice; } /// /// Sconto massimo applicabile /// [NotMapped] public double MaxDiscount { get => (UnitCost > 0 && UnitPrice > UnitCost) ? (UnitPrice - UnitCost) / UnitPrice : 0; } /// /// Costo Totale risorsa /// [NotMapped] public double TotalCost { get => UnitCost * Qty; } /// /// Costo Totale risorsa /// [NotMapped] public double TotalPrice { get => UnitPrice * Qty; } /// /// Definisce se sia calcolabile, dato il tipo SellingItem /// [NotMapped] public bool CalcEnabled { get => ImgType == ImageType.Calculated; } /// /// Definisce presenza file /// [NotMapped] public bool HasFile { get => !string.IsNullOrEmpty(FileName) && FileSize > 0 || (CalcEnabled && Envir != Constants.EXECENVIRONMENTS.WINDOW); } /// /// Tipo immagine da visualizzare /// public ImageType ImgType { get; set; } = ImageType.ND; /// /// Restituisce UID da impiegare x immagine /// [NotMapped] public string ImgUID { get { string answ = ""; // se non calcolabile if (CalcEnabled) { answ = string.IsNullOrEmpty(OrderRowUID) ? OrderRowCode : OrderRowUID; } else { // cerco in primis se ha template... if (TemplateRowID != null && TemplateRowID > 0) { //answ= $"TR.{TemplateRowID:X16}"; answ = TemplateRowModel.CodeUid(TemplateRowID ?? 0); } // altrimenti da selling item... else if (SellingItemID > 0) { //answ = $"SP.{SellingItemID:X12}"; answ = SellingItemModel.CodeUid(SellingItemID ?? 0); } } return answ; } } /// /// Restituisce Url immagine già calcolato (da sistemare!!!) /// [NotMapped] public string ImgUrl { get { string answ = "empty.svg"; string fType = Envir == Constants.EXECENVIRONMENTS.WINDOW ? "svg" : "png"; string rndImg = $"{DateTime.Now:HHmmssfff}"; if (CalcEnabled) { answ = $"cache/{ImgUID}-{rndImg}.{fType}?env={Envir}"; } else { answ = $"static/{ImgUID}"; } return answ; } } /// /// Valore serializzato della composizione articolo (in formato JWD x finestra) /// public string SerStruct { get; set; } = ""; /// /// Nomi risorsa file associato alla riga offerta (es per BTL) /// URI come risorsa dentro folder offerta/riga-offerta/guid /// public string FileResource { get; set; } = ""; /// /// Nomi file originale associato alla riga offerta (es per BTL) /// public string FileName { get; set; } = ""; /// /// Dimensione del file (per visualizzazione rapida) /// public long FileSize { get; set; } = 0; /// /// BOM serializzata per la produzione dell'item /// public string ItemBOM { get; set; } = ""; /// /// Lista BOM deserializzata /// [NotMapped] public List ListBOM { get { List answ = new(); if (!string.IsNullOrEmpty(ItemBOM) && ItemBOM.Length > 2) { answ = JsonConvert.DeserializeObject>(ItemBOM) ?? new(); } return answ; } } [NotMapped] public bool HasMatReqRow { get => MatReqNav != null && MatReqNav.Count > 0; } /// /// Lista dei Job Cost Drivers calcolati dall'engine (necessari x calcolo Steps) /// public string ItemJCD { get; set; } = ""; /// /// Lista dei TAGS associati all'item (es selezione ciclo) /// public string ItemTags { get; set; } = ""; /// /// Quantità degli item da produrre (es parti del serramento, singole parti BTL...) /// public int ProdItemQty { get; set; } = 0; /// /// Tempo complessivo stimato (secondo Status come stima, balance, ...) /// public decimal ProdEstimTime { get; set; } = 0; /// /// Quantità degli item da produrre per PEZZO (es parti del serramento, singole parti BTL...) /// public double ProdItemQtyTot { get => Qty * ProdItemQty; } /// /// Riferimento JobID Ciclo corrente (tra quelli ammissibili dato ItemJCD) /// public int JobID { get; set; } /// /// Elenco StepDTO (Fasi Costificate, sommabili) per la stima tempi / costi /// public string ItemSteps { get; set; } = ""; /// /// Oggetto serializzato contentente lista degli Estimate su tutte le macchine utilizzabili, serve a /// - carico macchine /// - pianificazione /// public string ProdEstimate { get; set; } = ""; /// /// Valore serializzato info sui RawItem (es: lungh barra / qty barre) /// public string RawItemData { get; set; } = ""; /// /// Validazione dati BOM (Inteso come gruppi tutti trovati/esistenti) /// public bool BomOk { get; set; } = false; /// /// Validazione livello item per Costo e range dimensione /// public bool ItemOk { get; set; } = false; /// /// Note libere /// public string Note { get; set; } = ""; #if false /// /// Stack degli ultimi item serializzati per Uno/Redo actions /// [NotMapped] public List UndoRedoSerStruct { get; set; } = new List(); #endif /// /// DataOra inserimento /// public DateTime Inserted { get; set; } = DateTime.Now; /// /// DataOra ultima modifica /// public DateTime Modified { get; set; } = DateTime.Now; /// /// Indica che è in attesa aggiornamento BOM /// public bool AwaitBom { get; set; } = false; /// /// Indica che è in attesa aggiornamento Price /// public bool AwaitPrice { get; set; } = false; /// /// Dizionario serializzato delle preselezioni (pending, da applicare) /// public string DictPendPresRaw { get; set; } = ""; [NotMapped] public bool HasPendReq { get => !string.IsNullOrEmpty(DictPendPresRaw) && DictPendingPresel.Count > 0; } [NotMapped] public Dictionary DictPendingPresel { get { Dictionary answ = new(); if (!string.IsNullOrEmpty(DictPendPresRaw)) { answ = JsonConvert.DeserializeObject>(DictPendPresRaw) ?? new Dictionary(); } return answ; } //set //{ // DictPendPresRaw = JsonConvert.SerializeObject(value); //} } /// /// Navigazione Order /// [ForeignKey("OrderID")] public virtual OrderModel OrderNav { get; set; } = null!; /// /// Navigazione Item /// [ForeignKey("SellingItemID")] public virtual SellingItemModel? SellingItemNav { get; set; } /// /// Navigazione TemplateRow /// [ForeignKey("TemplateRowID")] public virtual TemplateRowModel? TemplateRowNav { get; set; } /// /// Navigazione alle righe ProdItem /// public virtual ICollection ProdItemNav { get; set; } = new List(); /// /// Many-to-many verso associazione con MatReqNav /// public virtual ICollection MatReqNav { get; set; } = new List(); } }