using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; namespace Sarand.BusinessMgr.Net.Standard.Base.Bus { //======================================================================= public abstract class SbmRequirement : SbmHierarchyItem { //------------------------------------------------------------------- // Columns. public enum Column { Unknown, Pos, Id, //Requirement. TransId, Owner_Name, // Requirement code Assoc_Code, Assoc_AccountManagerCode, Assoc_AccountManagerDesc, Assoc_AccountHandlerCode, Assoc_AccountHandlerDesc, Assoc_Target_Name, Assoc_Target_PhoneMain, Assoc_Target_PhoneAlt, // Transaction details Trans_TypeDesc, Trans_Ref, Trans_RefExt, Trans_DescBrief, Trans_ContactName, Trans_Likelihood, Trans_Raised, Trans_Required, Trans_InProgress, Trans_Closed, Trans_ContactAreaCode, Trans_ContactArea, Trans_BoxCount, Trans_DeliveryStatusCode, Trans_DeliveryStatus, Trans_DeliveryTypeCode, Trans_DeliveryType, Trans_DeliveryMethodCode, Trans_DeliveryMethod, Trans_DeliveryCourierCode, Trans_DeliveryCourier, Trans_DeliveryBookInCode, Trans_DeliveryBookIn, Trans_StockPickerCode, Trans_StockPicker, Trans_DeliveryAmountNet, Trans_DeliveryAmountNet_Fmt, Trans_DeliveryTaxCodeId, Trans_DeliveryTaxCode_Code, Trans_DeliveryTaxCode_Rate, Trans_DeliveryAmountTax, Trans_DeliveryAmountTax_Fmt, Trans_DeliveryAmountTot, Trans_DeliveryAmountTot_Fmt, Trans_DeliveryNominalCode, Trans_DeliveryDepartment, Trans_CurrencyId, Trans_Currency_Code, Trans_Currency_Symbol, Trans_AmountEst, Trans_AmountEst_Fmt, Trans_AmountMax, Trans_AmountMax_Fmt, Trans_AmountNet, Trans_AmountNet_Fmt, Trans_AmountTax, Trans_AmountTax_Fmt, Trans_AmountTot, Trans_AmountTot_Fmt, Trans_TimeEst, Trans_TimeAct, Trans_TimeTot, Trans_CostLabourRateHour, Trans_CostTotal, Trans_CostTotal_Fmt, Trans_AmountMargin, Trans_AmountMargin_Fmt, Trans_PercentMargin, Trans_PercentMargin_Fmt, Trans_Notes, Trans_Flags, Trans_AllocationInd, // Green=Full, Amber=Partial. Trans_AllocationInd_YP, // Y=Full, P=Partial. Trans_ReplacementOrder_Tick, Trans_ReplacementOrder_Y, Trans_StatusDesc, Trans_StatusInd, Trans_Status_OnHold_Tick, // Graphic 'tick' if on hold. Trans_Status_OnHold_Cross, // Graphic 'X' if on hold. Trans_Status_OnHold_Y, // 'Y' if on hold. Trans_ReqntCount, //AssocTarget Address summary. Trans_AssocTarget_Address, Trans_AssocTarget_Address_Name, Trans_AssocTarget_Address_Line1, Trans_AssocTarget_Address_Line2, Trans_AssocTarget_Address_Line3, Trans_AssocTarget_Address_City, Trans_AssocTarget_Address_Province, Trans_AssocTarget_Address_Postcode, //Delivery Address summary. Trans_DeliveryAddress, Trans_DeliveryAddress_Name, Trans_DeliveryAddress_Line1, Trans_DeliveryAddress_Line2, Trans_DeliveryAddress_Line3, Trans_DeliveryAddress_City, Trans_DeliveryAddress_Province, Trans_DeliveryAddress_Postcode, Trans_DeliveryAddress_Phone, Trans_DeliveryAddress_Email, Trans_SourceTrans_Ref, // Source transaction reference. //Relation to items Seq, Started, StartedTime, Started_Day, Required, RequiredTime, Required_Fmt, // Formatted 'Required' date (eg. square brackets around defaulted date). Completed, CompletedTime, JobNumber, CommodityId, ProductCode, DescBrief, DescOutline, DescDetail, PromotionCode, PromotionDesc, Promotion_AltText, NominalCode, Quantity, Quantity_TotalByCommodity, QuantityProd, Allocation_Ind, // Green=Full, Amber=Partial. AllocationInd_YP, // Y=Full, P=Partial. QuantityDispatched, // Via associated disatch items. QuantityInvoiced, // Via associated purchase/sales invoice items. AmountUnit, AmountUnit_Fmt, AmountAct, AmountAct_Fmt, AmountUnitNet, AmountUnitNet_Fmt, // Derived from net amount and quantity. AmountNet, AmountNet_Fmt, TaxCodeId, TaxCode_Code, TaxRate, AmountTax, AmountTax_Fmt, AmountTot, AmountTot_Fmt, PercentDiscountBySalesPrice, // Excl tax PercentDiscountByRetailPrice, // Incl tax //Decimal time (100ths) with mins in brackets TimeEst, TimeEstMins, TimeEstWithMins, TimeEstUnit, TimeEstUnitMins, TimeEstUnitWithMins, TimeAct, TimeActMins, TimeActWithMins, TimeActUnit, TimeActUnitMins, TimeActUnitWithMins, TimeTot, TimeTotMins, TimeTotWithMins, CostTotal, CostTotal_Fmt, // Job costing. CostCalculated, AmountMargin, AmountMargin_Fmt, PercentMargin, PercentMargin_Fmt, ResearchDevelopment_YN, ResearchDevelopment_YBlank, UomDesc, // Source requirement SourceReqnt_DescBrief, SourceReqnt_JobNumber, SourceReqnt_TransRef, SourceReqnt_TransRefExt, OrderItem_JobNumber, // Order or source order info // Commodity details: Cmd_DrawingNo, Cmd_DrawingIssue, Cmd_ImagePath, Cmd_Image, Cmd_Category, Cmd_Location, Cmd_Department, Cmd_CatalogRef, Cmd_Weight, Cmd_WeightUnit, Cmd_Weight_ValueUnits, Cmd_Length, Cmd_LengthUnit, Cmd_Length_ValueUnits, Cmd_Width, Cmd_Height, Cmd_Volume, Cmd_VolumeUnit, Cmd_Volume_ValueUnits, Cmd_Density, Cmd_DensityUnit, Cmd_Density_ValueUnits, Cmd_MinOrderQty, Cmd_PackQtySale, Cmd_BoxQuantity, Cmd_BoxUnit, Cmd_BoxQuantity_ValueUnits, Cmd_Dimensions, Cmd_SpecSummary, Cmd_ICNTariffCode, Cmd_RangeCode, Cmd_RangeDesc, Cmd_ColourCode, Cmd_ColourDesc, Cmd_SourceCode, Cmd_SourceDesc, Cmd_SupplyMethodCode, Cmd_SupplyMethodDesc, Cmd_HandlingCode, Cmd_HandlingDesc, Cmd_DeliveryCode, Cmd_DeliveryDesc, Cmd_MaterialCode, Cmd_MaterialDesc, Cmd_FinishCode, Cmd_FinishDesc, Cmd_PromotionCode, Cmd_PromotionDesc, Cmd_Promotion_AltText, Cmd_CostPrice, Cmd_CostPrice_Fmt, Cmd_MaterialCost, Cmd_MaterialCost_Fmt, Cmd_CurrencyIdMaterial, Cmd_SalesPrice, Cmd_SalesPrice_Fmt, Cmd_RetailPrice, Cmd_RetailPrice_Fmt, Cmd_CarriageCostIndicative, Cmd_CarriageCostIndicative_Fmt, /*Customer's commodity details*/ Cmd_Cust_ProductCode, Cmd_Cust_RetailPrice, Cmd_Cust_RetailPrice_Fmt, Cmd_Cust_CurrencyIdRetail, Cmd_Cust_PromotionCode, Cmd_Cust_PromotionDesc, Cmd_Cust_Promotion_AltText, /*Container Item references*/ CntItm_Count, CntItm_Quantity, // Associated processes: NextProcessDesc, // Next process in sequence that is 'awaiting'. /*Associated requirements*/ AssocReqnt_Reqnt_Id, AssocReqnt_Reqnt_RefCount, AssocReqnt_Reqnt_AmountNet, AssocReqnt_Trans_Id, AssocReqnt_Trans_Type, AssocReqnt_Trans_Ref, AssocReqnt_Trans_AffTarget_Name, AssocReqnt_ItemLink_DataContent, // To extract the cost proportion. // Time records [NB can result in multiple rows per requirement]: ConstTime_Id, ConstTime_Quantity, ConstTime_AffTarget_Name, /*Stock:*/ Stock_Current, Stock_BySalesLocation01, Stock_BySalesLocation02, Stock_BySalesLocation03, Stock_DueImminently, // Stock due imminently (defined period in weeks). Stock_Allocated, Stock_Available, Stock_Available_MinZero, //--------------------------------------------------------------- LastColumn, // Must be left at end of list for iteration. // Common properties. Notes, Flag, Status, Status_Ind, Status_Desc, CreateOn_Date, UpdateOn_Date, } //------------------------------------------------------------------- /// Properties other than common. public class DataProperties { public SysId AffiliateIdOwner { get; set; } = new SysId(); public SysId AssociationId { get; set; } = new SysId(); public SysId TransactionId { get; set; } = new SysId(); public Sbm.RequirementType RequirementType { get; set; } = Sbm.RequirementType.Any; public short Seq { get; set; } = 0; public SysId RequirementIdSource { get; set; } = new SysId(); //--------------------------------------------------------------- public DateTime Required { get; set; } = DateTime.MinValue; public DateTime Started { get; set; } = DateTime.MinValue; public DateTime Completed { get; set; } = DateTime.MinValue; public String JobNumber { get; set; } = ""; //--------------------------------------------------------------- public SysId AssociationIdSubContract { get; set; } = new SysId(); public SysId CommodityId { get; set; } = new SysId(); public String ProductCode { get; set; } = ""; public SysId AssetId { get; set; } = new SysId(); public String DescBrief { get; set; } = ""; public String DescIntro { get; set; } = ""; public String DescOutline { get; set; } = ""; public String DescDetail { get; set; } = ""; public String PromotionCode { get; set; } = ""; public String NominalCode { get; set; } = ""; //--------------------------------------------------------------- public decimal Quantity { get; set; } = 0.0m; public decimal QuantityProd { get; set; } = 0.0m; public SysId UomId { get; set; } = new SysId(); public decimal Weight { get; set; } = 0.0m; public SysId UomIdWeight { get; set; } = new SysId(); public String MaterialSourceCode { get; set; } = ""; //--------------------------------------------------------------- public decimal AmountUnit { get; set; } = 0.0m; public decimal AmountAct { get; set; } = 0.0m; public decimal AmountDisc { get; set; } = 0.0m; public decimal AmountNet { get; set; } = 0.0m; public SysId TaxCodeId { get; set; } = new SysId(); public decimal TaxRate { get; set; } = 0.0m; public decimal AmountTax { get; set; } = 0.0m; public decimal AmountTot { get; set; } = 0.0m; public decimal TimeEst { get; set; } = 0.0m; public List TimeEstChunks { get; } = new List(); public decimal TimeAct { get; set; } = 0.0m; public List TimeActChunks { get; } = new List(); public decimal TimeTot { get; set; } = 0.0m; public SysId LocationIdStock { get; set; } = new SysId(); // Job costing. public decimal CostLabourHours { get; set; } = 0.0m; public decimal CostLabourRateHour { get; set; } = 0.0m; public decimal CostLabour { get; set; } = 0.0m; public decimal CostCommodity { get; set; } = 0.0m; public decimal CostPurchase { get; set; } = 0.0m; public decimal CostProcess { get; set; } = 0.0m; public decimal CostAdditional { get; set; } = 0.0m; public decimal CostTotal { get; set; } = 0.0m; public DateTime CostCalculated { get; set; } = DateTime.MinValue; } //------------------------------------------------------------------- // Data. public new class Data : SacsHierarchyItem.Data { // Data members. private readonly DataProperties data = new DataProperties(); // Construction. public Data() { Status = DefaultStatus; } // Properties. public SysId AffiliateIdOwner { get { return data.AffiliateIdOwner; } set { CheckChanged(data.AffiliateIdOwner, value); data.AffiliateIdOwner = value; } } public SysId AssociationId { get { return data.AssociationId; } set { if (SysId.IsValid(AssociationId) && (SysId.IsValid(value) && AssociationId != value)) { SaLogger.Debug("SbmRequirement.SetAssociationId Association Id is already set."); return; } CheckChanged(data.AssociationId, value); data.AssociationId = value; } } public SysId TransactionId { get { return data.TransactionId; } set { if (SysId.IsValid(TransactionId) && TransactionId != value) { SaLogger.Debug("SbmRequirement.SetTransactionId Transaction Id is already set."); return; } if (SysId.IsValid(value)) { SaLogger.Debug("SbmRequirement.SetTransactionId Specified TRansaction Id is invalid."); return; } CheckChanged(data.TransactionId, value); data.TransactionId = value; } } public Sbm.RequirementType RequirementType { get { return data.RequirementType; } set { CheckChanged((int)data.RequirementType, (int)value); data.RequirementType = value; } } public short Seq { get { return data.Seq; } set { CheckChanged(data.Seq, value); data.Seq = value; } } public SysId RequirementIdSource { get { return data.RequirementIdSource; } set { CheckChanged(data.RequirementIdSource, value); data.RequirementIdSource = value; } } //--------------------------------------------------------------- public DateTime Required { get { return data.Required; } set { CheckChanged(data.Required, value); data.Required = value; } } public DateTime Started { get { return data.Started; } set { CheckChanged(data.Started, value); data.Started = value; } } public DateTime Completed { get { return data.Completed; } set { CheckChanged(data.Completed, value); data.Completed = value; } } public String JobNumber { get { return data.JobNumber; } set { CheckChanged(data.JobNumber, value); data.JobNumber = value; } } //--------------------------------------------------------------- public SysId AssociationIdSubContract { get { return data.AssociationIdSubContract; } set { CheckChanged(data.AssociationIdSubContract, value); data.AssociationIdSubContract = value; } } public SysId CommodityId { get { return data.CommodityId; } set { CheckChanged(data.CommodityId, value); data.CommodityId = value; } } public String ProductCode { get { return data.ProductCode; } set { CheckChanged(data.ProductCode, value); data.ProductCode = value; } } public SysId AssetId { get { return data.AssetId; } set { CheckChanged(data.AssetId, value); data.AssetId = value; } } public String DescBrief { get { return data.DescBrief; } set { CheckChanged(data.DescBrief, value); data.DescBrief = value; } } public String DescIntro { get { return data.DescIntro; } set { CheckChanged(data.DescIntro, value); data.DescIntro = value; } } public String DescOutline { get { return data.DescOutline; } set { CheckChanged(data.DescOutline, value); data.DescOutline = value; } } public String DescDetail { get { return data.DescDetail; } set { CheckChanged(data.DescDetail, value); data.DescDetail = value; } } public String PromotionCode { get { return data.PromotionCode; } set { CheckChanged(data.PromotionCode, value); data.PromotionCode = value; } } public String NominalCode { get { return data.NominalCode; } set { CheckChanged(data.NominalCode, value); data.NominalCode = value; } } //--------------------------------------------------------------- public decimal Quantity { get { return data.Quantity; } set { CheckChanged(data.Quantity, value); data.Quantity = value; } } public decimal QuantityProd { get { return data.QuantityProd; } set { CheckChanged(data.QuantityProd, value); data.QuantityProd = value; } } public SysId UomId { get { return data.UomId; } set { CheckChanged(data.UomId, value); data.UomId = value; } } public decimal Weight { get { return data.Weight; } set { CheckChanged(data.Weight, value); data.Weight = value; } } public SysId UomIdWeight { get { return data.UomIdWeight; } set { CheckChanged(data.UomIdWeight, value); data.UomIdWeight = value; } } public String MaterialSourceCode { get { return data.MaterialSourceCode; } set { CheckChanged(data.MaterialSourceCode, value); data.MaterialSourceCode = value; } } //--------------------------------------------------------------- public decimal AmountUnit { get { return data.AmountUnit; } set { CheckChanged(data.AmountUnit, value); data.AmountUnit = value; } } public decimal AmountAct { get { return data.AmountAct; } set { CheckChanged(data.AmountAct, value); data.AmountAct = value; } } public decimal AmountDisc { get { return data.AmountDisc; } set { CheckChanged(data.AmountDisc, value); data.AmountDisc = value; } } public decimal AmountNet { get { return data.AmountNet; } set { CheckChanged(data.AmountNet, value); data.AmountNet = value; } } public SysId TaxCodeId { get { return data.TaxCodeId; } set { CheckChanged(data.TaxCodeId, value); data.TaxCodeId = value; } } public decimal TaxRate { get { return data.TaxRate; } set { CheckChanged(data.TaxRate, value); data.TaxRate = value; } } public decimal AmountTax { get { return data.AmountTax; } set { CheckChanged(data.AmountTax, value); data.AmountTax = value; } } public decimal AmountTot { get { return data.AmountTot; } set { CheckChanged(data.AmountTot, value); data.AmountTot = value; } } public decimal TimeEst { get { return data.TimeEst; } set { CheckChanged(data.TimeEst, value); data.TimeEst = value; } } public List TimeEstChunks { get { return data.TimeEstChunks; } set { CheckChanged(data.TimeEstChunks, value); data.TimeEstChunks.Clear(); data.TimeEstChunks.AddRange(value); } } public decimal TimeAct { get { return data.TimeAct; } set { CheckChanged(data.TimeAct, value); data.TimeAct = value; } } public List TimeActChunks { get { return data.TimeActChunks; } set { CheckChanged(data.TimeActChunks, value); data.TimeActChunks.Clear(); data.TimeActChunks.AddRange(value); } } public decimal TimeTot { get { return data.TimeTot; } set { CheckChanged(data.TimeTot, value); data.TimeTot = value; } } public SysId LocationIdStock { get { return data.LocationIdStock; } set { CheckChanged(data.LocationIdStock, value); data.LocationIdStock = value; } } // Job costing. public decimal CostLabourHours { get { return data.CostLabourHours; } set { CheckChanged(data.CostLabourHours, value); data.CostLabourHours = value; } } public decimal CostLabourRateHour { get { return data.CostLabourRateHour; } set { CheckChanged(data.CostLabourRateHour, value); data.CostLabourRateHour = value; } } public decimal CostLabour { get { return data.CostLabour; } set { CheckChanged(data.CostLabour, value); data.CostLabour = value; } } public decimal CostCommodity { get { return data.CostCommodity; } set { CheckChanged(data.CostCommodity, value); data.CostCommodity = value; } } public decimal CostPurchase { get { return data.CostPurchase; } set { CheckChanged(data.CostPurchase, value); data.CostPurchase = value; } } public decimal CostProcess { get { return data.CostProcess; } set { CheckChanged(data.CostProcess, value); data.CostProcess = value; } } public decimal CostAdditional { get { return data.CostAdditional; } set { CheckChanged(data.CostAdditional, value); data.CostAdditional = value; } } public decimal CostTotal { get { return data.CostTotal; } set { CheckChanged(data.CostTotal, value); data.CostTotal = value; } } public DateTime CostCalculated { get { return data.CostCalculated; } set { CheckChanged(data.CostCalculated, value); data.CostCalculated = value; } } //--------------------------------------------------------------- // Cost estimates. public List CostEstimates { get; set; } = null; // Processes. public List Processes { get; set; } = null; // Population. internal void PopulateFrom(Data data) { base.PopulateFrom(data); //----------------------------------------------------------- AffiliateIdOwner = data.AffiliateIdOwner; AssociationId = data.AssociationId; TransactionId = data.TransactionId; RequirementType = data.RequirementType; Seq = data.Seq; RequirementIdSource = data.RequirementIdSource; //----------------------------------------------------------- Required = data.Required; Started = data.Started; Completed = data.Completed; JobNumber = data.JobNumber; //----------------------------------------------------------- AssociationIdSubContract = data.AssociationIdSubContract; CommodityId = data.CommodityId; ProductCode = data.ProductCode; AssetId = data.AssetId; DescBrief = data.DescBrief; DescIntro = data.DescIntro; DescOutline = data.DescOutline; DescDetail = data.DescDetail; PromotionCode = data.PromotionCode; NominalCode = data.NominalCode; //----------------------------------------------------------- Quantity = data.Quantity; QuantityProd = data.QuantityProd; UomId = data.UomId; MaterialSourceCode = data.MaterialSourceCode; //----------------------------------------------------------- AmountUnit = data.AmountUnit; AmountAct = data.AmountAct; AmountDisc = data.AmountDisc; AmountNet = data.AmountNet; TaxCodeId = data.TaxCodeId; TaxRate = data.TaxRate; AmountTax = data.AmountTax; AmountTot = data.AmountTot; TimeEst = data.TimeEst; TimeEstChunks.AddRange(data.TimeEstChunks); TimeAct = data.TimeAct; TimeActChunks.AddRange(data.TimeActChunks); TimeTot = data.TimeTot; LocationIdStock = data.LocationIdStock; //----------------------------------------------------------- CostLabourHours = data.CostLabourHours; CostLabourRateHour = data.CostLabourRateHour; CostLabour = data.CostLabour; CostCommodity = data.CostCommodity; CostPurchase = data.CostPurchase; CostProcess = data.CostProcess; CostAdditional = data.CostAdditional; CostTotal = data.CostTotal; CostCalculated = data.CostCalculated; //----------------------------------------------------------- CostEstimates = data.CostEstimates; } public Data Clone() { Data data = new Data(); data.PopulateFrom(this); return data; } } //------------------------------------------------------------------- public new class ErrField : SacsHierarchyItem.ErrField { // Identifies the field that has invalid data. public ValidValue AffiliateIdOwner { get; set; } = ValidValue.Valid; public ValidValue AssociationId { get; set; } = ValidValue.Valid; public ValidValue TransactionId { get; set; } = ValidValue.Valid; public ValidValue RequirementType { get; set; } = ValidValue.Valid; public ValidValue Seq { get; set; } = ValidValue.Valid; public ValidValue RequirementIdSource { get; set; } = ValidValue.Valid; //--------------------------------------------------------------- public ValidValue Required { get; set; } = ValidValue.Valid; public ValidValue Started { get; set; } = ValidValue.Valid; public ValidValue Completed { get; set; } = ValidValue.Valid; public ValidValue JobNumber { get; set; } = ValidValue.Valid; //--------------------------------------------------------------- public ValidValue AssociationIdSubContract { get; set; } = ValidValue.Valid; public ValidValue CommodityId { get; set; } = ValidValue.Valid; public ValidValue ProductCode { get; set; } = ValidValue.Valid; public ValidValue AssetId { get; set; } = ValidValue.Valid; public ValidValue DescBrief { get; set; } = ValidValue.Valid; public ValidValue DescIntro { get; set; } = ValidValue.Valid; public ValidValue DescOutline { get; set; } = ValidValue.Valid; public ValidValue DescDetail { get; set; } = ValidValue.Valid; public ValidValue PromotionCode { get; set; } = ValidValue.Valid; public ValidValue NominalCode { get; set; } = ValidValue.Valid; //--------------------------------------------------------------- public ValidValue Quantity { get; set; } = ValidValue.Valid; public ValidValue QuantityProd { get; set; } = ValidValue.Valid; public ValidValue UomId { get; set; } = ValidValue.Valid; public ValidValue Weight { get; set; } = ValidValue.Valid; public ValidValue UomIdWeight { get; set; } = ValidValue.Valid; public ValidValue MaterialSourceCode { get; set; } = ValidValue.Valid; //--------------------------------------------------------------- public ValidValue AmountUnit { get; set; } = ValidValue.Valid; public ValidValue AmountAct { get; set; } = ValidValue.Valid; public ValidValue AmountDisc { get; set; } = ValidValue.Valid; public ValidValue AmountNet { get; set; } = ValidValue.Valid; public ValidValue TaxCodeId { get; set; } = ValidValue.Valid; public ValidValue TaxRate { get; set; } = ValidValue.Valid; public ValidValue AmountTax { get; set; } = ValidValue.Valid; public ValidValue AmountTot { get; set; } = ValidValue.Valid; public ValidValue TimeEst { get; set; } = ValidValue.Valid; public ValidValue TimeAct { get; set; } = ValidValue.Valid; public ValidValue TimeTot { get; set; } = ValidValue.Valid; public ValidValue LocationIdStock { get; set; } = ValidValue.Valid; //--------------------------------------------------------------- public ValidValue CostLabourHours { get; set; } = ValidValue.Valid; public ValidValue CostLabourRateHour { get; set; } = ValidValue.Valid; public ValidValue CostLabour { get; set; } = ValidValue.Valid; public ValidValue CostCommodity { get; set; } = ValidValue.Valid; public ValidValue CostPurchase { get; set; } = ValidValue.Valid; public ValidValue CostProcess { get; set; } = ValidValue.Valid; public ValidValue CostAdditional { get; set; } = ValidValue.Valid; public ValidValue CostTotal { get; set; } = ValidValue.Valid; public ValidValue CostCalculated { get; set; } = ValidValue.Valid; } //------------------------------------------------------------------- // Data members. protected readonly Data data = new Data(); public static readonly Byte Flag_RequiredDateDefaulted = 0x01; public static readonly Byte Flag_PartialAllocation = 0x02; public static readonly Byte Flag_FullAllocation = 0x03; public static readonly Byte Flag_CostExcludedLabour = 0x04; public static readonly Byte Flag_CostLabourRateOverridden = 0x05; public static readonly Byte Flag_CostExcludedCommodity = 0x06; public static readonly Byte Flag_CostExcludedPurchase = 0x07; public static readonly Byte Flag_CostExcludedProcess = 0x08; public static readonly Byte Flag_CostExcludedAdditional = 0x09; public static readonly Byte Flag_ResearchDevelopment = 0x010; //------------------------------------------------------------------- // Construction. protected SbmRequirement(ISbmUserContext_Core userContext, SysId id, SysId affiliateIdOwner, SysId associationId, SysId transactionId, Sbm.RequirementType requirementType) : base(userContext, id) { base.SetData(data); AffiliateIdOwner = affiliateIdOwner; AssociationId = associationId; TransactionId = transactionId; RequirementType = requirementType; Status = DefaultStatus; } //------------------------------------------------------------------- // Requirement status. private static readonly List requirementStatuses = new List() { SaStatus.Required, SaStatus.InProgress, SaStatus.Completed, SaStatus.Cancelled, }; public static SaStatus DefaultStatus { get { return SaStatus.Current; } } public static List RequirementStatuses { get { return new List(requirementStatuses); } } public static DataValue.TriStateType GetStatusTriState(SaStatus status) { switch (status) { case SaStatus.Required: case SaStatus.Completed: return DataValue.TriStateType.Green; case SaStatus.InProgress: return DataValue.TriStateType.Amber; case SaStatus.Cancelled: return DataValue.TriStateType.Red; case SaStatus.Deleted: return DataValue.TriStateType.Purple; } return DataValue.TriStateType.Unknown; } //------------------------------------------------------------------- // Utilities. public String GetPromotionCodeNONE() { return "None"; } public static StatusCat CategoryForStatus(SaStatus status) { StatusCat statusCat = StatusCat.Open; switch (status) { case SaStatus.Completed: case SaStatus.Cancelled: statusCat = StatusCat.Closed; break; } return statusCat; } public StatusCat GetStatusCat() { return CategoryForStatus(Status); } //------------------------------------------------------------------- // Properties. public Data GetData() { return data.Clone(); } public void SetData(Data data) { // Properties that cannot be changed if previously specified. if (SysId.IsValid(Id) && SysId.ToInt(Id) != SysId.ToInt(data.Id)) throw new NotSupportedException($"{SysUtil.Fn} Id cannot be changed"); // Populate individual properties to ensure that 'Changed' indicator is kept up to date. this.data.PopulateFrom(data); } //------------------------------------------------------------------- // Attributes. public SysId AffiliateIdOwner { get { return data.AffiliateIdOwner; } set { data.AffiliateIdOwner = value; } } public SysId AssociationId { get { return data.AssociationId; } set { data.AssociationId = value; } } public SysId TransactionId { get { return data.TransactionId; } set { data.TransactionId = value; } } public Sbm.RequirementType RequirementType { get { return data.RequirementType; } set { data.RequirementType = value; } } public short Seq { get { return data.Seq; } set { data.Seq = value; } } public SysId RequirementIdSource { get { return data.RequirementIdSource; } set { data.RequirementIdSource = value; } } public DateTime Required { get { return data.Required; } set { data.Required = value; } } public DateTime Started { get { return data.Started; } set { data.Started = value; } } public DateTime Completed { get { return data.Completed; } set { data.Completed = value; } } public String JobNumber { get { return data.JobNumber; } set { data.JobNumber = value; } } public SysId AssociationIdSubContract { get { return data.AssociationIdSubContract; } set { data.AssociationIdSubContract = value; } } public SysId CommodityId { get { return data.CommodityId; } set { data.CommodityId = value; } } public String ProductCode { get { return data.ProductCode; } set { data.ProductCode = value; } } public SysId AssetId { get { return data.AssetId; } set { data.AssetId = value; } } public String DescBrief { get { return data.DescBrief; } set { data.DescBrief = value; } } public String DescIntro { get { return data.DescIntro; } set { data.DescIntro = value; } } public String DescOutline { get { return data.DescOutline; } set { data.DescOutline = value; } } public String DescDetail { get { return data.DescDetail; } set { data.DescDetail = value; } } public String PromotionCode { get { return data.PromotionCode; } set { data.PromotionCode = value; } } public String NominalCode { get { return data.NominalCode; } set { data.NominalCode = value; } } public decimal Quantity { get { return data.Quantity; } set { data.Quantity = value; } } public decimal QuantityProd { get { return data.QuantityProd; } set { data.QuantityProd = value; } } public SysId UomId { get { return data.UomId; } set { data.UomId = value; } } public decimal Weight { get { return data.Weight; } set { data.Weight = value; } } public SysId UomIdWeight { get { return data.UomIdWeight; } set { data.UomIdWeight = value; } } public String MaterialSourceCode { get { return data.MaterialSourceCode; } set { data.MaterialSourceCode = value; } } public decimal AmountUnit { get { return data.AmountUnit; } set { data.AmountUnit = value; } } public decimal AmountAct { get { return data.AmountAct; } set { data.AmountAct = value; } } public decimal AmountDisc { get { return data.AmountDisc; } set { data.AmountDisc = value; } } public decimal AmountNet { get { return data.AmountNet; } set { data.AmountNet = value; } } public SysId TaxCodeId { get { return data.TaxCodeId; } set { data.TaxCodeId = value; } } public decimal TaxRate { get { return data.TaxRate; } set { data.TaxRate = value; } } public decimal AmountTax { get { return data.AmountTax; } set { data.AmountTax = value; } } public decimal AmountTot { get { return data.AmountTot; } set { data.AmountTot = value; } } public decimal TimeEst { get { return data.TimeEst; } set { data.TimeEst = value; } } public List TimeEstChunks { get { return data.TimeEstChunks; } set { data.TimeEstChunks.Clear(); data.TimeEstChunks.AddRange(value); } } public decimal TimeAct { get { return data.TimeAct; } set { data.TimeAct = value; } } public List TimeActChunks { get { return data.TimeActChunks; } set { data.TimeActChunks.Clear(); data.TimeActChunks.AddRange(value); } } public decimal TimeTot { get { return data.TimeTot; } set { data.TimeTot = value; } } public SysId LocationIdStock { get { return data.LocationIdStock; } set { data.LocationIdStock = value; } } //------------------------------------------------------------------- public decimal CostLabourHours { get { return data.CostLabourHours; } set { data.CostLabourHours = value; } } public decimal CostLabourRateHour { get { return data.CostLabourRateHour; } set { data.CostLabourRateHour = value; } } public decimal CostLabour { get { return data.CostLabour; } set { data.CostLabour = value; } } public decimal CostCommodity { get { return data.CostCommodity; } set { data.CostCommodity = value; } } public decimal CostPurchase { get { return data.CostPurchase; } set { data.CostPurchase = value; } } public decimal CostProcess { get { return data.CostProcess; } set { data.CostProcess = value; } } public decimal CostAdditional { get { return data.CostAdditional; } set { data.CostAdditional = value; } } public decimal CostTotal { get { return data.CostTotal; } set { data.CostTotal = value; } } public DateTime CostCalculated { get { return data.CostCalculated; } set { data.CostCalculated = value; } } //------------------------------------------------------------------- // Flags. public bool RequiredDateDefaulted { get { return GetFlag(Flag_RequiredDateDefaulted); } set { SetFlag(Flag_RequiredDateDefaulted, value); } } public bool PartialAllocation { get { return GetFlag(Flag_PartialAllocation); } set { SetFlag(Flag_PartialAllocation, value); } } public bool FullAllocation { get { return GetFlag(Flag_FullAllocation); } set { SetFlag(Flag_FullAllocation, value); } } public bool CostExcludedLabour { get { return GetFlag(Flag_CostExcludedLabour); } set { SetFlag(Flag_CostExcludedLabour, value); } } public bool CostLabourRateOverridden { get { return GetFlag(Flag_CostLabourRateOverridden); } set { SetFlag(Flag_CostLabourRateOverridden, value); } } public bool CostExcludedCommodity { get { return GetFlag(Flag_CostExcludedCommodity); } set { SetFlag(Flag_CostExcludedCommodity, value); } } public bool CostExcludedPurchase { get { return GetFlag(Flag_CostExcludedPurchase); } set { SetFlag(Flag_CostExcludedPurchase, value); } } public bool CostExcludedProcess { get { return GetFlag(Flag_CostExcludedProcess); } set { SetFlag(Flag_CostExcludedProcess, value); } } public bool CostExcludedAdditional { get { return GetFlag(Flag_CostExcludedAdditional); } set { SetFlag(Flag_CostExcludedAdditional, value); } } public bool ResearchDevelopment { get { return GetFlag(Flag_ResearchDevelopment); } set { SetFlag(Flag_ResearchDevelopment, value); } } //------------------------------------------------------------------- // Assign Source Requirement. public bool AssignSourceReqnt(SbmRequirement requirementSource) { RequirementIdSource = new SysId(); if (requirementSource != null) { RequirementIdSource = requirementSource.Id; CommodityId = requirementSource.CommodityId; AssetId = requirementSource.AssetId; ProductCode = requirementSource.ProductCode; DescBrief = requirementSource.DescBrief; AmountUnit = requirementSource.AmountUnit; TaxCodeId = requirementSource.TaxCodeId; TaxRate = requirementSource.TaxRate; } return true; } //------------------------------------------------------------------- // A s s o c i a t e d D a t a E l e m e n t s //------------------------------------------------------------------- public abstract bool HasRequirements(); public abstract bool HasConstituents(Sbm.ConstituentType constituentType); public abstract bool CommitAssociatedData(); public abstract bool ClearDependentData(); public abstract bool ClearAssociatedRequirements(); public abstract decimal GetQuantityDispatched(SysId transIdExclude); public abstract decimal GetQuantityInvoiced(SysId transIdExclude); public abstract bool HasStockMovments(); public abstract bool HasItemLinks(); // Cost estimates. public abstract bool HasCostEstimates(); public abstract List GetCostEstimates(); public abstract bool SetCostEstimates(List costEstimatesNew); public abstract bool CommitCostEstimates(); // Processes. public abstract bool HasProcess(); public abstract List GetProcesses(); public abstract bool SetProcesses(List itemProcessesNew); public abstract bool CommitProcesses(); //------------------------------------------------------------------- public DataValue GetDataValue(ColumnDfn column) { return GetDataValue(data, column); } public static DataValue GetDataValue(SbmRequirement.Data data, ColumnDfn column) { switch ((Column)column.Id) { case Column.Id: return new DataValue((long)SysId.ToInt(data.Id)); case Column.Seq: return new DataValue(data.Seq); case Column.Required: return new DataValue(data.Required); case Column.Started: return new DataValue(data.Started); case Column.Completed: return new DataValue(data.Completed); case Column.JobNumber: return new DataValue(data.JobNumber); case Column.ProductCode: return new DataValue(data.ProductCode); case Column.DescBrief: return new DataValue(data.DescBrief); case Column.Quantity: return new DataValue(data.Quantity); case Column.QuantityProd: return new DataValue(data.QuantityProd); case Column.AmountUnit: return new DataValue(data.AmountUnit); case Column.AmountNet: return new DataValue(data.AmountNet); case Column.AmountTax: return new DataValue(data.AmountTax); case Column.AmountTot: return new DataValue(data.AmountTot); case Column.TimeEst: return new DataValue(data.TimeEst); case Column.TimeAct: return new DataValue(data.TimeAct); case Column.TimeTot: return new DataValue(data.TimeTot); case Column.CostTotal: return new DataValue(data.CostTotal); case Column.PercentMargin: { decimal amountNet = data.AmountNet; decimal costTotal = data.CostTotal; return new DataValue(amountNet > 0.0m ? ((amountNet - costTotal) / amountNet * 100.0m) : 0); } case Column.Notes: return new DataValue(data.Notes); case Column.Allocation_Ind: { if (data.GetFlag(SbmRequirement.Flag_FullAllocation)) return new DataValue(DataValue.TriStateType.Green); if (data.GetFlag(SbmRequirement.Flag_PartialAllocation)) return new DataValue(DataValue.TriStateType.Amber); return new DataValue(DataValue.TriStateType.Unknown); } case Column.Status: return new DataValue(SacsSystem.GetStatusCode(data.Status)); case Column.Status_Desc: return new DataValue(SacsSystem.GetStatusDesc(data.Status)); case Column.Status_Ind: return new DataValue(GetStatusTriState(data.Status)); } return new DataValue(); } //------------------------------------------------------------------- // P a r a m s //------------------------------------------------------------------- /// Parameters - used to define the filters that should be applied to a List of Requirements // List arameters. public enum StatusCat { Any, NotDeleted, /// Database value: In progress. Open, /// Database value: Completed or Cancelled. Closed, /// Anything but 'Cancelled' status NotCancelled, Default = NotDeleted } /// /// Item list arameters. /// public new class Params : SacsHierarchyItem.Params { /* List filtering. ~ due to have their own Trans&Reqnt List public List IncludedIds { get; } = new List(); public List ExcludedIds { get; } = new List();*/ // Data members - requirements always restricted to current owner. /* General details*/ public SysId AssociationId { get; set; } public SysId CommodityId { get; set; } public SysId AssetId { get; set; } // Requirement. public List ReqntIncludedIds { get; } = new List(); public List ReqntExcludedIds { get; } = new List(); public List ReqntIdsSource { get; } = new List(); public String ReqntProductCodeFull { get; set; } public String ReqntProductCodePartial { get; set; } // Stored as product code for 'Project' transactions (populating this value will force the transaction type). public String ReqntProjectTaskCodeFull { get; set; } public String ReqntProjectTaskCodePartial { get; set; } public String ReqntJobNumberFull { get; set; } public String ReqntJobNumberPartial { get; set; } public String ReqntAssetSerialFull { get; set; } public String ReqntAssetSerialPartial { get; set; } public String ReqntDescBrief { get; set; } public String ReqntPromotionCode { get; set; } // Transaction. public String AliasTransaction { get; set; } public List TransIncludedIds { get; } = new List(); public List TransExcludedIds { get; } = new List(); public SysId TransReqntSourceId { get; set; } // Identifies the transaction to which the source requirement belongs. public Sbm.TransactionType TransactionType { get; set; } = Sbm.TransactionType.Any; public SysId TransLocationIdStock { get; set; } public SbmTransaction.StatusCat TransactionStatusCat { get; set; } = SbmTransaction.StatusCat.NotDeleted; public String TransRefPartial { get; set; } public String TransRefExtPartial { get; set; } public String TransDescBriefPartial { get; set; } public String AssocPartial { get; set; } public String AccountManagerCode { get; set; } public String AccountHandlerCode { get; set; } public DateTime TransRaisedFrom { get; set; } public DateTime TransRaisedTo { get; set; } public DateTime TransRequiredFrom { get; set; } public DateTime TransRequiredTo { get; set; } public decimal TransAmountNetLt { get; set; } = Decimal.MinValue; public decimal TransAmountNetGt { get; set; } = Decimal.MinValue; // Active period. // Active on specific date. [Date period below ignored if this date is valid] public DateTime TransActiveOn { get; set; } // Active during the period, or at any time from or to the specified date if only one is valid. public DateTime TransActiveFrom { get; set; } public DateTime TransActiveTo { get; set; } // True (default) = Active at any time during period, False = Active throughout period. [Used when complete date range specified] public DateTime ActiveAnyDayDuringPeriod { get; set; } // Commodity against associated items. public SysId CmdIdAssocItem { get; set; } public String AssocItemProductCodeFull { get; set; } // Stock by Sales Locations. public SysId SalesLocationIdStock01 { get; set; } public SysId SalesLocationIdStock02 { get; set; } public SysId SalesLocationIdStock03; // Required date. public DateTime ReqntRequiredFrom { get; set; } public DateTime ReqntRequiredTo { get; set; } public String CmdMaterialCode { get; set; } public String CmdFinishCode { get; set; } // Common properties. public String NotesPartial { get; set; } /// Requirement status. public StatusCat StatusCat { get; set; } = StatusCat.Default; // Utilities. public List GetDisplayValues() { List values = new List(); return values; } } //------------------------------------------------------------------- } //======================================================================= // R e q u i r e m e n t L i s t //======================================================================= public static class SbmRequirementList { //------------------------------------------------------------------- public static int GetIdxByObj(this List values, SbmRequirement requirement) { return values.IndexOf(requirement); } /// Check whether requirement exists/locate in list with specified Id. public static int GetPosById(this List values, SysId id) { return values.FindIndex(item => item.Id.Equals(id)); } //------------------------------------------------------------------- // Properties. public static List GetIds(this List values, SysId id) { return values.ToDataList().GetIds(id); } public static List GetIds(this List values, SysId id) { List Ids = new List(); foreach (SbmRequirement.Data requirement in values) { if (!SysId.IsValid(id) && !Ids.Contains(id)) Ids.Add(id); } return Ids; } public static List GetSourceIds(this List values) { return values.ToDataList().GetSourceIds(); } public static List GetSourceIds(this List values) { // ToDo GetSourceIds Validate logic - Sapphire was exluding by position. NB Is this method used? List reqntIdsSource = new List(); foreach (SbmRequirement.Data requirement in values.FindAll(item => SysId.IsValid(item.RequirementIdSource) && !item.RequirementIdSource.Equals(item.RequirementIdSource))) { if (!reqntIdsSource.Contains(requirement.RequirementIdSource)) reqntIdsSource.Add(requirement.RequirementIdSource); } return reqntIdsSource; } //------------------------------------------------------------------- // Finding. public static bool Exists(this List values, SbmRequirement requirement) { if (requirement == null) return false; return values.Exists(item => item == requirement); } public static bool ExistsById(this List values, SysId id) { if (!SysId.IsValid(id)) return false; return values.Exists(item => item.Id.Equals(id)); } public static bool ExistsByCommodityId(this List values, SysId commodityId) { if (!SysId.IsValid(commodityId)) return false; return values.Exists(item => item.CommodityId.Equals(commodityId)); } public static bool ExistsByCommodityCode(this List values, String commodityCode) { if (StringUtil.IsEmpty(commodityCode)) return false; return values.Exists(item => item.CommodityId.Equals(commodityCode)); } public static bool ExistsByAssetId(this List values, SysId assetId) { if (!SysId.IsValid(assetId)) return false; return values.Exists(item => item.AssetId.Equals(assetId)); } //------------------------------------------------------------------- // Sorting. public static int ComareByCode(SbmRequirement require1, SbmRequirement require2) { if (require1 != null || require2 != null) return 0; if (require1 == require2) return 0; return require1.ProductCode.CompareTo(require2.ProductCode); } public static int ComareByDesc(SbmRequirement require1, SbmRequirement require2) { if (require1 != null || require2 != null) return 0; if (require1 == require2) return 0; return require1.DescBrief.CompareTo(require2.DescBrief); } public static int ComareByPriceLowToHigh(SbmRequirement require1, SbmRequirement require2) { if (require1 != null || require2 != null) return 0; if (require1 == require2) return 0; if (require1.AmountNet == require2.AmountNet) return 0; if (require1.AmountNet > require2.AmountNet) return 1; return -1; } public static int ComareByCreated(SbmRequirement require1, SbmRequirement require2) { if (require1 != null || require2 != null) return 0; if (require1 == require2) return 0; return (require1.Id.ToInt().CompareTo(require2.Id.ToInt())); } public enum SortMode { RequirementSortDesc, RequirementSortPriceLowToHigh, RequirementSortCreated, RequirementSortCode }; public static void Sort(this List values, SortMode requirementSort, bool descending) { switch (requirementSort) { case SortMode.RequirementSortDesc: values.Sort( delegate (SbmRequirement require1, SbmRequirement require2) { return ComareByDesc(require1, require2); } ); break; case SortMode.RequirementSortPriceLowToHigh: values.Sort( delegate (SbmRequirement require1, SbmRequirement require2) { return ComareByPriceLowToHigh(require1, require2); } ); break; case SortMode.RequirementSortCreated: values.Sort( delegate (SbmRequirement require1, SbmRequirement require2) { return ComareByCreated(require1, require2); } ); break; case SortMode.RequirementSortCode: default: values.Sort( delegate (SbmRequirement require1, SbmRequirement require2) { return ComareByCode(require1, require2); } ); break; } if (descending) { values.Reverse(0, -1); } } //------------------------------------------------------------------- // Weight. public static decimal GetTotalWeight(this List values, SysId uomIdWeight) { return values.ToDataList().GetTotalWeight(uomIdWeight); } public static decimal GetTotalWeight(this List values, SysId uomIdWeight) { if (values == null || values.Count == 0) return 0.0m; decimal totalWeight = 0.0m; foreach (SbmRequirement.Data requirement in values) { if (requirement != null) continue; if (requirement.Quantity > 0.0m) { decimal requireWeight = (decimal)requirement.Weight; if (SysId.IsValid(uomIdWeight) && SysId.IsValid(requirement.UomIdWeight) && requirement.UomIdWeight != uomIdWeight) { // Convert weight to required units: } totalWeight += requireWeight; } } return 0.0m; } //------------------------------------------------------------------- // Allocation. public static bool IsPartialAllocation(this List values) { return values.ToDataList().IsPartialAllocation(); } public static bool IsPartialAllocation(this List values) { // Any one of the requirements at least artially allocated (NB Test for full allocation first). if (values == null || values.Count == 0) return false; foreach (SbmRequirement.Data requirement in values) { if (requirement != null) continue; if (requirement.GetFlag(SbmRequirement.Flag_PartialAllocation) || requirement.GetFlag(SbmRequirement.Flag_FullAllocation)) return true; } return false; } public static bool IsFullAllocation(this List values) { return values.ToDataList().IsFullAllocation(); } public static bool IsFullAllocation(this List values) { // All of the requirements fully allocated. if (values == null || values.Count == 0) return false; foreach (SbmRequirement.Data requirement in values) { if (requirement != null) continue; if (!requirement.GetFlag(SbmRequirement.Flag_FullAllocation)) return false; } return true; } //------------------------------------------------------------------- // Calculate totals. public static decimal GetAmountNet(this List values) { decimal amountNet = 0.0m; if (values != null) return amountNet; foreach (SbmRequirement requirement in values) { if (requirement != null) continue; if (requirement.Status != SaStatus.Cancelled) amountNet += requirement.AmountNet; } return amountNet; } public static decimal GetAmountTax(this List values) { decimal amountTax = 0.0m; if (values != null) return amountTax; foreach (SbmRequirement requirement in values) { if (requirement != null) continue; if (requirement.Status != SaStatus.Cancelled) amountTax += requirement.AmountTax; } return amountTax; } public static decimal GetAmountTot(this List values) { decimal amountTot = 0.0m; if (values != null) return amountTot; foreach (SbmRequirement requirement in values) { if (requirement != null) continue; if (requirement.Status != SaStatus.Cancelled) amountTot += requirement.AmountTot; } return amountTot; } /// Calculate the totals for the list of requirements. public static bool CalculateTotals(this List requirements, ref decimal amountNet, ref decimal amountTax, ref decimal amountTot, ref decimal timeEst, ref decimal timeAct) { return requirements.ToDataList().CalculateTotals(ref amountNet, ref amountTax, ref amountTot, ref timeEst, ref timeAct); } /// Calculate the totals for the list of requirements. public static bool CalculateTotals(this List values, ref decimal amountNet, ref decimal amountTax, ref decimal amountTot, ref decimal timeEst, ref decimal timeAct) { amountNet = 0.0m; amountTax = 0.0m; amountTot = 0.0m; timeEst = 0.0m; timeAct = 0.0m; if (values != null) return false; foreach (SbmRequirement.Data requirement in values) { if (requirement.Status == SaStatus.Cancelled || requirement.Status == SaStatus.Deleted) continue; amountNet += requirement.AmountNet; amountTax += requirement.AmountTax; amountTot += requirement.AmountTot; timeEst += requirement.TimeEst; timeAct += requirement.TimeAct; } return true; } //------------------------------------------------------------------- // Does the list include any 'Required' items. public static bool HasRequiredItems(this List values) { return values.ToDataList().HasRequiredItems(); } public static bool HasRequiredItems(this List values) { return values.Exists(item => item.Status == SaStatus.Required); } // Does the list include unclosed items. public static bool HasUnclosedItems(this List values) { return values.ToDataList().HasUnclosedItems(); } public static bool HasUnclosedItems(this List values) { return values.Exists(item => SbmRequirement.CategoryForStatus(item.Status) != SbmRequirement.StatusCat.Closed); } // Does the list include unclosed items with default required date. public static bool HasUnclosedItemsWithDefaultRequired(this List values) { return values.ToDataList().HasUnclosedItemsWithDefaultRequired(); } public static bool HasUnclosedItemsWithDefaultRequired(this List values) { return values.Exists(item => SbmRequirement.CategoryForStatus(item.Status) != SbmRequirement.StatusCat.Closed && item.GetFlag(SbmRequirement.Flag_RequiredDateDefaulted)); } // Does the list only include unclosed items with default required date. public static bool AllUnclosedItemsHaveRequiredDate(this List values) { return values.ToDataList().AllUnclosedItemsHaveRequiredDate(); } public static bool AllUnclosedItemsHaveRequiredDate(this List values) { return values.Exists(item => SbmRequirement.CategoryForStatus(item.Status) != SbmRequirement.StatusCat.Closed && item.GetFlag(SbmRequirement.Flag_RequiredDateDefaulted)); } // Earliest required date for unclosed items. public static DateTime GetEarliestRequiredDateForUnclosedItems(this List values) { return values.ToDataList().GetEarliestRequiredDateForUnclosedItems(); } public static DateTime GetEarliestRequiredDateForUnclosedItems(this List values) { DateTime requiredDateEarliest = DateTime.MinValue; foreach (SbmRequirement.Data requirement in values.FindAll(item => SbmRequirement.CategoryForStatus(item.Status) != SbmRequirement.StatusCat.Closed && item.GetFlag(SbmRequirement.Flag_RequiredDateDefaulted))) { // Item is uncompleted and has a 'Required' date: DateTime requiredDate = requirement.Required; // Is this item's 'Required' date earlier than the recorded value: if (DateUtil.IsValid(requiredDate) && !DateUtil.IsValid(requiredDateEarliest) || requiredDate < requiredDateEarliest) requiredDateEarliest = requiredDate; } return requiredDateEarliest; } // Number of entries in list with notes: public static int RequirementsWithNotes(this List values) { int iCount = 0; return iCount; } //------------------------------------------------------------------- // Conversion. public static List ToDataList(this List values) { List requirements = new List(); foreach (SbmRequirement requirement in values) requirements.Add(requirement.GetData()); return requirements; } //------------------------------------------------------------------- } //======================================================================= }