467 lines
14 KiB
C#
467 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Sarand.Net.Standard.Base.App;
|
|
using Sarand.Net.Standard.Base.Core;
|
|
using Sarand.Net.Standard.Base.Dbas;
|
|
using Sarand.Net.Standard.Base.Utils;
|
|
|
|
namespace Sarand.Net.Standard.Base.Bus
|
|
{
|
|
//=======================================================================
|
|
public class UpdateStamp
|
|
{
|
|
private DateTime on = DateTime.Now;
|
|
private SysId by = new SysId();
|
|
private String host = String.Empty;
|
|
public DateTime On
|
|
{
|
|
get { return on; }
|
|
set { on = value; }
|
|
}
|
|
public SysId By
|
|
{
|
|
get { return by; }
|
|
set { by = SysId.InvalidOnNull(value); }
|
|
}
|
|
public String Host
|
|
{
|
|
get { return host; }
|
|
set { host = StringUtil.EmptyOnNull(value); }
|
|
}
|
|
}
|
|
//=======================================================================
|
|
public class SacsHierarchyItem : SaErrorStateItem
|
|
{
|
|
//-------------------------------------------------------------------
|
|
// Definitions.
|
|
public class Data
|
|
{
|
|
//---------------------------------------------------------------
|
|
// Common properties.
|
|
private SysId id = new SysId();
|
|
private String notes = String.Empty;
|
|
/// <summary>Item identifier.</summary>
|
|
public SysId Id
|
|
{
|
|
get { return SysId.InvalidOnNull(id); }
|
|
set
|
|
{
|
|
CheckChanged(id, value);
|
|
id = SysId.InvalidOnNull(value);
|
|
}
|
|
}
|
|
/// <summary>Item notes.</summary>
|
|
public String Notes
|
|
{
|
|
get { return StringUtil.EmptyOnNull(notes); }
|
|
set
|
|
{
|
|
CheckChanged(notes, value);
|
|
notes = StringUtil.EmptyOnNull(value);
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
// Flags.
|
|
private UInt16 flags = 0;
|
|
/// <summary>Item flags.<para>Up to 16 flags supported.</para></summary>
|
|
public UInt16 Flags
|
|
{
|
|
get { return flags; }
|
|
set
|
|
{
|
|
CheckChanged(flags, value);
|
|
flags = value;
|
|
}
|
|
}
|
|
/// <summary>Get flag value - position 1 - 16</summary>
|
|
public bool GetFlag (Byte flagPos)
|
|
{
|
|
return SacsHierarchyItem.GetFlag(Flags, flagPos);
|
|
}
|
|
/// <summary>Set flag value - position 1 - 16</summary>
|
|
public void SetFlag (Byte flagPos, bool value)
|
|
{
|
|
CheckChanged(GetFlag(flagPos), value);
|
|
Flags = SacsHierarchyItem.SetFlag(Flags, flagPos, value);
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
// Status.
|
|
private SaStatus status = SaStatus.Unknown;
|
|
/// <summary>Item status.</summary>
|
|
public SaStatus Status
|
|
{
|
|
get { return status; }
|
|
set
|
|
{
|
|
CheckChangedEnum(status, value);
|
|
status = value;
|
|
}
|
|
}
|
|
public String StatusCode
|
|
{
|
|
get { return SacsSystem.GetStatusCode(Status); }
|
|
set { Status = SacsSystem.GetStatusForCode(value); }
|
|
}
|
|
public String StatusDesc
|
|
{
|
|
get { return SacsSystem.GetStatusDesc(Status); }
|
|
}
|
|
public bool IsStatusCurrent { get { return Status == SaStatus.Current; } }
|
|
public bool IsStatusActive { get { return Status == SaStatus.Active; } }
|
|
public bool IsStatusEnabled { get { return Status == SaStatus.Enabled; } }
|
|
public bool IsStatusCompleted { get { return Status == SaStatus.Completed; } }
|
|
public bool IsStatusCancelled { get { return Status == SaStatus.Cancelled; } }
|
|
public bool IsStatusDeleted { get { return Status == SaStatus.Deleted; } }
|
|
|
|
//---------------------------------------------------------------
|
|
// Update stamps.
|
|
public UpdateStamp CreateStamp { get; protected set; } = new UpdateStamp();
|
|
public UpdateStamp UpdateStamp { get; protected set; } = new UpdateStamp();
|
|
|
|
//---------------------------------------------------------------
|
|
// Population.
|
|
/// <summary>Copy common properties to this object.</summary>
|
|
protected void PopulateFrom (Data sourceData)
|
|
{
|
|
Id = sourceData.Id;
|
|
Notes = sourceData.Notes;
|
|
Status = sourceData.Status;
|
|
Flags = sourceData.Flags;
|
|
CreateStamp = sourceData.CreateStamp;
|
|
UpdateStamp = sourceData.UpdateStamp;
|
|
}
|
|
/// <summary>Copy comon properties to the target object.</summary>
|
|
internal void PopulateTo (Data targetData)
|
|
{
|
|
targetData.PopulateFrom(this);
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
// Property change tracking.
|
|
private bool changed = false;
|
|
/// <summary>Flag to indicate whether any property has been modified.</summary>
|
|
public bool Changed
|
|
{
|
|
get { return changed; }
|
|
set
|
|
{
|
|
if (changed == value) return;
|
|
changed = value;
|
|
}
|
|
}
|
|
/// <summary>Clear 'Changed' flag.</summary>
|
|
public void AcceptChanges ()
|
|
{
|
|
Changed = false;
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
// Compare old and new property values and set 'Changed' if different.
|
|
protected void CheckChanged (SysId oldValue, SysId newValue)
|
|
{
|
|
if (Changed) return;
|
|
// Compare by numeric value so that invalid values are equal.
|
|
Changed = SysId.ToInt(oldValue) != SysId.ToInt(newValue);
|
|
}
|
|
protected void CheckChanged (ItemId oldValue, ItemId newValue)
|
|
{
|
|
if (Changed) return;
|
|
Changed = (oldValue.Type != newValue.Type) || (!oldValue.Id.Equals(newValue.Id));
|
|
}
|
|
protected void CheckChanged (String oldValue, String newValue)
|
|
{
|
|
if (Changed) return;
|
|
Changed = !StringUtil.EmptyOnNull(oldValue).Equals(StringUtil.EmptyOnNull(newValue));
|
|
}
|
|
protected void CheckChanged (bool oldValue, bool newValue)
|
|
{
|
|
if (Changed) return;
|
|
Changed = (oldValue != newValue);
|
|
}
|
|
protected void CheckChangedEnum<T>(T oldValue, T newValue) where T : struct, IConvertible
|
|
{
|
|
if (!(oldValue is Enum) || !(newValue is Enum))
|
|
throw new ArgumentException(GetType().Name+ ".CheckChangedEnum<T> Parameters must be enumerated types. Type supplied: " + oldValue.GetType().Name + ", " + newValue.GetType().Name);
|
|
if (Changed) return;
|
|
Changed = ((int)(oldValue as IConvertible) != (int)(newValue as IConvertible));
|
|
}
|
|
protected void CheckChanged (long oldValue, long newValue)
|
|
{
|
|
if (Changed) return;
|
|
Changed = (oldValue != newValue);
|
|
}
|
|
protected void CheckChanged (double oldValue, double newValue)
|
|
{
|
|
if (Changed) return;
|
|
Changed = (oldValue != newValue);
|
|
}
|
|
protected void CheckChanged (decimal oldValue, decimal newValue)
|
|
{
|
|
if (Changed) return;
|
|
Changed = (oldValue != newValue);
|
|
}
|
|
protected void CheckChanged (DateTime oldValue, DateTime newValue)
|
|
{
|
|
if (Changed) return;
|
|
Changed = !oldValue.Equals(newValue);
|
|
}
|
|
protected void CheckChanged (List<String> oldValues, List<String> newValues)
|
|
{
|
|
if (Changed) return;
|
|
Changed = !oldValues.ContentEquals(newValues);
|
|
}
|
|
protected void CheckChanged<T> (List<T> oldValues, List<T> newValues)
|
|
{
|
|
if (Changed) return;
|
|
if (oldValues.Count() != newValues.Count()) Changed = true;
|
|
else
|
|
{
|
|
for (int idx = 0; idx < oldValues.Count(); idx++)
|
|
{
|
|
if (!oldValues[idx].Equals(newValues[idx]))
|
|
{
|
|
Changed = true;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
protected void CheckChanged (byte[] oldValue, byte[] newValue)
|
|
{
|
|
if (Changed) return;
|
|
if ((oldValue == null) != (newValue != null)) Changed = true;
|
|
else if (oldValue.Length != newValue.Length) Changed = true;
|
|
if (oldValue != null && newValue != null)
|
|
Changed = !oldValue.SequenceEqual(newValue);
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Property validation.
|
|
public enum ValidValue
|
|
{
|
|
/// <summary>Property is valid (or has not been validate).</summary>
|
|
Valid,
|
|
/// <summary>Property is invalid.</summary>
|
|
Invalid,
|
|
/// <summary>Property is to be ignored during validation.</summary>
|
|
Ignore,
|
|
}
|
|
public class ErrField
|
|
{
|
|
// Identifies the field that has invalid data.
|
|
public ValidValue Id { get; set; } = ValidValue.Valid;
|
|
public ValidValue Notes { get; set; } = ValidValue.Valid;
|
|
public ValidValue Status { get; set; } = ValidValue.Valid;
|
|
public ValidValue Flags { get; set; } = ValidValue.Valid;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Data members.
|
|
// Data object holds object business properties.
|
|
// Starts as internal class, replaced on construction by object specific class.
|
|
private Data data = new Data();
|
|
|
|
//-------------------------------------------------------------------
|
|
// Construction.
|
|
protected SacsHierarchyItem ()
|
|
{
|
|
}
|
|
protected SacsHierarchyItem (SysId id)
|
|
{
|
|
data.Id = id;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Disposal.
|
|
protected override void Dispose (bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Properties.
|
|
public virtual bool ItemHasId { get; } = true;
|
|
public SysId Id
|
|
{
|
|
get
|
|
{
|
|
if (!ItemHasId) throw new NotSupportedException(GetType().Name + ".Id Item has no Id property");
|
|
return data.Id;
|
|
}
|
|
set
|
|
{
|
|
if (!ItemHasId && SysId.IsValid(data.Id)) throw new NotSupportedException(GetType().Name + ".Id Item has no Id property");
|
|
if (SysId.IsValid(data.Id) && (!SysId.IsValid(value) || !data.Id.Equals(value)))
|
|
throw new NotSupportedException("SacsHierarchyItem.Id.set Id already has a valid value");
|
|
data.Id = value;
|
|
}
|
|
}
|
|
public String Notes
|
|
{
|
|
get { return StringUtil.EmptyOnNull(data.Notes); }
|
|
set { data.Notes = value; }
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Status.
|
|
public SaStatus Status
|
|
{
|
|
get { return data.Status; }
|
|
set { data.Status = value; }
|
|
}
|
|
public String StatusCode
|
|
{
|
|
get { return data.StatusCode; }
|
|
set { data.StatusCode = value; }
|
|
}
|
|
public String StatusDesc
|
|
{
|
|
get { return data.StatusDesc; }
|
|
}
|
|
public bool IsStatusCurrent { get { return data.IsStatusCurrent; } }
|
|
public bool IsStatusActive { get { return data.IsStatusActive; } }
|
|
public bool IsStatusEnabled { get { return data.IsStatusEnabled; } }
|
|
public bool IsStatusCompleted { get { return data.IsStatusCompleted; } }
|
|
public bool IsStatusCancelled { get { return data.IsStatusCancelled; } }
|
|
public bool IsStatusDeleted { get { return data.IsStatusDeleted; } }
|
|
|
|
//-------------------------------------------------------------------
|
|
// Flags.
|
|
public UInt16 Flags
|
|
{
|
|
get { return data.Flags; }
|
|
protected set { data.Flags = value; }
|
|
}
|
|
/// <summary>Flags are positioned from 1, up to 16 allowed.</summary>
|
|
public static bool GetFlag (UInt16 flags, Byte flagPos)
|
|
{
|
|
bool flag = false;
|
|
if (flagPos > 0 && flagPos <= 16)
|
|
flag = (((flags >> (flagPos - 1)) & 0x0001) == 1 ? true : false);
|
|
return flag;
|
|
}
|
|
/// <summary>Flags are positioned from 1, up to 16 allowed.</summary>
|
|
public bool GetFlag (Byte flagPos)
|
|
{
|
|
return GetFlag(data.Flags, flagPos);
|
|
}
|
|
/// <summary>Set flag value - position 1 - 16</summary>
|
|
public static UInt16 SetFlag (UInt16 flags, Byte flagPos, bool value)
|
|
{
|
|
if (flagPos > 0 && flagPos <= 16)
|
|
{
|
|
UInt16 mask = (UInt16)(1 << (flagPos - 1));
|
|
if (value)
|
|
flags |= mask;
|
|
else
|
|
flags &= (UInt16)(~mask);
|
|
}
|
|
return flags;
|
|
}
|
|
/// <summary>Set flag value - position 1 - 16</summary>
|
|
public void SetFlag (Byte flagPos, bool value)
|
|
{
|
|
data.Flags = SetFlag(data.Flags, flagPos, value);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Update stamps.
|
|
public UpdateStamp CreateStamp { get { return data.CreateStamp; } }
|
|
public void SetCreateStamp (DateTime on, SysId by, String host)
|
|
{
|
|
CreateStamp.On = on;
|
|
CreateStamp.By = by;
|
|
CreateStamp.Host = host;
|
|
}
|
|
public UpdateStamp UpdateStamp { get { return data.UpdateStamp; } }
|
|
public void SetUpdateStamp (DateTime on, SysId by, String host)
|
|
{
|
|
UpdateStamp.On = on;
|
|
UpdateStamp.By = by;
|
|
UpdateStamp.Host = host;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Populate data item - only once on construction.
|
|
protected void SetData (Data data)
|
|
{
|
|
String fn = GetType().Name + ".SetData";
|
|
// Can only be replaced if currently internal class.
|
|
if (this.data.GetType() != typeof(Data))
|
|
throw new NotSupportedException(fn + " Data object has already been specified");
|
|
// If Id has already been specified (on construction) and supplied Id is not valid, set it to the existing value.
|
|
if (ItemHasId && SysId.IsValid(Id) && !SysId.IsValid(data.Id)) data.Id = Id;
|
|
// Properties that cannot be changed if previously specified.
|
|
if (ItemHasId && SysId.IsValid(Id) && SysId.ToInt(Id) != SysId.ToInt(data.Id))
|
|
throw new NotSupportedException(fn + " Id cannot be changed");
|
|
this.data.PopulateTo(data);
|
|
this.data = data;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Property change tracking.
|
|
/// <summary>Flag to indicate whether any property has been modified.</summary>
|
|
public bool Changed
|
|
{
|
|
get { return data.Changed; }
|
|
set
|
|
{
|
|
if (data.Changed == value) return;
|
|
data.Changed = value;
|
|
}
|
|
}
|
|
/// <summary>Clear the 'Changed' flag to indicate that no changes have been made.</summary>
|
|
public void AcceptChanges ()
|
|
{
|
|
Changed = false;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Format value for display.
|
|
public static String FormatForDisplay (String value, int maxLength = 0)
|
|
{
|
|
if (StringUtil.IsEmpty(value)) return String.Empty;
|
|
// Replace non-display characters.
|
|
value = value.Replace("\t", " ").Replace("\r", " ").Replace("\n", " ");
|
|
// Remove leading, trailing and multiple internal spaces.
|
|
value = value.Trim().Replace(" +", " ");
|
|
// Restrict to maximum length.
|
|
if (maxLength > 0 && value.Length > maxLength)
|
|
{
|
|
value = value.Left(maxLength);
|
|
if (maxLength > 20) value += "...";
|
|
}
|
|
return value;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Parameters.
|
|
public class Params
|
|
{
|
|
// Construction.
|
|
protected Params ()
|
|
{
|
|
}
|
|
/// <summary>Primary table alias to use if different from default.</summary>
|
|
public String TableAlias { get; set; }
|
|
/// <summary>Flag to indicate whether default filter ('1=1') is included if no other filter.</summary>
|
|
public bool IncludeDefaultFilter { get; set; } = true;
|
|
/// <summary>Results list paging.</summary>
|
|
public DbQuery.Paging ResultsPaging { get; } = new DbQuery.Paging();
|
|
/// <summary>Sort columns.</summary>
|
|
public List<ColumnDfn> SortColumns { get; } = new List<ColumnDfn>();
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|