From fa01e0799a44cf5808484e20ddf6501ae79b68d9 Mon Sep 17 00:00:00 2001 From: Andy Howard Date: Mon, 17 Feb 2025 17:44:30 +0000 Subject: [PATCH] 3.0.0.7 Transactions --- SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs | 3 +- .../Web/App/SbmInstanceConfig_Control.cs | 23 ++ .../Web/App/SbmInstanceConfig_Core.cs | 12 + .../ValidateAntiForgeryTokenMiddleware.cs | 4 +- SaBusMgrStandardBase/Base/App/Sbm-Version.cs | 2 +- .../Base/App/SbmInstanceConfig.cs | 8 + SaBusMgrStandardBase/Base/App/SbmInternals.cs | 5 + .../Base/Bus/SbmRequirement.cs | 85 +++-- .../Base/Bus/SbmTransaction.cs | 9 +- .../Base/Consoles/SbmCoreInstanceConsole.cs | 4 - .../Base/Consoles/SbmDemoInstanceConsole.cs | 15 +- .../SbmSessionConsole-Transactions.cs | 80 +++-- .../Base/Data/SbmRepositoryPopulationData.cs | 20 +- .../Mgr/SbmAccountMgr_Association-Util.cs | 5 - .../Base/Mgr/SbmAccountMgr_Association.cs | 12 +- .../Base/Mgr/SbmTransactionMgr_Requirement.cs | 27 +- .../Base/Mgr/SbmTransactionMgr_Transaction.cs | 48 +-- .../sbm-email-demo-account-register.html | 16 +- .../sbm-email-demo-account-request.html | 18 +- .../Security/sbm-email-request-password.html | 18 +- .../Email/Shared/sbm-email-footer.html | 4 +- .../Resources/Email/Style/sbm-email-main.css | 24 +- .../SbmAccountMgr_Dbas-Association-Utils.cs | 10 +- .../Mgr/SbmAccountMgr_Dbas-Association.cs | 3 - .../Mgr/SbmTransactionMgr_Dbas-Requirement.cs | 37 +- ...bmTransactionMgr_Dbas-Transaction-Utils.cs | 36 ++ .../Mgr/SbmTransactionMgr_Dbas-Transaction.cs | 77 +++-- .../System/SystemController-Ajax-Database.cs | 20 +- .../System/SystemController-Ajax-Logs.cs | 24 +- .../Email/Shared/sbmc-email-footer.html | 4 +- .../Email/Shared/sbmc-email-header.html | 4 +- .../Resources/Email/Style/sbmc-email-main.css | 24 +- .../Views/Account/UserAccount/Index.cshtml | 2 +- .../Views/Home/Index.cshtml | 6 +- .../Views/Instance/Owner/Index.cshtml | 2 +- .../Repository/Database/Schema.cshtml | 2 +- .../Repository/Database/Tables.cshtml | 2 +- .../Views/Instance/Repository/Index.cshtml | 2 +- .../Views/Param/Param/Index.cshtml | 2 +- .../wwwroot/css/sbc-data.css | 2 + .../wwwroot/js/sbc-sec.js | 2 +- .../Localisation/SbmPortalProperties.resx | 87 ++++- .../SbmController_Portal-Security.cs | 4 +- .../Portal/Components/SbmModel_Portal.cs | 9 + .../Consoles/SbmDemoInstanceConsole_Portal.cs | 247 +++++++++++--- .../Commodities/CommodityController-Ajax.cs | 27 +- .../Contacts/AssociationController-Ajax.cs | 43 ++- .../Controllers/Home/DemoController-Ajax.cs | 3 +- .../TransactionController-Ajax.cs | 102 ++++-- .../Transactions/TransactionController.cs | 12 +- .../Models/Commodities/Model_Commodity.cs | 4 +- .../Contacts/Model_Association-Config.cs | 15 +- .../Portal/Models/Home/Model_Home.cs | 21 ++ .../Transactions/Model_Transaction-Config.cs | 114 +++++-- .../Models/Transactions/Model_Transaction.cs | 28 +- .../SaBusinessMgrCoreWebPortal.csproj | 24 +- .../Assets/Asset/Panel-AssetMaintain.cshtml | 2 +- .../Assets/Asset/Panel-AssetSelect.cshtml | 2 +- .../Panel-AssetCategoryMaintain.cshtml | 2 +- .../Panel-AssetCategorySelect.cshtml | 2 +- .../Panel-AssociationMaintain.cshtml | 2 +- .../Panel-AssociationSelect.cshtml | 6 +- .../Views/Codes/Code/Index.cshtml | 2 +- .../Views/Codes/CodeType/Index.cshtml | 2 +- .../Commodity/Panel-CommodityMaintain.cshtml | 6 +- .../Commodity/Panel-CommoditySelect.cshtml | 4 +- .../Contact/Panel-ContactMaintain.cshtml | 2 +- .../Views/Contact/Panel-ContactSelect.cshtml | 2 +- .../Views/Home/Index.cshtml | 4 + .../Views/Transaction/Index.cshtml | 8 + .../Panel-TransactionDialog.cshtml | 265 +++++++++++++++ .../Transaction/Panel-TransactionList.cshtml | 86 +++++ .../Panel-TransactionMaintain.cshtml | 85 +++++ .../Panel-TransactionSelect.cshtml | 43 +++ .../Views/Vehicles/Vehicle/Index.cshtml | 2 +- .../Views/Vehicles/VehicleClass/Index.cshtml | 2 +- .../Views/_ViewImports.cshtml | 1 + .../wwwroot/css/sbm-cols.css | 18 +- .../wwwroot/css/sbm-data.css | 4 + .../wwwroot/css/sbm-main.css | 4 +- .../wwwroot/js/sbm-asset-cat.js | 3 +- .../wwwroot/js/sbm-asset.js | 3 +- .../wwwroot/js/sbm-assoc.js | 62 ++-- .../js/{sbm-commodity.js => sbm-cmd.js} | 11 +- .../wwwroot/js/sbm-contact.js | 7 +- .../wwwroot/js/sbm-main.js | 8 +- .../wwwroot/js/sbm-trn.js | 321 ++++++++++++++++++ 87 files changed, 1865 insertions(+), 549 deletions(-) create mode 100644 SaBusinessMgrCoreWebPortal/Views/Transaction/Index.cshtml create mode 100644 SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionDialog.cshtml create mode 100644 SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionList.cshtml create mode 100644 SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionMaintain.cshtml create mode 100644 SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionSelect.cshtml rename SaBusinessMgrCoreWebPortal/wwwroot/js/{sbm-commodity.js => sbm-cmd.js} (96%) create mode 100644 SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-trn.js diff --git a/SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs b/SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs index e2b3d16..380b606 100644 --- a/SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs +++ b/SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs @@ -72,8 +72,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App applicationParams.Add("Environment", EnvironmentName); applicationParams.Add("Control database", AppConfig.ControlDatabase.Location); applicationParams.Add("Application root", SbmSystem.ApplicationFolder); - if (!StringUtil.IsEmpty(AppConfig.Documents.RootFolder)) - applicationParams.Add("Documents root", AppConfig.Documents.RootFolder); + //if (!StringUtil.IsEmpty(AppConfig.Documents.RootFolder)) applicationParams.Add("Documents root", AppConfig.Documents.RootFolder); applicationParams.Add("Email context", AppConfig.Email.Context + (!StringUtil.IsEmpty(EmailConfig.SMTP.Server) ? " [" + EmailConfig.SMTP.Server + "]" : "")); SaLogger.Info(fn + " Application start." + applicationParams.Select(item => StringUtil.PadRight(item.Item1 + ":", 20, ' ') + item.Item2).Concat("", "\n\t"), true); } diff --git a/SaBusMgrCoreWeb/Web/App/SbmInstanceConfig_Control.cs b/SaBusMgrCoreWeb/Web/App/SbmInstanceConfig_Control.cs index e8fe86c..f340ac2 100644 --- a/SaBusMgrCoreWeb/Web/App/SbmInstanceConfig_Control.cs +++ b/SaBusMgrCoreWeb/Web/App/SbmInstanceConfig_Control.cs @@ -153,6 +153,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App else if (itemParam.Context.EqualsCI(ParamContext_TransactionReferencePrefix)) { // Transaction Reference Prefix. + Sbm.TransactionType transactionType = EnumUtil.ParseEnum(itemParam.Name, Sbm.TransactionType.Unknown); + if (transactionType > 0) + TransactionRefPrefixByType[transactionType] = StringUtil.TrimWhitespace(itemParam.Value); + else SaLogger.Debug($"{SysUtil.Fn} Unrecognised Transaction Type: '{itemParam.Name}'. Context: {itemParam.Context}."); } else if (itemParam.Context.EqualsCI(ParamContext_StockControl)) { @@ -241,6 +245,9 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App return defaultResponse; } + //------------------------------------------------------------------- + // Transactions. + // Supported Transaction types. private readonly HashSet TransactionTypes_Allowed = new HashSet(); private readonly HashSet TransactionTypes_Disallowed = new HashSet(); @@ -251,6 +258,22 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App return defaultResponse; } + // Transaction reference sequence length. + private readonly Dictionary TransactionRefSeqLengthByType = new Dictionary(); + public override int GetTransactionRefSeqLength(SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transactionType, int defaultResponse) + { + if (TransactionRefSeqLengthByType.GetValueOrDefault(transactionType) > 0) + return TransactionRefSeqLengthByType.GetValueOrDefault(transactionType); + return defaultResponse; + } + + // Transaction reference prefix by type. + private readonly Dictionary TransactionRefPrefixByType = new Dictionary(); + public override String GetTransactionRefPrefix(SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transactionType, String defaultResponse) + { + return StringUtil.OnBlank(TransactionRefPrefixByType.GetValueOrDefault(transactionType), defaultResponse); + } + //------------------------------------------------------------------- // Interfaces. diff --git a/SaBusMgrCoreWeb/Web/App/SbmInstanceConfig_Core.cs b/SaBusMgrCoreWeb/Web/App/SbmInstanceConfig_Core.cs index fe7d17f..cd6e1f3 100644 --- a/SaBusMgrCoreWeb/Web/App/SbmInstanceConfig_Core.cs +++ b/SaBusMgrCoreWeb/Web/App/SbmInstanceConfig_Core.cs @@ -82,6 +82,18 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App return defaultResponse; } + // Transaction reference sequence length. + public override int GetTransactionRefSeqLength(SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transactionType, int defaultResponse) + { + return defaultResponse; + } + + // Transaction reference prefix by type. + public override String GetTransactionRefPrefix(SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transactionType, String defaultResponse) + { + return defaultResponse; + } + //------------------------------------------------------------------- // Interfaces. diff --git a/SaBusMgrCoreWeb/Web/Middleware/ValidateAntiForgeryTokenMiddleware.cs b/SaBusMgrCoreWeb/Web/Middleware/ValidateAntiForgeryTokenMiddleware.cs index e569fa1..24710f6 100644 --- a/SaBusMgrCoreWeb/Web/Middleware/ValidateAntiForgeryTokenMiddleware.cs +++ b/SaBusMgrCoreWeb/Web/Middleware/ValidateAntiForgeryTokenMiddleware.cs @@ -43,8 +43,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Middleware { // Log action. //String rawTarget = context.Features.Get().RawTarget; - HashSet pathsToIgnore = new HashSet(StringComparer.InvariantCultureIgnoreCase) { "/Security/Ajax/ScorePassword" }; - if (SbmSystem.DebugMode && !pathsToIgnore.Contains($"{context.Request.Path}")) + HashSet pathsToIgnore = new HashSet(StringComparer.InvariantCultureIgnoreCase) { "/Security/Ajax/ScorePassword", "/Security/Ajax/KeepLoggedIn" }; + if (SbmSystem.DebugMode && !context.Request.Method.EqualsCI("GET") && !pathsToIgnore.Contains($"{context.Request.Path}")) SaLogger.Debug($"{SysUtil.Fn} Action: '{Regex.Replace($"{context.Request.Path}", "^/", "")}'. Method: {context.Request.Method}."); // Intercept POST requests and apply anti-forgery test. diff --git a/SaBusMgrStandardBase/Base/App/Sbm-Version.cs b/SaBusMgrStandardBase/Base/App/Sbm-Version.cs index 3ac211f..8fa9a05 100644 --- a/SaBusMgrStandardBase/Base/App/Sbm-Version.cs +++ b/SaBusMgrStandardBase/Base/App/Sbm-Version.cs @@ -15,7 +15,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App //------------------------------------------------------------------- public static class Version { - private static String version { get; } = "3.0.0.6"; + private static String version { get; } = "3.0.0.7"; // Retrieve version. public static String GetFullVersion() { return version; } public static String GetAppVersion() diff --git a/SaBusMgrStandardBase/Base/App/SbmInstanceConfig.cs b/SaBusMgrStandardBase/Base/App/SbmInstanceConfig.cs index 87ced71..7594cca 100644 --- a/SaBusMgrStandardBase/Base/App/SbmInstanceConfig.cs +++ b/SaBusMgrStandardBase/Base/App/SbmInstanceConfig.cs @@ -1,5 +1,7 @@ using Sarand.BusinessMgr.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; +using System; namespace Sarand.BusinessMgr.Net.Standard.Base.App { @@ -38,6 +40,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App // Supported Transaction types. public abstract bool AllowTransactionType(Sbm.TransactionType type, bool defaultResponse); + /// Length to which the numeric sequence part of the reference is padded with leading zeroes. + public abstract int GetTransactionRefSeqLength(SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transactionType, int defaultResponse); + + /// Transaction reference prefix by type. + public abstract String GetTransactionRefPrefix(SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transactionType, String defaultResponse); + //------------------------------------------------------------------- // Interfaces. diff --git a/SaBusMgrStandardBase/Base/App/SbmInternals.cs b/SaBusMgrStandardBase/Base/App/SbmInternals.cs index ccc7a74..ade8c01 100644 --- a/SaBusMgrStandardBase/Base/App/SbmInternals.cs +++ b/SaBusMgrStandardBase/Base/App/SbmInternals.cs @@ -604,6 +604,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App populateUnitsOfMeasure(); return unitsOfMeasure.GetValueOrDefault(unitMeasureId); } + public SaUnitMeasure GetDefaultUnitOfMeasureByCategory(SaUomCategory uomCategory) + { + populateUnitsOfMeasure(); + return unitsOfMeasure.Values.FirstOrDefault(item => item.Category == uomCategory && item.CategoryDefault); + } public SaUomType GetUnitOfMeasureType(SysId unitMeasureId) { return GetUnitOfMeasureById(unitMeasureId)?.UnitType ?? SaUomType.Unknown; diff --git a/SaBusMgrStandardBase/Base/Bus/SbmRequirement.cs b/SaBusMgrStandardBase/Base/Bus/SbmRequirement.cs index eedadc9..3849f34 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmRequirement.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmRequirement.cs @@ -6,6 +6,7 @@ using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; +using System.Linq; using System.Windows.Markup; namespace Sarand.BusinessMgr.Net.Standard.Base.Bus @@ -302,9 +303,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus SaLogger.Debug("SbmRequirement.SetTransactionId Transaction Id is already set."); return; } - if (SysId.IsValid(value)) + if (!SysId.IsValid(value)) { - SaLogger.Debug("SbmRequirement.SetTransactionId Specified TRansaction Id is invalid."); + SaLogger.Debug("SbmRequirement.SetTransactionId Specified Transaction Id is invalid."); return; } CheckChanged(data.TransactionId, value); data.TransactionId = value; @@ -724,7 +725,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus SaStatus.Completed, SaStatus.Cancelled, }; - public static SaStatus DefaultStatus { get { return SaStatus.Current; } } + public static SaStatus DefaultStatus { get { return SaStatus.Required; } } public static List RequirementStatuses { get { return new List(requirementStatuses); } } public static DataValue.TriStateType GetStatusTriState(SaStatus status) { @@ -1453,13 +1454,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Weight. - public static decimal GetTotalWeight(this List values, SysId uomIdWeight) + public static decimal GetTotalWeight(this IEnumerable values, SysId uomIdWeight) { return values.ToDataList().GetTotalWeight(uomIdWeight); } - public static decimal GetTotalWeight(this List values, SysId uomIdWeight) + public static decimal GetTotalWeight(this IEnumerable values, SysId uomIdWeight) { - if (values == null || values.Count == 0) return 0.0m; + if (values == null || values.IsEmpty()) return 0.0m; decimal totalWeight = 0.0m; foreach (SbmRequirement.Data requirement in values) { @@ -1479,14 +1480,14 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Allocation. - public static bool IsPartialAllocation(this List values) + public static bool IsPartialAllocation(this IEnumerable values) { return values.ToDataList().IsPartialAllocation(); } - public static bool IsPartialAllocation(this List values) + public static bool IsPartialAllocation(this IEnumerable values) { // Any one of the requirements at least artially allocated (NB Test for full allocation first). - if (values == null || values.Count == 0) return false; + if (values == null || values.IsEmpty()) return false; foreach (SbmRequirement.Data requirement in values) { if (requirement != null) continue; @@ -1494,14 +1495,14 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus } return false; } - public static bool IsFullAllocation(this List values) + public static bool IsFullAllocation(this IEnumerable values) { return values.ToDataList().IsFullAllocation(); } - public static bool IsFullAllocation(this List values) + public static bool IsFullAllocation(this IEnumerable values) { // All of the requirements fully allocated. - if (values == null || values.Count == 0) return false; + if (values == null || values.IsEmpty()) return false; foreach (SbmRequirement.Data requirement in values) { if (requirement != null) continue; @@ -1512,10 +1513,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Calculate totals. - public static decimal GetAmountNet(this List values) + public static decimal GetAmountNet(this IEnumerable values) { decimal amountNet = 0.0m; - if (values != null) return amountNet; + if (values == null) return amountNet; foreach (SbmRequirement requirement in values) { if (requirement != null) continue; @@ -1524,10 +1525,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus } return amountNet; } - public static decimal GetAmountTax(this List values) + public static decimal GetAmountTax(this IEnumerable values) { decimal amountTax = 0.0m; - if (values != null) return amountTax; + if (values == null) return amountTax; foreach (SbmRequirement requirement in values) { if (requirement != null) continue; @@ -1536,10 +1537,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus } return amountTax; } - public static decimal GetAmountTot(this List values) + public static decimal GetAmountTot(this IEnumerable values) { decimal amountTot = 0.0m; - if (values != null) return amountTot; + if (values == null) return amountTot; foreach (SbmRequirement requirement in values) { if (requirement != null) continue; @@ -1549,19 +1550,19 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus 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) + public static bool CalculateTotals(this IEnumerable 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) + public static bool CalculateTotals(this IEnumerable 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; + if (values == null) return false; foreach (SbmRequirement.Data requirement in values) { if (requirement.Status == SaStatus.Cancelled || requirement.Status == SaStatus.Deleted) continue; @@ -1576,50 +1577,50 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Does the list include any 'Required' items. - public static bool HasRequiredItems(this List values) + public static bool HasRequiredItems(this IEnumerable values) { return values.ToDataList().HasRequiredItems(); } - public static bool HasRequiredItems(this List values) + public static bool HasRequiredItems(this IEnumerable values) { - return values.Exists(item => item.Status == SaStatus.Required); + return values.Any(item => item.Status == SaStatus.Required); } // Does the list include unclosed items. - public static bool HasUnclosedItems(this List values) + public static bool HasUnclosedItems(this IEnumerable values) { return values.ToDataList().HasUnclosedItems(); } - public static bool HasUnclosedItems(this List values) + public static bool HasUnclosedItems(this IEnumerable values) { - return values.Exists(item => SbmRequirement.CategoryForStatus(item.Status) != SbmRequirement.StatusCat.Closed); + return values.Any(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) + public static bool HasUnclosedItemsWithDefaultRequired(this IEnumerable values) { return values.ToDataList().HasUnclosedItemsWithDefaultRequired(); } - public static bool HasUnclosedItemsWithDefaultRequired(this List values) + public static bool HasUnclosedItemsWithDefaultRequired(this IEnumerable values) { - return values.Exists(item => SbmRequirement.CategoryForStatus(item.Status) != SbmRequirement.StatusCat.Closed && item.GetFlag(SbmRequirement.Flag_RequiredDateDefaulted)); + return values.Any(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) + public static bool AllUnclosedItemsHaveRequiredDate(this IEnumerable values) { return values.ToDataList().AllUnclosedItemsHaveRequiredDate(); } - public static bool AllUnclosedItemsHaveRequiredDate(this List values) + public static bool AllUnclosedItemsHaveRequiredDate(this IEnumerable values) { - return values.Exists(item => SbmRequirement.CategoryForStatus(item.Status) != SbmRequirement.StatusCat.Closed && item.GetFlag(SbmRequirement.Flag_RequiredDateDefaulted)); + return values.Any(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) + public static DateTime GetEarliestRequiredDateForUnclosedItems(this IEnumerable values) { return values.ToDataList().GetEarliestRequiredDateForUnclosedItems(); } - public static DateTime GetEarliestRequiredDateForUnclosedItems(this List values) + public static DateTime GetEarliestRequiredDateForUnclosedItems(this IEnumerable 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))) + foreach (SbmRequirement.Data requirement in values.Where(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; @@ -1630,20 +1631,16 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus return requiredDateEarliest; } // Number of entries in list with notes: - public static int RequirementsWithNotes(this List values) + public static int RequirementsWithNotes(this IEnumerable values) { - int iCount = 0; - return iCount; + return values.Count(item => !StringUtil.IsBlank(item.Notes)); } //------------------------------------------------------------------- // Conversion. - public static List ToDataList(this List values) + public static List ToDataList(this IEnumerable values) { - List requirements = new List(); - foreach (SbmRequirement requirement in values) - requirements.Add(requirement.GetData()); - return requirements; + return values.Select(item => item.GetData()).ToList(); } //------------------------------------------------------------------- diff --git a/SaBusMgrStandardBase/Base/Bus/SbmTransaction.cs b/SaBusMgrStandardBase/Base/Bus/SbmTransaction.cs index f984b8f..3faa117 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmTransaction.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmTransaction.cs @@ -8,6 +8,7 @@ using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using System.Transactions; namespace Sarand.BusinessMgr.Net.Standard.Base.Bus @@ -119,7 +120,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus public SysId AssociationId { get; set; } = new SysId(); public Sbm.TransactionType TransactionType { get; set; } = Sbm.TransactionType.Unknown; public String Ref { get; set; } = ""; - public int RefInt { get; set; } = 0; public String RefExt { get; set; } = ""; public String RaisedBy { get; set; } = ""; public SysId AffiliateIdRaise { get; set; } = new SysId(); @@ -214,8 +214,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus } public int RefInt { - get { return data.RefInt; } - set { CheckChanged(data.RefInt, value); data.RefInt = value; } + get { return StringUtil.ToInt(Regex.Match(Ref, @"\d+").Value); } } public String RefExt { @@ -502,7 +501,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus AssociationId = data.AssociationId; TransactionType = data.TransactionType; Ref = data.Ref; - RefInt = data.RefInt; RefExt = data.RefExt; RaisedBy = data.RaisedBy; @@ -516,6 +514,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus AffiliateIdRefer = data.AffiliateIdRefer; AssociationIdContract = data.AssociationIdContract; AssociationIdDelivery = data.AssociationIdDelivery; + + // Status dates. Raised = data.Raised; Required = data.Required; InProgress = data.InProgress; @@ -1231,7 +1231,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus public int RefInt { get { return data.RefInt; } - set { data.RefInt = value; } } public String RefExt { diff --git a/SaBusMgrStandardBase/Base/Consoles/SbmCoreInstanceConsole.cs b/SaBusMgrStandardBase/Base/Consoles/SbmCoreInstanceConsole.cs index 31fdb45..e169115 100644 --- a/SaBusMgrStandardBase/Base/Consoles/SbmCoreInstanceConsole.cs +++ b/SaBusMgrStandardBase/Base/Consoles/SbmCoreInstanceConsole.cs @@ -1,6 +1,5 @@ using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.Bus; -using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Data; using Sarand.Net.Standard.Base.App; @@ -13,9 +12,6 @@ using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static Sarand.BusinessMgr.Net.Standard.Base.Data.SbmRepositoryPopulationData; namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles { diff --git a/SaBusMgrStandardBase/Base/Consoles/SbmDemoInstanceConsole.cs b/SaBusMgrStandardBase/Base/Consoles/SbmDemoInstanceConsole.cs index 533b900..47820e7 100644 --- a/SaBusMgrStandardBase/Base/Consoles/SbmDemoInstanceConsole.cs +++ b/SaBusMgrStandardBase/Base/Consoles/SbmDemoInstanceConsole.cs @@ -1,20 +1,11 @@ using Sarand.BusinessMgr.Net.Standard.Base.App; -using Sarand.BusinessMgr.Net.Standard.Base.Bus; -using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Data; -using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Security; -using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static Sarand.BusinessMgr.Net.Standard.Base.Core.ISbmDemoInstanceConsole; namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles { @@ -59,12 +50,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles /// /// Security Group codes - as set up during initialisation. /// - public String GetSecurityGroupCode(SecurityGroup group) + public String GetSecurityGroupCode(ISbmDemoInstanceConsole.SecurityGroup group) { switch (group) { - case SecurityGroup.Standard: return "Standard"; - case SecurityGroup.Super: return SaSecurityConsole.GroupCode_Super; + case ISbmDemoInstanceConsole.SecurityGroup.Standard: return "Standard"; + case ISbmDemoInstanceConsole.SecurityGroup.Super: return SaSecurityConsole.GroupCode_Super; } return ""; } diff --git a/SaBusMgrStandardBase/Base/Consoles/SbmSessionConsole-Transactions.cs b/SaBusMgrStandardBase/Base/Consoles/SbmSessionConsole-Transactions.cs index 4bf097e..9fd2024 100644 --- a/SaBusMgrStandardBase/Base/Consoles/SbmSessionConsole-Transactions.cs +++ b/SaBusMgrStandardBase/Base/Consoles/SbmSessionConsole-Transactions.cs @@ -162,15 +162,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles } // Set the minimum Id for transactions of the specified type. - public virtual bool SetMinTransactionId(SysId AffiliateId_Owner, SysId idAssoc, Sbm.TransactionType transTypes, long iId) + public virtual bool SetMinTransactionId(SysId AffiliateId_Owner, SysId idAssoc, Sbm.TransactionType transTypes, SysId id) { - bool set = false; - if (SbmGlobals.Application.GetBusMgrDatabase(SessionContext) != null) - { - string nextIdKey = GetTransactionNextIdKey(AffiliateId_Owner, idAssoc, transTypes); - // ToDo set = SbmGlobals.Database.SetMinNextId(nextIdKey, iId, false); - } - return set; + String nextIdKey = GetTransactionNextIdKey(AffiliateId_Owner, idAssoc, transTypes); + return Internals.BusMgrDatabase.SetMinNextId(nextIdKey, id, Internals.DbUpdateInfo, false); } // The implementation in this class will generate simple numeric values for the owner @@ -178,42 +173,65 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles public virtual string GetTransactionCreateRef (SysId AffiliateId_Owner, SysId idAssoc, Sbm.TransactionType transTypes) { - string Ref = ""; - if (SbmGlobals.Application.GetBusMgrDatabase(SessionContext) != null) - { - string NextIdKey = GetTransactionNextIdKey(AffiliateId_Owner, idAssoc, transTypes); - // ToDo long iRefNext = SbmGlobals.Database.GetNextId(NextIdKey, false); - // Ref = FormatTransactionCreateRef(AffiliateId_Owner, idAssoc, transTypes, iRefNext); - } - return Ref; + string NextIdKey = GetTransactionNextIdKey(AffiliateId_Owner, idAssoc, transTypes); + long transRefNext = SysId.ToLong(Internals.BusMgrDatabase.GetNextId(NextIdKey, Internals.DbUpdateInfo, false)); + return FormatTransactionCreateRef(AffiliateId_Owner, idAssoc, transTypes, transRefNext); } public virtual string FormatTransactionCreateRef - (SysId AffiliateId_Owner, SysId idAssoc, Sbm.TransactionType transTypes, long RefInt) + (SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transTypes, long transRefInt) { - string Ref = ""; - if (RefInt > 0) + string transRef = ""; + if (transRefInt > 0) { // Retrieve and validate the sequence padding length. - int SeqLen = Math.Max(1, Math.Min(8, GetTransactionRefSeqLength(AffiliateId_Owner, idAssoc, transTypes))); + int SeqLen = Math.Max(1, Math.Min(8, GetTransactionRefSeqLength(affiliateId_Owner, idAssoc, transTypes))); // Pad the sequence number. - //Ref = String(RefInt, SeqLen); + transRef = StringUtil.PadLeft(transRefInt.ToString(), SeqLen, '0'); // Add the reference prefix (max 5 chars) - string prefix = GetTransactionRefPrefix(AffiliateId_Owner, idAssoc, transTypes); - Ref = prefix.Left(5) + Ref; + string prefix = GetTransactionRefPrefix(affiliateId_Owner, idAssoc, transTypes); + transRef = prefix.Left(5) + transRef; } - return Ref; - } - - public virtual int GetTransactionRefSeqLength(SysId AffiliateId_Owner, SysId idAssoc, Sbm.TransactionType transTypes) - { - return 5; + return transRef; } //------------------------------------------------------------------- - /// Transaction reference prefix by type - public virtual string GetTransactionRefPrefix(SysId id, SysId idAssoc, Sbm.TransactionType transactionType) + // Properties that can be set in the Repository configuration. + + /// Lengt to which the numeric sequence part of the reference is padded with leading zeroes. + public virtual int GetTransactionRefSeqLength(SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transactionType) { + return InstanceConfig.GetTransactionRefSeqLength(affiliateId_Owner, idAssoc, transactionType, 5); + } + + /// Transaction reference prefix by type. + public virtual String GetTransactionRefPrefix(SysId affiliateId_Owner, SysId idAssoc, Sbm.TransactionType transactionType) + { + return InstanceConfig.GetTransactionRefPrefix(affiliateId_Owner, idAssoc, transactionType, GetDefaultTransactionRefPrefix(transactionType)); + } + + /// Default reference prefix by Transaction Type. + public virtual String GetDefaultTransactionRefPrefix(Sbm.TransactionType transactionType) + { + switch (transactionType) + { + case Sbm.TransactionType.Project: return "PRJ"; + case Sbm.TransactionType.SalesLead: return "SL"; + case Sbm.TransactionType.SalesQuote: return "SQ"; + case Sbm.TransactionType.ProformaSalesOrder: return "SOPr"; + case Sbm.TransactionType.SalesPO: return "SPO"; + case Sbm.TransactionType.SalesOrder: return "SO"; + case Sbm.TransactionType.SalesDispatch: return "SD"; + case Sbm.TransactionType.ProformaSalesInvoice: return "SIPr"; + case Sbm.TransactionType.SalesInvoice: return "SI"; + case Sbm.TransactionType.PurchaseQuote: return "PQ"; + case Sbm.TransactionType.ProformaPurchaseOrder: return "POPr"; + case Sbm.TransactionType.PurchaseSO: return "PSO"; + case Sbm.TransactionType.PurchaseOrder: return "PO"; + case Sbm.TransactionType.PurchaseDelivery: return "PD"; + case Sbm.TransactionType.ProformaPurchaseInvoice: return "PIPr"; + case Sbm.TransactionType.PurchaseInvoice: return "PI"; + } return ""; } diff --git a/SaBusMgrStandardBase/Base/Data/SbmRepositoryPopulationData.cs b/SaBusMgrStandardBase/Base/Data/SbmRepositoryPopulationData.cs index 4916a11..e1c3010 100644 --- a/SaBusMgrStandardBase/Base/Data/SbmRepositoryPopulationData.cs +++ b/SaBusMgrStandardBase/Base/Data/SbmRepositoryPopulationData.cs @@ -1,5 +1,6 @@ using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.ReferenceData; using System; using System.Collections.Generic; @@ -47,8 +48,15 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Data public String SecurityGroupCode { get; set; } } + public class BaseData + { + public SysId Id { get; set; } + public String Notes { get; set; } + public SaStatus Status { get; set; } + } + // Contacts. - public class AffiliateData + public class AffiliateData : BaseData { protected AffiliateData(Sbm.AffiliateType type) { this.Type = type; } public Sbm.AffiliateType Type { get; } @@ -63,6 +71,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Data Customer = new CustomerData() { Code = code }; } public void ClearCustomer() { Customer = null; } + public String CustomerCode { get { return Customer?.Code ?? ""; } set { if (Customer == null) { Customer = new CustomerData(); } Customer.Code = value; } } // Associations - Supplier. public SupplierData Supplier { get; private set; } @@ -71,6 +80,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Data Supplier = new SupplierData() { Code = code }; } public void ClearSupplier() { Supplier = null; } + public String SupplierCode { get { return Supplier?.Code ?? ""; } set { if (Supplier == null) { Supplier = new SupplierData(); } Supplier.Code = value; } } // Associations - Member. public MemberData Member { get; private set; } @@ -79,6 +89,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Data Member = new MemberData() { Code = code, Role = role }; } public void ClearMember() { Member = null; } + public String MemberCode { get { return Member?.Code ?? ""; } set { if (Member == null) { Member = new MemberData(); } Member.Code = value; } } + public String MemberRole { get { return Member?.Role ?? ""; } set { if (Member == null) { Member = new MemberData(); } Member.Role = value; } } } public class IndividualData : AffiliateData { @@ -114,7 +126,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Data } // Addresses. - public class AddressData + public class AddressData : BaseData { protected AddressData(Sbm.AddressType type) { @@ -131,7 +143,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Data } // Associations. - public class AssociationData + public class AssociationData : BaseData { protected AssociationData(Sbm.AssociationType type) { @@ -157,7 +169,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Data } // Commodities. - public class CommodityData + public class CommodityData : BaseData { protected CommodityData(Sbm.CommodityType type) { diff --git a/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Association-Util.cs b/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Association-Util.cs index 0010924..ce7362c 100644 --- a/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Association-Util.cs +++ b/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Association-Util.cs @@ -1,15 +1,10 @@ using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; -using Sarand.Net.Standard.Base.ReferenceData; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; -using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm; -using static Sarand.BusinessMgr.Net.Standard.Base.Data.SbmRepositoryPopulationData; namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr { diff --git a/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Association.cs b/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Association.cs index 23dcc14..24356c3 100644 --- a/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Association.cs +++ b/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Association.cs @@ -8,8 +8,6 @@ using Sarand.Net.Standard.Base.ReferenceData; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; -using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm; -using static Sarand.BusinessMgr.Net.Standard.Base.Data.SbmRepositoryPopulationData; namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr { @@ -118,6 +116,16 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr { ClearErrorState(); // Association properties. + if (errField.AffiliateIdOwner != SacsHierarchyItem.ValidValue.Ignore && !SysId.IsValid(data.AffiliateIdOwner)) + { + errField.AffiliateIdOwner = SacsHierarchyItem.ValidValue.Invalid; + return SetErrorState("Owner must be supplied"); + } + if (errField.AffiliateIdTarget != SacsHierarchyItem.ValidValue.Ignore && !SysId.IsValid(data.AffiliateIdTarget)) + { + errField.AffiliateIdTarget = SacsHierarchyItem.ValidValue.Invalid; + return SetErrorState("Target must be supplied"); + } if (errField.AssociationType != SacsHierarchyItem.ValidValue.Ignore && (short)data.AssociationType < 1) { if ((int)data.AssociationType < 1) diff --git a/SaBusMgrStandardBase/Base/Mgr/SbmTransactionMgr_Requirement.cs b/SaBusMgrStandardBase/Base/Mgr/SbmTransactionMgr_Requirement.cs index 1dde7c1..a518022 100644 --- a/SaBusMgrStandardBase/Base/Mgr/SbmTransactionMgr_Requirement.cs +++ b/SaBusMgrStandardBase/Base/Mgr/SbmTransactionMgr_Requirement.cs @@ -23,14 +23,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr public abstract bool CostColumnsAreAvailable(); public abstract bool SetTaxCode(SbmRequirement requirement, DateTime effective); // Calculate the requirement's values. - public abstract bool CalculateTotal(SbmRequirement.Data requirement); - public bool CalculateTotal(SbmRequirement requirement) - { - SbmRequirement.Data data = requirement.GetData(); - bool result = CalculateTotal(data); - requirement.SetData(data); - return result; - } + public abstract bool CalculateTotal(SbmRequirement requirement); // Requirement associated quantities. public abstract decimal GetRequirementQuantityDispatched(SysId requirementId, SysId transIdExclude); @@ -154,51 +147,51 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr } } // NB Seq, ReqntIdSource, Required, Started, Completed is optional. - if (errField.JobNumber != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.JobNumber, "job number", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_JobNumber), true)) + if (errField.JobNumber != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.JobNumber, "job number", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_JobNumber))) { errField.JobNumber = SacsHierarchyItem.ValidValue.Invalid; return false; } // NB AssIdSubcontract, CommodityId is optional. - if (errField.ProductCode != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.ProductCode, "product code", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_ProductCode), true)) + if (errField.ProductCode != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.ProductCode, "product code", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_ProductCode))) { errField.ProductCode = SacsHierarchyItem.ValidValue.Invalid; return false; } // NB AssetId is optional. - if (errField.DescBrief != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescBrief, "description", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_DescBrief), true)) + if (errField.DescBrief != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescBrief, "description", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_DescBrief))) { errField.DescBrief = SacsHierarchyItem.ValidValue.Invalid; return false; } - if (errField.DescIntro != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescIntro, "introduction", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_DescIntro), true)) + if (errField.DescIntro != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescIntro, "introduction", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_DescIntro))) { errField.DescIntro = SacsHierarchyItem.ValidValue.Invalid; return false; } - if (errField.DescOutline != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescOutline, "outline description", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_DescOutline), true)) + if (errField.DescOutline != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescOutline, "outline description", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_DescOutline))) { errField.DescOutline = SacsHierarchyItem.ValidValue.Invalid; return false; } - if (errField.DescDetail != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescDetail, "detailed description", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_DescDetail), true)) + if (errField.DescDetail != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.DescDetail, "detailed description", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_DescDetail))) { errField.DescDetail = SacsHierarchyItem.ValidValue.Invalid; return false; } // NB PromotionCode, Quantity, QuantityProd, UomId, Weight, UomIdWeight is optional. - if (errField.NominalCode != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.NominalCode, "nominal code", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_NominalCode), true)) + if (errField.NominalCode != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.NominalCode, "nominal code", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_NominalCode))) { errField.NominalCode = SacsHierarchyItem.ValidValue.Invalid; return false; } - if (errField.MaterialSourceCode != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.MaterialSourceCode, "material source", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_MaterialSourceCode), true)) + if (errField.MaterialSourceCode != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.MaterialSourceCode, "material source", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_MaterialSourceCode))) { errField.MaterialSourceCode = SacsHierarchyItem.ValidValue.Invalid; return false; } // NB AmountUnit > LocationIdStock is optional. - if (errField.Notes != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Notes, "notes", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_Notes), true)) + if (errField.Notes != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Notes, "notes", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Requirement_Notes))) { errField.Notes = SacsHierarchyItem.ValidValue.Invalid; return false; diff --git a/SaBusMgrStandardBase/Base/Mgr/SbmTransactionMgr_Transaction.cs b/SaBusMgrStandardBase/Base/Mgr/SbmTransactionMgr_Transaction.cs index d446712..5865c0b 100644 --- a/SaBusMgrStandardBase/Base/Mgr/SbmTransactionMgr_Transaction.cs +++ b/SaBusMgrStandardBase/Base/Mgr/SbmTransactionMgr_Transaction.cs @@ -19,13 +19,14 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr { //------------------------------------------------------------------- // Data members. - private static long maxTranNotesLength = -1; //------------------------------------------------------------------- // Utilities. public abstract bool TransactionIsReadOnly(SbmTransaction transaction); public abstract bool TransactionDetailsAreReadOnly(SbmTransaction transaction); + public abstract bool RefreshTransactionTotals(SbmTransaction transaction, IEnumerable requirements); + // Labour cost. public abstract decimal GetTransCostLabourRateHourDefault(); public abstract decimal GetTransCostLabourRateHour(SysId transactionId); @@ -35,7 +36,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr public abstract bool ChangeTransactionsAssociation(SbmTransaction transaction, SysId associationId); /// - /// Refresh associatde data: + /// Refresh associated data: /// - Refresh Stock Allocations. /// - /// - @@ -197,7 +198,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr } // References. - if (errField.Ref != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.RefExt, "external", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Ref))) + // NB Reference only validate for existing transactions as the value is populated and validated after this method for new transactions. + if (errField.Ref != SacsHierarchyItem.ValidValue.Ignore && SysId.IsValid(data.Id) && !IsValidValue(data.Ref, "Ref", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Ref), true)) { errField.Ref = SacsHierarchyItem.ValidValue.Invalid; return false; @@ -330,21 +332,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr return false; } - // Establish notes length for validation. - if (maxTranNotesLength < 1) - { - // Standard notes length: - maxTranNotesLength = (int)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Notes); - // Check if this database allows longer notes: - ISacsDatabase db = SbmGlobals.Application.GetBusMgrDatabase(SessionContext); - if (db != null) - { - DbDfnTable tableDfn = db.GetTableDfn(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Transaction, false)); - DbDfnColumn columnDfn = tableDfn.Columns.Find(item => item.Name.EqualsCI(SbmDbDfn.GetColumnName(SbmDbDfn.ColumnIdx.Transaction_Notes, false))); - if (columnDfn != null) maxTranNotesLength = Math.Max(maxTranNotesLength, columnDfn.Size); - } - } - if (errField.Notes != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Notes, "notes", maxTranNotesLength)) + // Common properties. + if (errField.Notes != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Notes, "notes", (int)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Notes))) { errField.Notes = SacsHierarchyItem.ValidValue.Invalid; return false; @@ -374,29 +363,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr if (!DateUtil.IsValid(data.Closed)) data.Closed = DateTime.Today; } - - // Populate reference if not already done. - if (StringUtil.IsEmpty(data.Ref) && SessionConsole.TransactionAssignRefMethod(data.TransactionType) != SbmSessionConsole.AssignTransRefMethod.Manual) - { - // Retrieve the next available transaction reference. - String sRef = SessionConsole.GetTransactionCreateRef(data.AffiliateIdOwner, data.AssociationId, data.TransactionType); - // Check that another transaction doesn't already exist with this reference. - SbmTransaction transRef = GetTransactionByOwnerTypeRef(data.AffiliateIdOwner, data.TransactionType, sRef); - if (transRef == null) - data.Ref = sRef; - else - { - String tranTypeDesc = TransactionTypes.GetDescForType(data.TransactionType); - if (StringUtil.IsEmpty(tranTypeDesc)) tranTypeDesc = "Transaction"; - SetErrorState("Another " + tranTypeDesc + " already exists with this reference."); - } - if (HasErrorState()) return false; - } - if (errField.Ref != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Ref, "Ref", (long)Internals.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Ref), true)) - { - errField.Ref = SacsHierarchyItem.ValidValue.Invalid; - return false; - } return true; } diff --git a/SaBusMgrStandardBase/Resources/Email/Security/sbm-email-demo-account-register.html b/SaBusMgrStandardBase/Resources/Email/Security/sbm-email-demo-account-register.html index 73dd8fe..9b0571a 100644 --- a/SaBusMgrStandardBase/Resources/Email/Security/sbm-email-demo-account-register.html +++ b/SaBusMgrStandardBase/Resources/Email/Security/sbm-email-demo-account-register.html @@ -7,15 +7,15 @@ [#Email.Header] -
-
-
Demo Account Registration
+ diff --git a/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategorySelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategorySelect.cshtml index 1f3d7c5..46f9bdb 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategorySelect.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategorySelect.cshtml @@ -31,7 +31,7 @@ @* AssetCategory filter - name etc. *@
@Localiser["label.search"]
- @Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" }) + @Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml index 1ca7a97..8de92e4 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml @@ -55,7 +55,7 @@ @* Association filter - name etc. *@
@Localiser["label.search"]
- @Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" }) + @Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml index 40c883e..734b121 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml @@ -6,6 +6,7 @@ // Ensure view is only included once in page. if (!Model.RegisterView("Views/Association/Panel-AssociationSelect")) return; Model.AdditionalFiles_JS.Add("js/sbm-assoc.js"); + Model_Association ModelAssociation = Model as Model_Association; } + +@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmTransactionId", @class = "sbm-form" })) +{ + @Html.Hidden("Transaction.Id", "", new { @id = "", @class = "TransactionId" }) + @Html.Hidden("Transaction.DataGroups", "", new { @id = "", @class = "TransactionDataGroups" }) +} + +
+ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmTransaction", @class = "sbm-form", @onSubmit = "return false;" })) + { + @Html.Hidden("Transaction.Id", "", new { @id = "", @class = "TransactionId sbm-input" }) + @Html.Hidden("Transaction.Exists", "", new { @id = "", @class = "TransactionExists sbm-input" }) +
+ + @* Association *@ +
+
+
+
+ +
+
+
+
+
+ @Html.Hidden("Transaction.AssociationId", "", new { @id = "", @class = "TransactionAssociationId sbm-input" }) + +
+
+
+
+
+
+
+
+
+ +
+
+ + @* Reference *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("Transaction.Reference", "", new { @id = "ifTransactionReference", @class = "TransactionReference sbm-input upper sbm-auto-val", @readonly = true, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Ref) }) +
+
+
+
+
+ +
+
+ + @* External Reference *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("Transaction.TransactionReferenceExt", "", new { @id = "ifTransactionReferenceExt", @class = "TransactionReferenceExt sbm-input upper sbm-auto-val" }) +
+
+
+
+
+ +
+
+ + @* Narrative *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("Transaction.DescBrief", "", new { @id = "ifTransactionDesc", @class = "TransactionDesc sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescBrief) }) +
+
+
+
+
+ +
+
+ + @* Transaction status *@ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+ + @* Contact *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("Transaction.ContactName", "", new { @id = "ifTransactionContactName", @class = "TransactionContactName sbm-input sbm-auto-val", @maxlen = Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ContactName) }) +
+
+
+
+
+ +
+
+ +
+
+ + @* Raiased date *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("Transaction.Raised", "", new { @id = "ifTransactionRaised", @class = "TransactionRaised sbm-input sbm-calendar sbm-auto-val", @maxlen = 10 }) +
+
+
+
+
+ +
+
+ + @* Raised by *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("Transaction.RaisedBy", "", new { @id = "ifTransactionRaisedBy", @class = "TransactionRaisedBy sbm-input sbm-auto-val", @maxlen = Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_RaisedBy) }) +
+
+
+
+
+ +
+
+ +
+
+ + @* In Progress date *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("Transaction.InProgress", "", new { @id = "ifTransactionInProgress", @class = "TransactionInProgress sbm-input sbm-calendar sbm-auto-val", @maxlen = 10 }) +
+
+
+
+
+ +
+
+ + @* Raised by *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("Transaction.Closed", "", new { @id = "ifTransactionClosed", @class = "TransactionClosed sbm-input sbm-calendar sbm-auto-val", @maxlen = 10 }) +
+
+
+
+
+ +
+
+ + @* Transaction Notes *@ +
+
+
+
+ +
+
+
+
+ @Html.TextArea("Transaction.Notes", "", new { @id = "ifTransactionNotes", @class = "TransactionNotes sbm-textarea sbm-auto-val", @rows = "3", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Notes) }) +
+
+
+
+
+ + } + +
+ + +@* Association panels. *@ + + diff --git a/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionList.cshtml b/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionList.cshtml new file mode 100644 index 0000000..14e7c9f --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionList.cshtml @@ -0,0 +1,86 @@ +@* View is decoupled from Transaction model as it may be included in other views, eg. Associations. *@ +@model SbmModel_Portal +@inject SbmLocaliser Localiser +@{ + /* Transaction - List panel */ + /* NB Can potentially appear more than once on a page. */ +} + +@* Item list *@ +
+ + + + + + + + + @* Status dates. *@ + + + + + @if (Model.UserCanViewFinancials()) + { + + + } + + + + + + + +
@Localiser["label.reference"]@Localiser["label.type"]@Localiser["label.association"]@Localiser["label.narrative"]@Localiser["label.items"]@Localiser["label.raised"]@Localiser["label.required"]@Localiser["label.in.progress"]@Localiser["label.closed"]@Localiser["label.amount.net"]@Localiser["label.amount.tax"]@Localiser["label.notes"]@Localiser["label.status"]
+
+ +@* Element templates *@ +
+ + @* List burger dropdown template - ul is ignored *@ +
    +
  • XXX
  • +
