//
// This is here so CodeMaid doesn't reorganize this document
//
namespace EgwCoreLib.Lux.Data.DbModel.Sales
{
[Table("sales_offer_row")]
public class OfferRowModel
{
///
/// ID del record
///
[Key]
public int OfferRowID { get; set; }
///
/// Riferimento offerta
///
public int OfferID { get; set; }
///
/// Riga Offerta (per ordinamento)
///
public int RowNum { get; set; } = 0;
///
/// Environment della richiesta
///
public EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS Envir { get; set; } = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW;
///
/// Campo salvato dell'UID da codice DataMatrix calcolato
/// inizia per SOR = SalesOfferRow
///
public string OfferRowUID { get; set; } = "SOR.25.0123ABCD";
///
/// Codice calcolato offerta ANNO.ID_RIGA_OFFERTA in HEX (0xFFFFFFFF)
///
[NotMapped]
public string OfferRowDtx
{
get => $"SOR.{Inserted:yy}.{OfferRowID:X8}";
}
///
/// ID dell'articolo di vendita offerto
///
public int? SellingItemID { get; set; }
///
/// Definisce se sia calcolabile, dato il tipo SellingItem
///
[NotMapped]
public bool IsNote => SellingItemID == null;
///
/// Riferimento (opzionale) al template da cui è derivato
///
public int? TemplateRowID { get; set; } = null;
///
/// 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(OfferRowUID) ? OfferRowDtx : OfferRowUID;
}
else
{
if (SellingItemNav != null)
{
answ = SellingItemNav.ImgUID;
}
else if (SellingItemID > 0)
{
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;
}
}
///
/// 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): somma dei WorkCost da ItemSteps
///
public double StepCost { get; set; } = 0;
///
/// Prezzo produzione Fase/Step (scontabile): somma dei WorkPrice da ItemSteps
///
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;
}
///
/// 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 dei Job Cost Drivers necessari x calcolo Steps come Lista(JcdDTO)
/// - idealmente calcolati dall'engine
/// - in alternativa quelli di default
///
public string ItemJCD { get; set; } = "";
///
/// Lista dei TAGS associati all'item (es selezione ciclo)
///
public string ItemTags { get; set; } = "";
///
/// Quantità degli item da produrre per PEZZO (es parti del serramento, singole parti BTL...)
///
public int ProdItemQty { 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 del JobTask, valorizzati (Fasi Costificate, sommabili) per la stima tempi / costi
///
public string ItemSteps { 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 Offer
///
[ForeignKey("OfferID")]
public virtual OfferModel OfferNav { get; set; } = null!;
///
/// Navigazione TemplateRow
///
[ForeignKey("TemplateRowID")]
public virtual TemplateRowModel? TemplateRowNav { get; set; }
///
/// Navigazione Item
///
[ForeignKey("SellingItemID")]
public virtual SellingItemModel? SellingItemNav { get; set; }
}
}