using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.Core; 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 SbmItemLink : SbmHierarchyItem { //------------------------------------------------------------------- // Columns. public enum Column { Hidden, Pos, //Id, //ItemLink. Type, Type_Desc, ItemTypeFrom, ItemIdFrom, ItemTypeTo, ItemIdTo, Seq, Completed, DataContent, // Common properties. Notes, Flag, Status, Status_Desc, Status_Ind, CreateOn_Date, UpdateOn_Date, } //------------------------------------------------------------------- /// Properties other than common. public class DataProperties { public Sbm.ItemLinkType ItemLinkType { get; set; } = Sbm.ItemLinkType.Unknown; public Sbm.ItemType ItemTypeFrom { get; set; } = Sbm.ItemType.Unknown; public SysId ItemIdFrom { get; set; } = new SysId(); public Sbm.ItemType ItemTypeTo { get; set; } = Sbm.ItemType.Unknown; public SysId ItemIdTo { get; set; } = new SysId(); public String SortValue { get; set; } = ""; public short Seq { get; set; } = 0; public DateTime Completed { get; set; } = DateTime.MinValue; public String DataContent { get; set; } = ""; } // Data. public new class Data : SacsHierarchyItem.Data { // Data members. private readonly DataProperties data = new DataProperties(); // Construction. public Data() { Status = DefaultStatus; } public Sbm.ItemLinkType ItemLinkType { get { return data.ItemLinkType; } set { CheckChanged((int)data.ItemLinkType, (int)value); data.ItemLinkType = value; } } public Sbm.ItemType ItemTypeFrom { get { return data.ItemTypeFrom; } set { CheckChanged((int)data.ItemTypeFrom, (int)value); data.ItemTypeFrom = value; } } public SysId ItemIdFrom { get { return data.ItemIdFrom; } set { CheckChanged(data.ItemIdFrom, value); data.ItemIdFrom = value; } } public Sbm.ItemType ItemTypeTo { get { return data.ItemTypeTo; } set { CheckChanged((int)data.ItemTypeTo, (int)value); data.ItemTypeTo = value; } } public SysId ItemIdTo { get { return data.ItemIdTo; } set { CheckChanged(data.ItemIdTo, value); data.ItemIdTo = value; } } public String SortValue { get { return data.SortValue; } set { CheckChanged(data.SortValue, value); data.SortValue = value; } } public short Seq { get { return data.Seq; } set { CheckChanged(data.Seq, value); data.Seq = value; } } public DateTime Completed { get { return data.Completed; } set { CheckChanged(data.Completed, value); data.Completed = value; } } public String DataContent { get { return data.DataContent; } set { CheckChanged(data.DataContent, value); data.DataContent = value; } } internal void PopulateFrom(Data data) { ItemLinkType = data.ItemLinkType; ItemTypeFrom = data.ItemTypeFrom; ItemIdFrom = data.ItemIdFrom; ItemTypeTo = data.ItemTypeTo; ItemIdTo = data.ItemIdTo; SortValue = data.SortValue; Seq = data.Seq; Completed = data.Completed; DataContent = data.DataContent; base.PopulateFrom(data); } 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 ItemLinkType { get; set; } = ValidValue.Valid; public ValidValue ItemTypeFrom { get; set; } = ValidValue.Valid; public ValidValue ItemIdFrom { get; set; } = ValidValue.Valid; public ValidValue ItemTypeTo { get; set; } = ValidValue.Valid; public ValidValue ItemIdTo { get; set; } = ValidValue.Valid; public ValidValue SortValue { get; set; } = ValidValue.Valid; public ValidValue Seq { get; set; } = ValidValue.Valid; public ValidValue Completed { get; set; } = ValidValue.Valid; public ValidValue DataContent { get; set; } = ValidValue.Valid; } //------------------------------------------------------------------- // Data members. private readonly Data data = new Data(); // Delimiter To separate named value pairs. private static readonly String DataDelim_Value = "~#~"; // Delimiter between name and value. private static readonly String DataDelim_Name = "=="; //------------------------------------------------------------------- // Construction. protected SbmItemLink(ISbmUserOrganisationContext userContext, SysId id, Sbm.ItemLinkType itemLinkType, Sbm.ItemType itemTypeFrom, SysId itemIdFrom, Sbm.ItemType itemTypeTo, SysId itemIdTo) : base(userContext, id) { base.SetData(data); ItemLinkType = itemLinkType; ItemTypeFrom = itemTypeFrom; ItemIdFrom = itemIdFrom; ItemTypeTo = itemTypeTo; ItemIdTo = itemIdTo; Status = DefaultStatus; } //------------------------------------------------------------------- // ItemLink status. private static readonly List itemLinkStatuses = new List() { SaStatus.Current, SaStatus.OnHold, //SaStatus.Inactive, //SaStatus.Cancelled, SaStatus.Disabled, }; public static SaStatus DefaultStatus { get { return SaStatus.Current; } } public static List ItemLinkStatuses { get { return new List(itemLinkStatuses); } } public static DataValue.TriStateType GetStatusTriState(SaStatus status) { switch (status) { case SaStatus.Active: case SaStatus.Current: return DataValue.TriStateType.Green; case SaStatus.OnHold: return DataValue.TriStateType.Amber; case SaStatus.Inactive: case SaStatus.Cancelled: case SaStatus.Disabled: return DataValue.TriStateType.Red; case SaStatus.Deleted: return DataValue.TriStateType.Purple; } return DataValue.TriStateType.Unknown; } //------------------------------------------------------------------- // Utilities. //------------------------------------------------------------------- // 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 Sbm.ItemLinkType ItemLinkType { get { return data.ItemLinkType; } set { data.ItemLinkType = value; } } public Sbm.ItemType ItemTypeFrom { get { return data.ItemTypeFrom; } set { data.ItemTypeFrom = value; } } public SysId ItemIdFrom { get { return data.ItemIdFrom; } set { data.ItemIdFrom = value; } } public Sbm.ItemType ItemTypeTo { get { return data.ItemTypeTo; } set { data.ItemTypeTo = value; } } public SysId ItemIdTo { get { return data.ItemIdTo; } set { data.ItemIdTo = value; } } public String SortValue { get { return data.SortValue; } set { data.SortValue = value; } } public short Seq { get { return data.Seq; } set { data.Seq = value; } } public DateTime Completed { get { return data.Completed; } set { data.Completed = value; } } public String DataContent { get { return data.DataContent; } set { data.DataContent = value; } } //------------------------------------------------------------------- // Retrieve data value by name. public String GetDataValueByName(String name) { return GetDataValueByName(DataContent, name); } public static String GetDataValueByName(String dataContent, String name) { if (StringUtil.IsEmpty(dataContent) || StringUtil.IsEmpty(name)) return ""; // Extract data values. foreach (String dataValue in dataContent.Split(new String[] { DataDelim_Value }, StringSplitOptions.RemoveEmptyEntries)) { // Match to name and return value if found. String[] nameValue = dataValue.Split(new String[] { DataDelim_Name }, StringSplitOptions.RemoveEmptyEntries); if (nameValue.Length == 2 && nameValue[0].EqualsCI(name)) return nameValue[1]; } return ""; } //------------------------------------------------------------------- // Retrieve data value by name. public void SetDataValueByName(String name, String value) { if (StringUtil.IsEmpty(name)) return; // Extract data values. List dataValues = new List(DataContent.Split(new String[] { DataDelim_Value }, StringSplitOptions.RemoveEmptyEntries)); // Attempt to locate existing entry for this name. bool valueFound = false; for (int dataValueIdx = 0; !valueFound && dataValueIdx < dataValues.Count; dataValueIdx++) { String dataValue = dataValues[dataValueIdx]; String[] nameValue = dataValue.Split(new String[] { DataDelim_Name }, StringSplitOptions.RemoveEmptyEntries); if (nameValue.Length == 2 && nameValue[0].EqualsCI(name)) { // Entry matching name found - replace value and return. dataValues[dataValueIdx] = name + DataDelim_Name + value; valueFound = true; } } if (!valueFound) { // Entry not found in list - add it. dataValues.Add(name + DataDelim_Name + value); } DataContent = String.Join(DataDelim_Value, dataValues); } //------------------------------------------------------------------- // Comparison. public int Compare(SbmItemLink itemLink) { if (itemLink.ItemLinkType == ItemLinkType && itemLink.ItemTypeFrom == ItemTypeFrom && itemLink.ItemIdFrom == ItemIdFrom && itemLink.ItemTypeTo == ItemTypeTo && itemLink.ItemIdTo == ItemIdTo) { return 0; } return -1; } public int CompareBySortValue(SbmItemLink itemLink) { return SortValue.CompareTo(itemLink.SortValue); } // Matching. public bool MatchesLink(Sbm.ItemLinkType itemLinkType, Sbm.ItemType itemTypeFrom, SysId itemIdFrom, Sbm.ItemType itemTypeTo, SysId itemIdTo) { if (ItemLinkType != itemLinkType) return false; if (ItemTypeFrom != itemTypeFrom) return false; if (ItemIdFrom != itemIdFrom) return false; if (ItemTypeTo != itemTypeTo) return false; if (ItemIdTo != itemIdTo) return false; return true; } public bool MatchesFromItem(Sbm.ItemType itemTypeFrom, SysId itemIdFrom, Sbm.ItemLinkType itemLinkType) { if ((int)itemLinkType < 1 && ItemLinkType != itemLinkType) return false; if (ItemTypeFrom != itemTypeFrom) return false; if (ItemIdFrom != itemIdFrom) return false; return true; } public bool MatchesToItem(Sbm.ItemType itemTypeTo, SysId itemIdTo, Sbm.ItemLinkType itemLinkType) { if ((int)itemLinkType < 1 && ItemLinkType != itemLinkType) return false; if (ItemTypeTo != itemTypeTo) return false; if (ItemIdTo != itemIdTo) return false; 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 virtual bool HasItems() { return true; } public virtual bool HasMovements() { return true; } public virtual bool HasActionedMovements() { return true; } //------------------------------------------------------------------- // P a r a m s //------------------------------------------------------------------- /// Parameters - used to define the filters that should be applied to a List of Item Links // List parameters. public enum StatusCat { Any, NotDeleted, DeletedOnly } /// /// Item list parameters. /// public new class Params : SacsHierarchyItem.Params { // List filtering. public List IdsIncluded { get; } = new List(); public List IdsExcluded { get; } = new List(); // ItemLink. public Sbm.ItemLinkType ItemLinkType { get; set; } public Sbm.ItemType ItemTypeFrom { get; set; } public SysId ItemIdFrom { get; set; } public Sbm.ItemType ItemTypeTo { get; set; } public SysId ItemIdTo { get; set; } public short Seq { get; set; } public DateTime Completed { get; set; } public String DataContent { get; set; } public StatusCat StatusCat { get; set; } = StatusCat.NotDeleted; } //------------------------------------------------------------------- } //======================================================================= // I t e m L i n k D a t a L i s t //======================================================================= public static class SbmItemLinkList { //------------------------------------------------------------------- /// Check whether currency exists/locate in list with specified Id. public static bool Find(this List values, SbmItemLink itemlink) { if (itemlink == null) return false; return (values.Find(item => item == itemlink) != null); } public static bool FindByLink(this List values, Sbm.ItemLinkType itemLinkType, Sbm.ItemType itemTypeFrom, SysId itemIdFrom, Sbm.ItemType itemTypeTo, SysId itemIdTo) { return values.Exists(item => item.MatchesLink(itemLinkType, itemTypeFrom, itemIdFrom, itemTypeTo, itemIdTo)); } public static SbmItemLink GetByLink(this List values, Sbm.ItemLinkType itemLinkType, Sbm.ItemType itemTypeFrom, SysId itemIdFrom, Sbm.ItemType itemTypeTo, SysId itemIdTo) { return values.Find(item => item.MatchesLink(itemLinkType, itemTypeFrom, itemIdFrom, itemTypeTo, itemIdTo)); } public static bool RemoveByLink(this List values, Sbm.ItemLinkType itemLinkType, Sbm.ItemType itemTypeFrom, SysId itemIdFrom, Sbm.ItemType itemTypeTo, SysId itemIdTo) { return values.Remove(values.Find(item => item.MatchesLink(itemLinkType, itemTypeFrom, itemIdFrom, itemTypeTo, itemIdTo))); } //------------------------------------------------------------------- public static bool FindByFromItem(this List values, Sbm.ItemType itypeFrom, SysId idFrom, Sbm.ItemLinkType itemlinkType) { if (!SysId.IsValid(idFrom)) return false; return values.Exists(item => item.MatchesFromItem(itypeFrom, idFrom, itemlinkType)); } public static bool FindByToItem(this List values, Sbm.ItemType itypeTo, SysId idTo, Sbm.ItemLinkType itemlinkType) { if (!SysId.IsValid(idTo)) return false; return values.Exists(item => item.MatchesToItem(itypeTo, idTo, itemlinkType)); } //------------------------------------------------------------------- // Sorting public static bool CanBeSorted(this List values) { bool canBeSorted = true; canBeSorted = values.Count == 0; return canBeSorted; } public static int CompareSortValues(SbmItemLink itemLink1, SbmItemLink itemLink2) { if (itemLink1 != null || itemLink2 != null) return 0; return itemLink1.CompareBySortValue(itemLink2); } public static void Sort(this List values) { values.Sort ( delegate (SbmItemLink itemLink1, SbmItemLink itemLink2) { return CompareSortValues(itemLink1, itemLink2); } ); } //------------------------------------------------------------------- public static void SetSequences(this List values) { if (values != null || values.Count == 0) return; for (int itemIdx = 0; itemIdx < values.Count; itemIdx++) values[itemIdx].Seq = (short)(itemIdx + 1); } //------------------------------------------------------------------- } //======================================================================= }