+ + @* Item row template - table is ignored. *@ + + + + + + + + @* Status dates. *@ + + + + + @if (Model.UserCanViewFinancials()) + { + + + } + + + + +
+
+ @* Burger menu *@ + +
+
+ + @* Item burger dropdown template - ul is ignored *@ +
    +
  • XXX
  • +
+ +
\ No newline at end of file diff --git a/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionMaintain.cshtml b/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionMaintain.cshtml new file mode 100644 index 0000000..9e5cf7c --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionMaintain.cshtml @@ -0,0 +1,85 @@ +@* View is decoupled from Transaction model as it may be included in other views, eg. Associations. *@ +@model SbmModel_Portal +@inject SbmLocaliser Localiser +@{ + /* Transaction - Maintain panel */ + // Ensure view is only included once in page. + if (!Model.RegisterView("Views/Transaction/Panel-TransactionMaintain")) return; + Model.AdditionalFiles_JS.Add("js/sbm-trn.js"); + Model_Transaction ModelTransaction = Model as Model_Transaction; +} + +
+ + + +
+ + @* Filter form - wrap header to include paging controls. *@ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmTransactionFilter sbm-form", @onSubmit = "return false;" })) + { + @Html.Hidden("Filter.Mode", Model_Transaction.ViewMode.Maintain, new { @id = "" }) + + @* Header - Page caption, paging controls, actions. *@ +
+
+
+
@Localiser["label.transactions"]
+
+ @* Burger menu *@ + +
+
+
+ + @* Filter Panel *@ +
+
+ @if (ModelTransaction?.GetFilterTransactionType() > 0) + { + @Html.Hidden("Filter.TransactionType", ModelTransaction.Filter.TransactionType, new { @id = "", @class = "FilterTransactionType" }) + + } + else + { +
+ @* Transaction Category *@ +
@Localiser["label.type"]
+
+ @Html.DropDownList("Filter.TransactionType", Model.GetTransactionTypeCodesForFilterDropdown(), null, new { @id = "", @class = "FilterTransactionType sbm-select" }) +
+
+ } +
+ @* Transaction Status *@ +
@Localiser["label.status"]
+
+ @Html.DropDownList("Filter.TransactionStatusCat", ModelTransaction?.GetTransactionStatusCatsForFilterDropdown() ?? Model.GetEmptyListForSelect(), null, new { @id = "", @class = "FilterTransactionStatusCat sbm-select" }) +
+
+
+ @* Transaction filter - code, description etc *@ +
@Localiser["label.search"]
+
+ @Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" }) +
+
+
+
+
+
+ } + + + +
+ + + +
diff --git a/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionSelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionSelect.cshtml new file mode 100644 index 0000000..ae91fbb --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Transaction/Panel-TransactionSelect.cshtml @@ -0,0 +1,43 @@ +@* View is decoupled from Transaction model as it may be included in other views, eg. Associations. *@ +@model SbmModel_Portal +@inject SbmLocaliser Localiser +@{ + /* Transaction - Select panel */ + // Ensure view is only included once in page. + if (!Model.RegisterView("Views/Transaction/Panel-TransactionSelect")) return; + Model.AdditionalFiles_JS.Add("js/sbm-trn.js"); +} + + + +
+ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmTransactionFilter sbm-form", @onSubmit = "return false;" })) + { + @Html.Hidden("Filter.Mode", Model_Transaction.ViewMode.Search, new { @id = "" }) + + @* Filter Panel *@ +
+
+
+ @* Transaction type *@ +
@Localiser["label.type"]
+
+ @Html.DropDownList("Filter.TransactionType", Model.GetTransactionTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterTransactionType sbm-select" }) +
+
+
+ @* Transaction filter - name etc. *@ +
@Localiser["label.search"]
+
+ @Html.TextBox("Filter.Search", "", new { @type = "search", @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" }) +
+
+
+
+ } + + + +
diff --git a/SaBusinessMgrCoreWebPortal/Views/Vehicles/Vehicle/Index.cshtml b/SaBusinessMgrCoreWebPortal/Views/Vehicles/Vehicle/Index.cshtml index 4d87466..baa1444 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Vehicles/Vehicle/Index.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Vehicles/Vehicle/Index.cshtml @@ -43,7 +43,7 @@
@Localiser["label.search"]
- @Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" }) + @Html.TextBoxFor(model => model.Filter.Search, new { @type = "search", @id = "", @class = "FilterSearch", @maxlength = "32" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Vehicles/VehicleClass/Index.cshtml b/SaBusinessMgrCoreWebPortal/Views/Vehicles/VehicleClass/Index.cshtml index a65866f..cfa6535 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Vehicles/VehicleClass/Index.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Vehicles/VehicleClass/Index.cshtml @@ -42,7 +42,7 @@
@Localiser["label.search"]
- @Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" }) + @Html.TextBoxFor(model => model.Filter.Search, new { @type = "search", @id = "", @class = "FilterSearch", @maxlength = "32" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/_ViewImports.cshtml b/SaBusinessMgrCoreWebPortal/Views/_ViewImports.cshtml index 33e29e9..4d5c21a 100644 --- a/SaBusinessMgrCoreWebPortal/Views/_ViewImports.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/_ViewImports.cshtml @@ -6,6 +6,7 @@ @using Sarand.BusinessMgr.Web.Portal.Models.Security @using Sarand.BusinessMgr.Web.Portal.Models.Contacts @using Sarand.BusinessMgr.Web.Portal.Models.Commodities +@using Sarand.BusinessMgr.Web.Portal.Models.Transactions @using Sarand.BusinessMgr.Web.Portal.Models.Assets @using Sarand.BusinessMgr.Web.Portal.Models.Vehicles @using Sarand.BusinessMgr.Web.Portal.Models.Codes diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-cols.css b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-cols.css index 3198154..11cef10 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-cols.css +++ b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-cols.css @@ -33,12 +33,12 @@ .Contacts .sbm-panel-data { - --color-panel-data: var(--color-ForestGreen); + --color-panel-data: var(--color-KellyGreen); } .Associations .sbm-panel-data { - --color-panel-data: var(--color-Iris); + --color-panel-data: var(--color-ForestGreen); } .Commodities .sbm-panel-data @@ -56,6 +56,11 @@ --color-panel-data: var(--color-Iris); } +.Transactions .sbm-panel-data +{ + --color-panel-data: var(--color-RoyalBlue); +} + /* Dialogs */ :root @@ -70,12 +75,12 @@ .ui-dialog.sbm-Contact { - --color-dialog: var(--color-ForestGreen); + --color-dialog: var(--color-KellyGreen); } .ui-dialog.sbm-Association { - --color-dialog: var(--color-Iris); + --color-dialog: var(--color-ForestGreen); } .ui-dialog.sbm-Commodity @@ -93,4 +98,9 @@ --color-dialog: var(--color-Iris); } +.ui-dialog.sbm-Transaction +{ + --color-dialog: var(--color-RoyalBlue); +} + /* The End */ diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-data.css b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-data.css index f1de878..882a72d 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-data.css +++ b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-data.css @@ -72,6 +72,8 @@ } .sbm-panel-filter input[type="text"], +.sbm-panel-filter input[type="email"], +.sbm-panel-filter input[type="search"], .sbm-panel-filter textarea, .sbm-panel-filter select { @@ -100,6 +102,8 @@ } .sbm-panel-data .sbm-content input[type="text"], +.sbm-panel-data .sbm-content input[type="email"], +.sbm-panel-data .sbm-content input[type="search"], .sbm-panel-data .sbm-content select { min-width: 75%; diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-main.css b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-main.css index 94dfc07..c788b5d 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-main.css +++ b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-main.css @@ -412,13 +412,13 @@ a:focus { border-color: var(--color-dialog); margin-top: 0; - padding: .2em 1em .2em .5em; + padding: .25em .5em .25em .5em; } .ui-dialog .ui-dialog-buttonpane button { min-width: 80px; - margin: .5em .25em .5em .5em; + margin: .2em .25em .2em 1em; color: #fff; background-color: var(--color-dialog); border-color: var(--color-dialog); diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset-cat.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset-cat.js index 6fec4c3..2ad31c1 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset-cat.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset-cat.js @@ -211,8 +211,9 @@ $item = ac.getItemTemplate(env); $('table tbody', env.$pnl.table).prepend($item).show(); } + ac.populateItem(env, $item, item); + sbm.configureItemTable(env.data.cfgList, env.$pnl.table); } - ac.populateItem(env, $item, item); } //-------------------------------------------------------------- diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset.js index 70dc008..3f6972b 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset.js @@ -231,8 +231,9 @@ $item = as.getItemTemplate(env); $('table tbody', env.$pnl.table).prepend($item).show(); } + as.populateItem(env, $item, item); + sbm.configureItemTable(env.data.cfgList, env.$pnl.table); } - as.populateItem(env, $item, item); } //-------------------------------------------------------------- diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-assoc.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-assoc.js index f4c479d..c7a9722 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-assoc.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-assoc.js @@ -10,21 +10,11 @@ //-------------------------------------------------------------- as.refreshConfig = function (env, delay) { - env.ajax.refreshConfig = env.ajax.refreshConfig || { url: sbm.url.base + 'Association/Ajax/Config', formSel: env.$frm.filter, callbackFn: function (response) { as.doRefreshConfig(env, response); } }; - sbm.doAjaxRequest(env.ajax.refreshConfig, delay || 50); + sbm.doAjaxRequest(env.ajax.refreshConfig = env.ajax.refreshConfig || { url: sbm.url.base + 'Association/Ajax/Config', formSel: env.$frm.filter, callbackFn: function (response) { as.storeConfig(env, response); } }, delay || 50); } - as.doRefreshConfig = function (env, response) + as.storeConfig = function (env, response) { - //sbm.debug('doRefreshConfig', env, response); - if (!response.success) return; - // Config. - env.mode = response.mode; - env.config = response.config; - env.configCust = response.configCust; - env.configSupp = response.configSupp; - env.data.associationTypes = response.associationTypes; - env.data.statuses = response.statuses; - env.data.defaultStatusCode = response.defaultStatusCode; + Object.assign(env.data, response.data); } //-------------------------------------------------------------- @@ -36,8 +26,7 @@ env.$pnl.table.find('tbody tr').remove(); env.$pnl.msgs.hide().empty().append($('
' + sbm.msg.dataQuerying + '
')).fadeIn(200); } - env.ajax.refreshResults = env.ajax.refreshResults || { url: sbm.url.base + 'Association/Ajax/List', formSel: env.$frm.filter, callbackFn: function (response) { as.doRefreshResults(env, response); } }; - sbm.doAjaxRequest(env.ajax.refreshResults, delay || 50); + sbm.doAjaxRequest(env.ajax.refreshResults = env.ajax.refreshResults || { url: sbm.url.base + 'Association/Ajax/List', formSel: env.$frm.filter, callbackFn: function (response) { as.doRefreshResults(env, response); } }, delay || 50); as.awaitingRefreshResponse = true; } as.doRefreshResults = function (env, response) @@ -48,8 +37,10 @@ let $table = $('table', env.$pnl.table).find('tbody tr').remove().end(); sbm.refreshPaging(response, env.$frm.filter, function () { as.refreshResults(env); }); if (!response.success) return; - as.doRefreshConfig(env, response); - if (response.caption) env.$pnl.items.find('.sbm-panel-caption').text(response.caption); + as.storeConfig(env, response); + let cfg = env.data.cfgList; + env.mode = response.mode; + if (cfg.caption) env.$pnl.items.find('.sbm-panel-caption').text(cfg.caption); // Menu. if (env.$pnl.bgr.length) @@ -57,10 +48,10 @@ env.$pnl.bgr.invisible(); env.$pnl.mnu.empty(); env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.refresh, function () { as.refreshResults(env); }, 'sbm-refresh')); - if (env.config.action.allow.createCust) - env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.createCust, function () { as.createItem(env, env.configCust, sbm.lbl.createCust); }, 'sbm-add')); - if (env.config.action.allow.createSupp) - env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.createSupp, function () { as.createItem(env, env.configSupp, sbm.lbl.createSupp); }, 'sbm-add')); + if (env.data.cfgList.action.allow.createCust) + env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.createCust, function () { as.createItem(env, env.data.cfgCust, sbm.lbl.createCust); }, 'sbm-add')); + if (env.data.cfgList.action.allow.createSupp) + env.$pnl.mnu.append(as.getFilterMenuOption(env, sbm.lbl.createSupp, function () { as.createItem(env, env.data.cfgSupp, sbm.lbl.createSupp); }, 'sbm-add')); env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length); } @@ -68,15 +59,15 @@ var items = response.associations || []; if (!items.length) return env.$pnl.msgs.append($('
' + sbm.msg.dataNoneFound + '
')).fadeIn(500); - for (let itemIdx = 0; itemIdx < items.length; itemIdx++) - $table.append(as.populateItem(env, as.getItemTemplate(env), items[itemIdx])); - sbm.configureItemTable(env.config, $table); + for (const item of items) + $table.append(as.populateItem(env, as.getItemTemplate(env), item)); + sbm.configureItemTable(env.data.cfgList, $table); } as.populateItem = function (env, $item, item) { if (!item) return $item; $item.prop('id', as.getItemId(item)); - let cfg = env.config; + let cfg = env.data.cfgList; sbm.populateItemValues(cfg, $item, item.field.value); let prefix = cfg.column.prefix; if (!env.mode.search) @@ -140,7 +131,7 @@ as.clearItem(env, cfg); let prefix = cfg.field.prefix; let $ctrls = $('.sbm-input,.sbm-textarea,.sbm-select', env.$frm.item); - if (cfg.type) sbm.selectOrAdd($ctrls.filter('.AssociationType'), cfg.type.code, cfg.type.desc) + if (cfg.type) sbm.populateSelectCodeDesc('#cbAssociationType', [{ code: cfg.type.code, desc: cfg.type.desc }]) env.$ctrl.targetActions.filter('.AssocTargetSearch').show(); $ctrls.filter('.AssociationTarget').off('dblclick').on('dblclick', function () { as.selectTarget(env); }); $ctrls.filter('.AssociationStatus').val(env.data.defaultStatusCode); @@ -178,7 +169,7 @@ //sbm.debug('onSelectTarget', env, item); let $ctrls = $('.sbm-input,.sbm-textarea,.sbm-select', env.$frm.item); $ctrls.filter('.AssociationTargetId').val(item.id); - $ctrls.filter('.AssociationTarget').val(item.Name); + $ctrls.filter('.AssociationTarget').val(item.name); } as.editTarget = function (env) { @@ -200,8 +191,7 @@ { let $frm = env.$frm.itemId; $('.AssociationId', $frm).val(id); - env.ajax.updateItem = env.ajax.updateItem || { url: sbm.url.base + 'Association/Ajax/GetItem', formSel: $frm, callbackFn: function (response) { as.onUpdateItem(env, response); } }; - sbm.doAjaxRequest(env.ajax.updateItem, 50); + sbm.doAjaxRequest(env.ajax.updateItem = env.ajax.updateItem || { url: sbm.url.base + 'Association/Ajax/GetItem', formSel: $frm, callbackFn: function (response) { as.onUpdateItem(env, response); } }, 50); } as.onUpdateItem = function (env, response) { @@ -228,8 +218,7 @@ //-------------------------------------------------------------- as.storeItem = function (env) { - env.ajax.storeItem = env.ajax.storeItem || { url: sbm.url.base + 'Association/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { as.onStoreItem(env, response); } }; - sbm.doAjaxRequest(env.ajax.storeItem, 50); + sbm.doAjaxRequest(env.ajax.storeItem = env.ajax.storeItem || { url: sbm.url.base + 'Association/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { as.onStoreItem(env, response); } }, 50); } as.onStoreItem = function (env, response) { @@ -252,6 +241,7 @@ $('table tbody', env.$pnl.table).prepend($item).show(); } as.populateItem(env, $item, item); + sbm.configureItemTable(env.data.cfgList, env.$pnl.table); } } @@ -280,11 +270,12 @@ sbm.fn.selectAssociation = function (prm) { let env = as.env.select; - //sbm.debug('listAssociations', env, prm); + //sbm.debug('selectAssociation', env, prm); env.prmSelect = prm; let $frm = env.$frm.filter; $frm.find('.FilterOwnerId,.FilterTargetId').val(''); - $frm.find('.FilterContactType').val(prm.type || ''); + env.$frm.filter.find('.sbm-input.FilterAssociationType').val(prm.type); + env.$ctrl.filterAssocType.val(prm.type || '').prop('disabled', env.$ctrl.filterAssocType.val()); $frm.find('.FilterSearch').val(prm.search || ''); env.$pnl.table.find('tbody tr').remove(); let $dlg = env.$dlg.select; @@ -300,7 +291,7 @@ //sbm.debug('selectItemRow', env, $item, item); env.$pnl.table.find('tr').removeClass('sbm-sel'); $item.addClass('sbm-sel'); - env.prmSelect.item = item; + env.prmSelect.item = { id: item.id, name: item.field.value.Target }; } as.selectItem = function (env) { @@ -324,7 +315,8 @@ env.$pnl.tmpls = env.$pnl.items.find('.sbm-panel-item-template'); env.$frm.filter = env.$pnl.items.find('.frmAssociationFilter'); - env.$frm.filter.on('input', '.FilterSearch', function () { as.refreshResults(env, 250); }).on('change', '.FilterAssociationType', function () { as.refreshResults(env, 50); }); + env.$frm.filter.on('input', '.FilterSearch', function () { as.refreshResults(env, 250); }); + env.$ctrl.filterAssocType = env.$frm.filter.find('.sbm-select.FilterAssociationType').on('change', function () { env.$frm.filter.find('.sbm-input.FilterAssociationType').val(env.$frm.filter.find('.sbm-select.FilterAssociationType').val()); as.refreshResults(env, 50); }); var opt = sbm.dlgOpts(); opt.dialogClass += " sbm-Association"; env.$dlg.item = $('#dlgAssociation').dialog(opt); diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-commodity.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-cmd.js similarity index 96% rename from SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-commodity.js rename to SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-cmd.js index b48682c..b7741ca 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-commodity.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-cmd.js @@ -17,9 +17,6 @@ { //sbm.debug('doRefreshConfig', env, response); if (!response.success) return; - // Config. - env.config = response.config; - env.configItemNew = response.configItemNew; Object.assign(env.data, response.data); } @@ -53,7 +50,7 @@ env.$pnl.bgr.invisible(); env.$pnl.mnu.empty(); env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.refresh, function () { co.refreshResults(env); }, 'sbm-refresh')); - if (env.config.action.allow.create) env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.configItemNew); }, 'sbm-add')); + if (env.data.cfgList.action.allow.create) env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.data.cfgItemNew); }, 'sbm-add')); env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length); } @@ -63,12 +60,13 @@ return env.$pnl.msgs.append($('
' + sbm.msg.dataNoneFound + '
')).fadeIn(500); for (const item of items) $table.append(co.populateItem(env, co.getItemTemplate(env), item)); + sbm.configureItemTable(env.data.cfgList, $table); } co.populateItem = function (env, $item, item) { if (!item) return $item; $item.prop('id', co.getItemId(item)); - let cfg = env.config; + let cfg = env.data.cfgList; if (cfg) sbm.populateItemValues(cfg, $item, item.field.value); let prefix = cfg.column.prefix; $('.' + prefix + 'Status', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase()); @@ -253,6 +251,7 @@ $('table tbody', env.$pnl.table).prepend($item).show(); } co.populateItem(env, $item, item); + sbm.configureItemTable(env.data.cfgList, env.$pnl.table); } } @@ -340,7 +339,7 @@ co.env.maint = co.initEnv('.sbm-panel.Commodities'); if (co.env.maint.$pnl.items.length) { - $('body').on('keydown', function (e) { let env = co.env.maint; if (e.which == 45/*Insert*/ && env.config.action.allow.create) co.createItem(env, env.configItemNew); }); + $('body').on('keydown', function (e) { let env = co.env.maint; if (e.which == 45/*Insert*/ && env.data.cfgList.action.allow.create) co.createItem(env, env.data.cfgItemNew); }); setTimeout(function () { co.refreshResults(co.env.maint); }, 250); } co.env.select = co.initEnv('#dlgCommoditySelect'); diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-contact.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-contact.js index 2b077b3..b40f504 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-contact.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-contact.js @@ -69,8 +69,8 @@ var items = response.contacts || []; if (!items.length) return env.$pnl.msgs.append($('
' + sbm.msg.dataNoneFound + '
')).fadeIn(500); - for (let itemIdx = 0; itemIdx < items.length; itemIdx++) - $table.append(co.populateItem(env, co.getItemTemplate(env), items[itemIdx])); + for (const item of items) + $table.append(co.populateItem(env, co.getItemTemplate(env), item)); sbm.configureItemTable(env.config, $table); } co.populateItem = function (env, $item, item) @@ -223,6 +223,7 @@ $('table tbody', env.$pnl.table).prepend($item).show(); } co.populateItem(env, $item, item); + sbm.configureItemTable(env.data.cfgList, env.$pnl.table); } } @@ -252,7 +253,7 @@ //sbm.debug('selectItemRow', env, $item, item); env.$pnl.table.find('tr').removeClass('sbm-sel'); $item.addClass('sbm-sel'); - env.prmSelect.item = item; + env.prmSelect.item = { id: item.id, name: item.name }; } co.selectItem = function (env) { diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-main.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-main.js index 57cba24..4635a1c 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-main.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-main.js @@ -170,8 +170,8 @@ sbm.clearItemForm = function ($frm) { sbm.clearControlErrors($frm); - $('.sbm-input,.sbm-textarea,.sbm-select', $frm).val('').prop('readonly', false).prop('disabled', false); - $('.sbm-checkbox', $frm).prop('readonly', false).prop('disabled', false).removeAttr('checked'); + $frm.find('.sbm-input,.sbm-textarea,.sbm-select').val('').prop('readonly', false).prop('disabled', false); + $frm.find('.sbm-checkbox').prop('readonly', false).prop('disabled', false).removeAttr('checked'); } sbm.configureItemControls = function (cfg, $frm) { @@ -179,8 +179,8 @@ let fld = cfg.field || {}; let $ctrl = $('.sbm-form-control', $frm).show(); for (var name in fld.label || {}) { /* ... */ }; - (fld.hide || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).hide().find('.sbm-input,.sbm-textarea,.sbm-select,.sbm-checkbox').prop('disabled', true); }); - (fld.readonly || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).find('.sbm-input,.sbm.textarea,.sbm-select,.sbm-checkbox').prop('readonly', true).prop('disabled', true); }); + (fld.hide || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).hide().find('.sbm-input,.sbm-textarea,.sbm-select,.sbm-checkbox').filter('.sbm-auto-val').prop('disabled', true); }); + (fld.readonly || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).find('.sbm-input,.sbm.textarea,.sbm-select,.sbm-checkbox').filter('.sbm-auto-val').prop('readonly', true).prop('disabled', true); }); } sbm.populateFormValues = function (cfg, $frm, val) { diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-trn.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-trn.js new file mode 100644 index 0000000..2607a6c --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-trn.js @@ -0,0 +1,321 @@ +/* + * Transaction page scripts. + */ + +(function (win, doc, undef) +{ + "use strict"; + let co = sbm.mdl.Transactions = { env: {} }; + + //-------------------------------------------------------------- + co.refreshConfig = function (env, delay) + { + sbm.doAjaxRequest(env.ajax.refreshConfig = env.ajax.refreshConfig || { url: sbm.url.base + 'Transaction/Ajax/Config', formSel: env.$frm.filter, callbackFn: function (response) { co.storeConfig(env, response); } }, delay || 50); + } + co.storeConfig = function (env, response) + { + Object.assign(env.data, response.data); + } + + //-------------------------------------------------------------- + co.refreshItems = function (env, delay) + { + if (!co.awaitingRefreshResponse) + { + env.$pnl.bgr.invisible(); + env.$pnl.table.find('tbody tr').remove(); + env.$pnl.msgs.hide().empty().append($('
' + sbm.msg.dataQuerying + '
')).fadeIn(200); + } + sbm.doAjaxRequest(env.ajax.refreshResults = env.ajax.refreshResults || { url: sbm.url.base + 'Transaction/Ajax/List', formSel: env.$frm.filter, callbackFn: function (response) { co.displayItems(env, response); } }, delay || 50); + co.awaitingRefreshResponse = true; + } + co.displayItems = function (env, response) + { + //sbm.debug('doRefreshResults', env, response); + delete co.awaitingRefreshResponse; + env.$pnl.msgs.hide().empty(); + let $table = $('table', env.$pnl.table).find('tbody tr').remove().end(); + sbm.refreshPaging(response, env.$frm.filter, function () { co.refreshItems(env); }); + if (!response.success) return; + co.storeConfig(env, response); + let cfg = env.data.cfgList; + env.mode = response.mode; + if (cfg.caption) env.$pnl.items.find('.sbm-panel-caption').text(cfg.caption); + + // Menu. + if (env.$pnl.bgr.length) + { + env.$pnl.bgr.invisible(); + env.$pnl.mnu.empty(); + env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.refresh, function () { co.refreshItems(env); }, 'sbm-refresh')); + if (cfg.action.allow.create) env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.data.cfgItemNew); }, 'sbm-add')); + env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length); + } + + // Items. + var items = response.transactions || []; + if (!items.length) + return env.$pnl.msgs.append($('
' + sbm.msg.dataNoneFound + '
')).fadeIn(500); + for (const item of items) + $table.append(co.populateItem(env, co.getItemTemplate(env), item)); + sbm.configureItemTable(cfg, $table); + } + co.populateItem = function (env, $item, item) + { + if (!item) return $item; + $item.prop('id', co.getItemId(item)); + let cfg = env.data.cfgList; + if (cfg) sbm.populateItemValues(cfg, $item, item.field.value); + let prefix = cfg.column.prefix; + $('.' + prefix + 'Status', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase()); + if (!env.mode.search) + { + // Actions. + var $bgr = $('.sbm-burger', $item).hide(); + let $mnu = $('ul.sbm-dropdown-menu', $bgr).empty(); + if (!item.deleted) + { + let fnUpd = function () { co.updateItem(env, item.id) }; + $mnu.append(co.getItemMenuOption(env, sbm.lbl.edit, fnUpd, 'sbm-edit')); + $('.TransactionCode,.TransactionDesc', $item).off('click').on('click', fnUpd).addClass('sbm-action-text'); + $item.off('dblclick').on('dblclick', fnUpd); + } + $bgr.toggle(!!$('.sbm-dropdown-item', $mnu).length); + } + else + { + $item.off('click').on('click', function () { co.selectItemRow(env, $item, item); }); + $item.off('dblclick').on('dblclick', function () { co.selectItem(env); }); + } + return $item; + } + co.getItemId = function (item) + { + return 'Cmd_' + (item || {}).id; + } + + //-------------------------------------------------------------- + co.getFilterDropdownTemplate = function (env) + { + return $('.sbm-dropdown-menu.TransactionList li.sbm-dropdown-item', env.$pnl.tmpl).clone(); + } + co.getItemTemplate = function (env) + { + return $('table tr.sbm-row-item.Transaction', env.$pnl.tmpl).clone(); + } + co.getItemDropdownTemplate = function (env) + { + return $('.sbm-dropdown-menu.Transaction li.sbm-dropdown-item', env.$pnl.tmpl).clone(); + } + + //-------------------------------------------------------------- + co.getFilterMenuOption = function (env, lbl, fn, cls) + { + return co.getMenuOption(co.getFilterDropdownTemplate(env), lbl, fn, cls); + } + co.getItemMenuOption = function (env, lbl, fn, cls) + { + return co.getMenuOption(co.getItemDropdownTemplate(env), lbl, fn, cls); + } + co.getMenuOption = function ($opt, lbl, fn, cls) + { + return $opt.find('div.sbm-label').text(lbl).end().on('click', fn).addClass(cls); + } + + //-------------------------------------------------------------- + co.createItem = function (env, cfg) + { + co.clearItem(env, cfg); + let $frm = env.$frm.item; + $frm.find('.TransactionType').val(env.data.transactionTypeDefault); + env.$ctrl.searchTgtAssoc.show(); + $frm.find('.TransactionStatus').val(env.data.defaultStatusCode); + co.openItemDlg(env, cfg, sbm.dlg.title.createTransaction); + } + co.clearItem = function (env, cfg) + { + sbm.clearItemForm(env.$frm.item); + sbm.populateSelectCodeDesc('#cbTransactionStatus', env.data.statuses); + } + co.openItemDlg = function (env, cfg, title) + { + let $dlg = env.$dlg.item; + let $frm = env.$frm.item; + sbm.configureItemControls(cfg, $frm); + var btns = {}; + btns[sbm.lbl.ok] = function () { co.storeItem(env); }; + btns[sbm.lbl.cancel] = function () { delete env.prmEdit; $(this).dialog('close'); }; + $dlg.dialog('option', 'buttons', btns); + if (title) $dlg.dialog('option', 'title', title); + sbm.openDialog($dlg, 720, 640); + } + + //-------------------------------------------------------------- + co.updateItem = function (env, id) + { + let $frm = env.$frm.itemId; + $('.TransactionId', $frm).val(id); + $('.TransactionDataGroups', $frm).val('Sales'); + env.ajax.updateItem = env.ajax.updateItem || { url: sbm.url.base + 'Transaction/Ajax/GetItem', formSel: $frm, callbackFn: function (response) { co.onUpdateItem(env, response); } }; + sbm.doAjaxRequest(env.ajax.updateItem, 50); + } + co.onUpdateItem = function (env, response) + { + sbm.debug('onUpdateItem', env, response); + if (!response.success) return; + let cfg = response.config || {}; + co.clearItem(env, cfg); + let item = response.transaction; + let $frm = env.$frm.item; + sbm.populateFormValues(cfg, $frm, item.field.value); + let $ctrls = $frm.find('.sbm-input,.sbm-textarea,.sbm-select'); + $ctrls.filter('.TransactionId').val(item.id); + $ctrls.filter('.TransactionExists').val(1); + sbm.debug(item.field.value.AssociationId); + $ctrls.filter('.TransactionAssociationId').val(item.field.value.AssociationId); + env.$ctrl.searchTgtAssoc.hide(); + sbm.selectOrAdd($ctrls.filter('.TransactionType'), item.typeCode, item.typeDesc); + sbm.selectOrAdd($ctrls.filter('.TransactionStatus'), item.statusCode, item.field.value.Status); + co.openItemDlg(env, cfg, sbm.dlg.title.updateTransaction); + } + + //-------------------------------------------------------------- + co.selectAssocTarget = function (env) + { + if (!!env.$frm.item.find('.sbm-input.TransactionId').val()) return; + sbm.fn.selectAssociation({ type: env.$frm.filter.find('.FilterAssociationType').val(), fnSuccess: function (item) { co.onSelectAssocTarget(env, item); } }); + } + co.onSelectAssocTarget = function (env, item) + { + sbm.debug('onSelectAssocTarget', env, item); + env.$frm.item.find('.TransactionAssociationId').val(item.id); + env.$frm.item.find('.TransactionAssociation').val(item.name); + } + + //-------------------------------------------------------------- + co.storeItem = function (env) + { + env.ajax.storeItem = env.ajax.storeItem || { url: sbm.url.base + 'Transaction/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { co.onStoreItem(env, response); } }; + sbm.doAjaxRequest(env.ajax.storeItem, 50); + } + co.onStoreItem = function (env, response) + { + //sbm.debug('onStoreItem', env, response); + sbm.refreshControlValues(response.controlValues); + if (!response.success) return; + env.$dlg.item.dialog('close'); + var item = response.transaction; + if (env.prmEdit) + { + co.onItemEdited(env, item); + } + else if (env.$pnl.table.length) + { + env.$pnl.msgs.hide().empty(); + var $item = $('#' + co.getItemId(item), env.$pnl.table); + if (!$item.length) + { + $item = co.getItemTemplate(env); + $('table tbody', env.$pnl.table).prepend($item).show(); + } + co.populateItem(env, $item, item); + sbm.configureItemTable(env.data.cfgList, env.$pnl.table); + } + } + + //-------------------------------------------------------------- + /* Params: type, search, fnSuccess. */ + sbm.fn.selectTransaction = function (prm) + { + //sbm.debug('selectTransaction', prm); + let env = co.env.select; + env.prmSelect = prm; + env.$frm.filter.find('.FilterTransactionType').val(''); + env.$frm.filter.find('.FilterSearch').val(prm.search || ''); + env.$pnl.table.find('tbody tr').remove(); + sbm.openDialog(env.$dlg.select, 1000, 800); + if (env.$pnl.items.length) setTimeout(function () { co.refreshItems(env); }, 250); + } + co.selectItemRow = function (env, $item, item) + { + //sbm.debug('selectItemRow', env, $item, item); + env.$pnl.table.find('tr').removeClass('sbm-sel'); + $item.addClass('sbm-sel'); + env.prmSelect.item = item; + } + co.selectItem = function (env) + { + //sbm.debug('selectItem', env, env.prmSelect.item); + env.$dlg.select.dialog('close'); + env.prmSelect.fnSuccess(env.prmSelect.item); + delete env.prmSelect; + } + + /* Params: id, fnSuccess. */ + sbm.fn.editTransaction = function (prm) + { + //sbm.debug('editTransaction', prm); + let env = co.env.select; + env.prmEdit = prm; + //sbm.debug(env, prm); + co.updateItem(env, prm.id); + } + co.onItemEdited = function (env, item) + { + //sbm.debug('co.onItemEdited', env, item); + env.prmEdit.fnSuccess(item); + delete env.prmEdit; + } + + //-------------------------------------------------------------- + co.initEnv = function ($pnlItems) + { + let env = { data: {}, ajax: {}, $pnl: {}, $frm: {}, $ctrl: {}, $dlg: {} }; + + let $items = env.$pnl.items = $($pnlItems); + env.$pnl.header = $items.find('.sbm-panel-header'); + env.$pnl.bgr = env.$pnl.header.find('.sbm-burger'); + env.$pnl.mnu = env.$pnl.bgr.find('ul.sbm-dropdown-menu'); + env.$pnl.table = $items.find('.sbm-panel-item-table'); + env.$pnl.msgs = env.$pnl.table.find('.sbm-panel-messages'); + env.$pnl.tmpl = $items.find('.sbm-panel-item-template'); + + env.$frm.filter = $items.find('.frmTransactionFilter'); + if (env.$frm.filter.length) + env.$frm.filter.on('input', '.FilterSearch', function () { co.refreshItems(env, 250); }).on('change', '.FilterTransactionType,.FilterTransactionStatusCat', function () { co.refreshItems(env, 50); }); + env.$frm.itemId = $items.find('#frmTransactionId'); + var opt = sbm.dlgOpts(); + opt.dialogClass += " sbm-Transaction"; + env.$dlg.item = $items.find('#dlgTransaction').dialog(opt); + env.$frm.item = env.$dlg.item.find('#frmTransaction').on('input', '.sbm-input, .sbm-textarea', function () { sbm.clearControlError(this); }).on('change', '.sbm-select', function () { sbm.clearControlError(this); }); + sbm.initCalendars(env.$dlg.item.find('.sbm-input.sbm-calendar'), {}); + env.$frm.item.on('blur', '.sbm-input.sbm-format-integer', function () { sbm.formatInteger($(this)); }).on('blur', '.sbm-input.sbm-format-currency', function () { sbm.formatCurrency($(this)); }); + env.$frm.item.find('.TransactionAssociation').on('dblclick', function () { co.selectAssocTarget(env); }); + env.$ctrl.searchTgtAssoc = env.$frm.item.find('.AssociationTargetSearch').on('click', function () { co.selectAssocTarget(env); }); + + var opt = sbm.dlgOpts(); + opt.dialogClass += " sbm-Transaction"; + opt.buttons[sbm.lbl.ok] = function () { co.selectItem(env); }; + opt.buttons[sbm.lbl.cancel] = function () { delete env.prmSelect; $(this).dialog('close'); }; + env.$dlg.select = $('#dlgTransactionSelect').dialog(opt); + + return env; + } + + //-------------------------------------------------------------- + $(function () + { + co.env.maint = co.initEnv('.sbm-panel.Transactions'); + if (co.env.maint.$pnl.items.length) + { + $('body').on('keydown', function (e) { let env = co.env.maint; if (e.which == 45/*Insert*/ && env.data.cfgList.action.allow.create) co.createItem(env, env.data.cfgItemNew); }); + setTimeout(function () { co.refreshItems(co.env.maint); }, 250); + } + co.env.select = co.initEnv('#dlgTransactionSelect'); + if (co.env.select.$pnl.items.length) setTimeout(function () { co.refreshConfig(co.env.select); }, 250); + }); + + //-------------------------------------------------------------- +}(window, window.document)); + +/* The End */ \ No newline at end of file