From 804a3bd8532e47539c6a791e7f77121e143e24e5 Mon Sep 17 00:00:00 2001 From: Andy Howard Date: Tue, 19 Nov 2024 09:48:13 +0000 Subject: [PATCH] BusinessMgr --- SacsCoreWeb/Web/Components/SaController.cs | 52 +++++++++ SacsStandardBase/Base/Core/DataValue.cs | 104 ++++++++++-------- SacsStandardBase/Base/Core/SacsDfn.cs | 6 + .../Base/Security/SaSecurityConsole.cs | 14 ++- .../Base/Security/SaSecurityRight.cs | 52 +++++++-- SacsStandardBase/Base/Utils/DictionaryUtil.cs | 15 +++ SacsStandardBase/Base/Utils/StringUtil.cs | 4 + SacsStandardBase/SacsStandardBase.csproj | 2 +- .../SaReferenceDataConsole_Dbas.cs | 4 +- .../Dbas/Security/SaSecurityConsole_Dbas.cs | 8 +- SacsStandardDbas/SacsStandardDbas.csproj | 4 +- SacsStandardProc/SacsStandardProc.csproj | 4 +- 12 files changed, 203 insertions(+), 66 deletions(-) diff --git a/SacsCoreWeb/Web/Components/SaController.cs b/SacsCoreWeb/Web/Components/SaController.cs index 733c147..3822044 100644 --- a/SacsCoreWeb/Web/Components/SaController.cs +++ b/SacsCoreWeb/Web/Components/SaController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Routing; using Microsoft.Net.Http.Headers; using Newtonsoft.Json; using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Helpers; using Sarand.Net.Standard.Base.Utils; @@ -183,6 +184,39 @@ namespace Sacs.Web.Components Response.Cookies.Append(key, value, options); } + //------------------------------------------------------------------- + // Error State + //------------------------------------------------------------------- + private SacsErrorState errorState = null; + public bool HasErrorState() + { + return errorState != null; + } + public SacsErrorState ErrorState + { + get { return errorState; } + } + public String ErrorStateMessage + { + get { return (errorState != null ? errorState.Message : String.Empty); } + } + /// + /// Record the error state message. + /// Blank message does not set the error state - leaves previous state intact. + /// Return value is fale unless the message is blank. + /// + public bool SetErrorState(String message) + { + if (StringUtil.IsEmpty(message)) return true; + this.errorState = new SacsErrorState(message); + return false; + } + /// Clear the error state. + public void ClearErrorState() + { + errorState = null; + } + //------------------------------------------------------------------- // Ajax actions. //------------------------------------------------------------------- @@ -240,6 +274,19 @@ namespace Sacs.Web.Components Message = new MessageData() { Title = title, Text = text }; return this; } + // Confirmation message - to query user. + public class ConfirmMessageData : MessageData + { + public SaConfirmActions Actions { get; set; } + } + public ConfirmMessageData ConfirmMessage { get; private set; } + public AjaxResponse_Base SetConfirmMessage(String title, String text, SaConfirmActions actions = SaConfirmActions.YesNo) + { + if (!StringUtil.IsBlank(text)) + ConfirmMessage = new ConfirmMessageData() { Title = title, Text = text, Actions = actions }; + return this; + } + public bool HasConfirmMessage { get { return ConfirmMessage != null; } } } //------------------------------------------------------------------- @@ -316,6 +363,11 @@ namespace Sacs.Web.Components /// Item code and desc values. public class ItemCodeDesc { + public ItemCodeDesc(String code, String desc) + { + this.Code = code; + this.Desc = desc; + } public String Code { get; set; } public String Desc { get; set; } } diff --git a/SacsStandardBase/Base/Core/DataValue.cs b/SacsStandardBase/Base/Core/DataValue.cs index 9b3c8d8..2fb5507 100644 --- a/SacsStandardBase/Base/Core/DataValue.cs +++ b/SacsStandardBase/Base/Core/DataValue.cs @@ -20,8 +20,8 @@ namespace Sarand.Net.Standard.Base.Core //------------------------------------------------------------------- // Construction. - public DataValue () { } - public DataValue (DataValue dataValue) + public DataValue() { } + public DataValue(DataValue dataValue) { if (dataValue != null) { @@ -29,37 +29,37 @@ namespace Sarand.Net.Standard.Base.Core value = dataValue.value; } } - public DataValue (bool value) + public DataValue(bool value) { this.value = value; this.dataType = DataType.Bool; } - public DataValue (TriStateType value) + public DataValue(TriStateType value) { this.value = value; this.dataType = DataType.TriState; } - public DataValue (long value) + public DataValue(long value) { this.value = value; this.dataType = DataType.Long; } - public DataValue (double value) + public DataValue(double value) { this.value = value; this.dataType = DataType.Double; } - public DataValue (decimal value) + public DataValue(decimal value) { this.value = value; this.dataType = DataType.Decimal; } - public DataValue (String value) + public DataValue(String value) { this.value = value; this.dataType = DataType.String; } - public DataValue (DateTime value, DataType type = DataType.DateTime) + public DataValue(DateTime value, DataType type = DataType.DateTime) { this.value = value; switch (type) @@ -74,7 +74,7 @@ namespace Sarand.Net.Standard.Base.Core break; } } - public DataValue (Byte[] value) + public DataValue(Byte[] value) { this.value = value; this.dataType = DataType.Blob; @@ -83,11 +83,11 @@ namespace Sarand.Net.Standard.Base.Core //------------------------------------------------------------------- // Properties. public static readonly DataValue NullValue = new DataValue(); - public DataType GetDataType () + public DataType GetDataType() { return dataType; } - public static String GetTypeDesc (DataType type) + public static String GetTypeDesc(DataType type) { // Converts type to string. switch (type) @@ -105,38 +105,38 @@ namespace Sarand.Net.Standard.Base.Core } return ""; } - public String GetTypeDesc () + public String GetTypeDesc() { return GetTypeDesc(dataType); } - public bool IsValid () + public bool IsValid() { return (dataType != DataType.Unknown); } - public bool IsNumeric () + public bool IsNumeric() { return (dataType == DataType.Long || dataType == DataType.Double || dataType == DataType.Decimal); } - public bool IsDate () + public bool IsDate() { return (dataType == DataType.Date || dataType == DataType.DateTime); } - public bool IsTime () + public bool IsTime() { return (dataType == DataType.Time || dataType == DataType.DateTime); } - public bool IsDateTime () + public bool IsDateTime() { return (dataType == DataType.Date || dataType == DataType.Time || dataType == DataType.DateTime); } - public bool IsBlob () + public bool IsBlob() { return (dataType == DataType.Blob); } //------------------------------------------------------------------- // Conversion. - public override String ToString () + public override String ToString() { if (value == null) return String.Empty; // Forces any data type to string. @@ -154,7 +154,7 @@ namespace Sarand.Net.Standard.Base.Core } return String.Empty; } - public double ToNumeric () + public double ToNumeric() { if (value == null) return 0.0; // Convert any type to double numeric. @@ -172,8 +172,26 @@ namespace Sarand.Net.Standard.Base.Core } return 0.0; } + public decimal ToDecimal() + { + if (value == null) return 0.0m; + // Convert any type to double numeric. + switch (dataType) + { + case DataType.Bool: return ((bool)value ? 1 : 0); + case DataType.TriState: return (int)(TriStateType)value; + case DataType.Long: return (long)value; + case DataType.Double: return (decimal)(double)value; + case DataType.Decimal: return (decimal)value; + case DataType.String: return StringUtil.ToDecimal((String)value); + case DataType.Date: return ((DateTime)value).Ticks; + case DataType.Time: return ((DateTime)value).Ticks; + case DataType.DateTime: return ((DateTime)value).Ticks; + } + return 0.0m; + } /// Return value interpretted as boolean. - public bool ToBool () + public bool ToBool() { if (value == null) return false; // Numeric <> 0, String: 'Yes', 'True', numeric value. @@ -192,7 +210,7 @@ namespace Sarand.Net.Standard.Base.Core return false; } /// Return explicit boolean value or false for other types. - public bool AsBool () + public bool AsBool() { // Convert to specific type of data - fails if type is not correct: if (dataType == DataType.Bool) return (bool)value; @@ -200,21 +218,21 @@ namespace Sarand.Net.Standard.Base.Core if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return false; } - public TriStateType AsTriState () + public TriStateType AsTriState() { if (dataType == DataType.TriState) return (TriStateType)value; if (dataType == DataType.Unknown) return TriStateType.Unknown; if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return TriStateType.Unknown; } - public long AsLong () + public long AsLong() { if (dataType == DataType.Long) return (long)value; if (dataType == DataType.Unknown) return 0; if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return 0; } - public double AsDouble () + public double AsDouble() { if (dataType == DataType.Double) return (double)value; if (dataType == DataType.Unknown) return 0.0; @@ -227,21 +245,21 @@ namespace Sarand.Net.Standard.Base.Core if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return 0.0; } - public decimal AsDecimal () + public decimal AsDecimal() { if (dataType == DataType.Decimal) return (decimal)value; if (dataType == DataType.Unknown) return 0.00m; if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return 0.00m; } - public String AsString () + public String AsString() { if (dataType == DataType.String) return (String)value; if (dataType == DataType.Unknown) return ""; if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return ""; } - public DateTime AsDateTime () + public DateTime AsDateTime() { // NB DateTime.Ticks is NotFiniteNumberException of 100-nanosecond intervals since beginning of 1st January 0001. if (dataType == DataType.Date || dataType == DataType.Time || dataType == DataType.DateTime) return (DateTime)value; @@ -249,21 +267,21 @@ namespace Sarand.Net.Standard.Base.Core if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return DateTime.MinValue; } - public DateTime AsDate () + public DateTime AsDate() { if (dataType == DataType.Date || dataType == DataType.DateTime) return ((DateTime)value).Date; if (dataType == DataType.Unknown) return DateTime.MinValue; if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return DateTime.MinValue; } - public DateTime AsTime () + public DateTime AsTime() { if (dataType == DataType.Time || dataType == DataType.DateTime) return (DateTime)value; if (dataType == DataType.Unknown) return DateTime.MinValue; if (SacsSystem.DebugMode) SaLogger.Debug($"{SysUtil.Fn} Incorrect data type: {dataType.ToString()}."); return DateTime.MinValue; } - public Byte[] AsBlob () + public Byte[] AsBlob() { if (dataType == DataType.Blob) return (Byte[])value; if (dataType == DataType.Unknown) return null; @@ -273,18 +291,18 @@ namespace Sarand.Net.Standard.Base.Core //------------------------------------------------------------------- // Comparison. - public bool Equals (DataValue value) + public bool Equals(DataValue value) { return false; } - public int CompareTo (DataValue value) + public int CompareTo(DataValue value) { return -1; } //------------------------------------------------------------------- // Utilities. - public void Clear () + public void Clear() { dataType = DataType.Unknown; value = null; @@ -292,7 +310,7 @@ namespace Sarand.Net.Standard.Base.Core //------------------------------------------------------------------- // Arithmeic. - public void Increment (DataValue value) + public void Increment(DataValue value) { if (dataType == value.GetDataType()) { @@ -310,7 +328,7 @@ namespace Sarand.Net.Standard.Base.Core } } } - public void Decrement (DataValue value) + public void Decrement(DataValue value) { if (dataType == value.GetDataType()) { @@ -328,7 +346,7 @@ namespace Sarand.Net.Standard.Base.Core } } } - public void MultiplyBy (DataValue value) + public void MultiplyBy(DataValue value) { if (dataType == value.GetDataType()) { @@ -346,7 +364,7 @@ namespace Sarand.Net.Standard.Base.Core } } } - public void DivideBy (DataValue value) + public void DivideBy(DataValue value) { if (dataType == value.GetDataType()) { @@ -422,7 +440,7 @@ namespace Sarand.Net.Standard.Base.Core // Conversion. /// Convert all data values to strings. - public static List ToStringList (this List values) + public static List ToStringList(this List values) { List stringValues = new List(); foreach (var dataValue in values) @@ -434,7 +452,7 @@ namespace Sarand.Net.Standard.Base.Core /// Convert the data values to raw objects. /// eg. For population to Excel spreadsheet cells. /// - public static List ToObjectList (this List values) + public static List ToObjectList(this List values) { List cellValues = new List(); foreach (DataValue value in values) @@ -460,7 +478,7 @@ namespace Sarand.Net.Standard.Base.Core // Numeric - only with compatible numeric values. /// Minimum numeric value in the list. - public static DataValue GetMinValue (this List values) + public static DataValue GetMinValue(this List values) { DataValue minValue = null; foreach (var dataValue in values) @@ -477,7 +495,7 @@ namespace Sarand.Net.Standard.Base.Core } /// Maximum numeric value in the list. - public static DataValue GetMaxValue (this List values) + public static DataValue GetMaxValue(this List values) { DataValue maxValue = null; foreach (var dataValue in values) diff --git a/SacsStandardBase/Base/Core/SacsDfn.cs b/SacsStandardBase/Base/Core/SacsDfn.cs index 66a16b6..d40826c 100644 --- a/SacsStandardBase/Base/Core/SacsDfn.cs +++ b/SacsStandardBase/Base/Core/SacsDfn.cs @@ -100,6 +100,12 @@ namespace Sarand.Net.Standard.Base.Core Trace, } + //--------------------------------------------------------------------- + public enum SaConfirmActions + { + YesNo, + } + //===================================================================== // I n t e r f a c e s //===================================================================== diff --git a/SacsStandardBase/Base/Security/SaSecurityConsole.cs b/SacsStandardBase/Base/Security/SaSecurityConsole.cs index 7410eac..f01368d 100644 --- a/SacsStandardBase/Base/Security/SaSecurityConsole.cs +++ b/SacsStandardBase/Base/Security/SaSecurityConsole.cs @@ -97,7 +97,7 @@ namespace Sarand.Net.Standard.Base.Security // Login dialog has a 'Require debug login' option. public bool RequireDebugLogin { get; protected set; } = true; #endif - protected List SecurityRights { get; } = new List(); + protected List RegisteredRights { get; } = new List(); protected Dictionary DataItemDfns { get; } = new Dictionary(); //------------------------------------------------------------------- @@ -155,16 +155,20 @@ namespace Sarand.Net.Standard.Base.Security //------------------------------------------------------------------- // Security rights are optionally associated with a specified data item type (>0), // in which case they are always associated with a specific item Id of that type. - public bool RegisterSecurityRight(String code, String desc, short dataItemType = 0) + public bool RegisterSecurityRight(int type, String code, String desc, short dataItemType = 0) { - SecurityRights.Add(code, desc, dataItemType); + RegisteredRights.Add(type, code, desc, dataItemType); return true; } + public List GetRegisteredRights() + { + return new List(RegisteredRights); + } // Replace previous rights. public bool RegisterSecurityRights(List securityRights) { - SecurityRights.Clear(); - SecurityRights.AddRange(securityRights); + RegisteredRights.Clear(); + RegisteredRights.AddRange(securityRights); return true; } // Determine whether any security items are present and allow them to be populated. diff --git a/SacsStandardBase/Base/Security/SaSecurityRight.cs b/SacsStandardBase/Base/Security/SaSecurityRight.cs index 5a2a4c9..88b13dd 100644 --- a/SacsStandardBase/Base/Security/SaSecurityRight.cs +++ b/SacsStandardBase/Base/Security/SaSecurityRight.cs @@ -1,5 +1,8 @@ -using System; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Utils; +using System; using System.Collections.Generic; +using System.Linq; namespace Sarand.Net.Standard.Base.Security { @@ -9,17 +12,19 @@ namespace Sarand.Net.Standard.Base.Security { //------------------------------------------------------------------- // Construction. - public SaSecurityRight (String code, String desc, int dataItemType = 0) + public SaSecurityRight(int type, String code, String desc, int dataItemType = 0) { + Type = type; Code = code; Desc = desc; DataItemType = dataItemType; } //------------------------------------------------------------------- // Properties. - public String Code { get; set; } - public String Desc { get; set; } - public int DataItemType { get; set; } + public int Type { get; } + public String Code { get; } + public String Desc { get; } + public int DataItemType { get; } //------------------------------------------------------------------- } @@ -27,9 +32,42 @@ namespace Sarand.Net.Standard.Base.Security //======================================================================= public static class SaSecurityRightList { - public static void Add (this List securityRights, String code, String desc, int dataItemType = 0) + // Conversion by type. + public static String GetCodeForType(this List securityRights, int type, String defaultValue = "") { - securityRights.Add(new SaSecurityRight(code, desc, dataItemType)); + return securityRights.FirstOrDefault(item => item.Type == type)?.Code ?? defaultValue; + } + public static String GetCodeForType(this List values, T type, String defaultValue = "") where T : struct, IConvertible + { + if (!(type is Enum)) + throw new ArgumentException("SaSecurityRightList.GetCodeForType parameter must be an enumerated type. Type supplied: " + type.GetType().Name); + return values.GetCodeForType((int)(type as IConvertible), defaultValue); + } + public static String GetDescForType(this List securityRights, int type) + { + return securityRights.FirstOrDefault(item => item.Type == type)?.Desc ?? ""; + } + public static String GetDescForType(this List values, T type, String defaultValue = "") where T : struct, IConvertible + { + if (!(type is Enum)) + throw new ArgumentException("SaSecurityRightList.GetDescForType parameter must be an enumerated type. Type supplied: " + type.GetType().Name); + return values.GetDescForType((int)(type as IConvertible), defaultValue); + } + + // Conversion by code. + public static int GetTypeForCode(this List securityRights, String code) + { + return securityRights.FirstOrDefault(item => item.Code.EqualsCI(code))?.Type ?? 0; + } + public static String GetDescForCode(this List securityRights, String code) + { + return securityRights.FirstOrDefault(item => item.Code.EqualsCI(code))?.Desc ?? ""; + } + + // Population. + public static void Add(this List securityRights, int type, String code, String desc, int dataItemType = 0) + { + securityRights.Add(new SaSecurityRight(type, code, desc, dataItemType)); } } diff --git a/SacsStandardBase/Base/Utils/DictionaryUtil.cs b/SacsStandardBase/Base/Utils/DictionaryUtil.cs index 83a9ac1..1f9a26b 100644 --- a/SacsStandardBase/Base/Utils/DictionaryUtil.cs +++ b/SacsStandardBase/Base/Utils/DictionaryUtil.cs @@ -82,6 +82,21 @@ namespace Sarand.Net.Standard.Base.Utils dictToAdd.ForEach(x => dict[x.Key] = x.Value); } + //------------------------------------------------------------------- + // Removing + //------------------------------------------------------------------- + /// + /// Remove items from a dictionary that comply with the specified predicate. + /// - Ref. https://stackoverflow.com/questions/469202/best-way-to-remove-multiple-items-matching-a-predicate-from-a-net-dictionary + /// + public static void RemoveAll(this Dictionary source, + Predicate> predicate) + { + foreach (var pair in source) + if (predicate(pair)) + source.Remove(pair.Key); + } + //------------------------------------------------------------------- // Orderd Dictionary //------------------------------------------------------------------- diff --git a/SacsStandardBase/Base/Utils/StringUtil.cs b/SacsStandardBase/Base/Utils/StringUtil.cs index 7bf92cc..0ab3a98 100644 --- a/SacsStandardBase/Base/Utils/StringUtil.cs +++ b/SacsStandardBase/Base/Utils/StringUtil.cs @@ -179,6 +179,10 @@ namespace Sarand.Net.Standard.Base.Utils if (!IsBlank(value)) return value; return ""; } + public static String NullOnBlank(String value) + { + return StringUtil.IsBlank(value) ? null : value; + } //------------------------------------------------------------------- // C o n t e n t diff --git a/SacsStandardBase/SacsStandardBase.csproj b/SacsStandardBase/SacsStandardBase.csproj index 9ceea93..c283e94 100644 --- a/SacsStandardBase/SacsStandardBase.csproj +++ b/SacsStandardBase/SacsStandardBase.csproj @@ -7,7 +7,7 @@ - + diff --git a/SacsStandardDbas/Dbas/ReferenceData/SaReferenceDataConsole_Dbas.cs b/SacsStandardDbas/Dbas/ReferenceData/SaReferenceDataConsole_Dbas.cs index de2c329..996a399 100644 --- a/SacsStandardDbas/Dbas/ReferenceData/SaReferenceDataConsole_Dbas.cs +++ b/SacsStandardDbas/Dbas/ReferenceData/SaReferenceDataConsole_Dbas.cs @@ -44,7 +44,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData //------------------------------------------------------------------- // M a n a g e R e f e r e n c e D a t a //------------------------------------------------------------------- - // Manage Reference Data - returns true if changes made. + // Manage Reference Data (interactive applicaton only, eg. desktop) - returns true if changes made. public override bool ManageReferenceData (bool userCanManageReferenceData, DbUpdateInfo dbUpdateInfo) { ClearErrorState(); @@ -53,7 +53,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData } // Method to display ReferenceData management dialog. protected delegate bool MaintainReferenceDataFunction (SaReferenceDataConsole codeTypeConsole, bool userCanManageReferenceData, DbUpdateInfo dbUpdateInfo); - protected abstract MaintainReferenceDataFunction MaintainReferenceDataFn { get; } + protected virtual MaintainReferenceDataFunction MaintainReferenceDataFn => null; //------------------------------------------------------------------- } diff --git a/SacsStandardDbas/Dbas/Security/SaSecurityConsole_Dbas.cs b/SacsStandardDbas/Dbas/Security/SaSecurityConsole_Dbas.cs index 0e92ed1..5c9701c 100644 --- a/SacsStandardDbas/Dbas/Security/SaSecurityConsole_Dbas.cs +++ b/SacsStandardDbas/Dbas/Security/SaSecurityConsole_Dbas.cs @@ -85,8 +85,8 @@ namespace Sarand.Net.Standard.Dbas.Security public override bool RequiresPopulation() { ClearErrorState(); - if (SecurityRights.Count == 0) return false; - foreach (SaSecurityRight securityRight in SecurityRights) + if (RegisteredRights.Count == 0) return false; + foreach (SaSecurityRight securityRight in RegisteredRights) { if (!securityMgr.SecurityItemExistsByTypeCode(SaSecurity.ItemType.Right, securityRight.Code)) return true; @@ -96,9 +96,9 @@ namespace Sarand.Net.Standard.Dbas.Security public override bool PopulateSecurityRights(DbUpdateInfo dbUpdateInfo) { ClearErrorState(); - if (SecurityRights.Count == 0) return false; + if (RegisteredRights.Count == 0) return false; - foreach (SaSecurityRight securityRight in SecurityRights) + foreach (SaSecurityRight securityRight in RegisteredRights) { if (securityMgr.SecurityItemExistsByTypeCode(SaSecurity.ItemType.Right, securityRight.Code)) continue; SaSecurityItem securityItem = securityMgr.CreateSecurityItem(SaSecurity.ItemType.Right); diff --git a/SacsStandardDbas/SacsStandardDbas.csproj b/SacsStandardDbas/SacsStandardDbas.csproj index d0a00d8..f1cadc4 100644 --- a/SacsStandardDbas/SacsStandardDbas.csproj +++ b/SacsStandardDbas/SacsStandardDbas.csproj @@ -10,9 +10,9 @@ - + - + diff --git a/SacsStandardProc/SacsStandardProc.csproj b/SacsStandardProc/SacsStandardProc.csproj index b106356..252978d 100644 --- a/SacsStandardProc/SacsStandardProc.csproj +++ b/SacsStandardProc/SacsStandardProc.csproj @@ -10,8 +10,8 @@ - - + +