diff --git a/SaBusMgrCoreProcs/Procs/Consoles/SbmProcessConsole.cs b/SaBusMgrCoreProcs/Procs/Consoles/SbmProcessConsole.cs index 18ee28e..6c1d871 100644 --- a/SaBusMgrCoreProcs/Procs/Consoles/SbmProcessConsole.cs +++ b/SaBusMgrCoreProcs/Procs/Consoles/SbmProcessConsole.cs @@ -197,7 +197,7 @@ namespace Sarand.BusinessMgr.Net.Core.Procs.Consoles prmInterface.InterfaceCategory = interfaceCategory; prmInterface.IncludedInterfaceTypes.Add(interfaceType); prmInterface.StatusCat = SaInterface.StatusCat.Any; - using (SaInterfaceConsole interfaceConsole = SbmGlobals.Application.CreateInterfaceConsole(userContext)) + using (SaInterfaceConsole interfaceConsole = SbmGlobals.System.CreateInterfaceConsole(userContext)) { saInterface = interfaceConsole.GetInterface(prmInterface); if (saInterface == null) diff --git a/SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs b/SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs index 33a0a3f..e2b3d16 100644 --- a/SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs +++ b/SaBusMgrCoreWeb/Web/App/SbmApplication_Web.cs @@ -96,45 +96,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App catch (Exception) { } } - //------------------------------------------------------------------- - // Create consoles. - public override SbmSessionConsole CreateSessionConsole(ISbmUserOrganisationContext userContext) - { - return SbmSessionConsole.CreateConsole(userContext); - } - public override SaDiaryConsole CreateDiaryConsole(ISbmUserOrganisationContext userContext) - { - return null; - } - public override SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext) - { - return new SbmSecurityConsole_Web(userContext); - } - public override SaCodeTypeConsole CreateCodeTypeConsole(ISbmUserOrganisationContext userContext) - { - return new SbmCodeTypeConsole_Web(userContext); - } - public override SaItemDataConsole CreateItemDataConsole(ISbmUserOrganisationContext userContext) - { - return null; - } - public override SaItemDocConsole CreateItemDocConsole(ISbmUserOrganisationContext userContext) - { - return null; - } - public override SaItemOptionConsole CreateItemOptionConsole(ISbmUserOrganisationContext userContext) - { - return new SbmItemOptionConsole_Web(userContext); - } - public override SaInterfaceConsole CreateInterfaceConsole(ISbmUserOrganisationContext userContext) - { - return null; - } - public override SaUpdateLogConsole CreateUpdateLogConsole(ISbmUserOrganisationContext userContext) - { - return new SbmUpdateLogConsole_Web(userContext); - } - //------------------------------------------------------------------- } //======================================================================= diff --git a/SaBusMgrCoreWeb/Web/App/SbmSessionData_Web.cs b/SaBusMgrCoreWeb/Web/App/SbmSessionData_Web.cs index 7f1963b..656ebf5 100644 --- a/SaBusMgrCoreWeb/Web/App/SbmSessionData_Web.cs +++ b/SaBusMgrCoreWeb/Web/App/SbmSessionData_Web.cs @@ -1,12 +1,5 @@ using Newtonsoft.Json; using Sarand.BusinessMgr.Net.Standard.Base.App; -using Sarand.BusinessMgr.Net.Standard.Base.Bus; -using Sarand.BusinessMgr.Net.Standard.Base.Core; -using Sarand.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.Security; -using System; -using System.Collections.Generic; -using System.Text; namespace Sarand.BusinessMgr.Net.Core.Web.App { @@ -14,12 +7,18 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App public abstract class SbmSessionData_Web : SbmSessionData { //------------------------------------------------------------------- - // Protected construction - for JSON deserialisation. - protected SbmSessionData_Web(long sessionIdx, int itemIdx, SbmSessionContext sessionContext) : - base(sessionIdx, itemIdx, sessionContext) + /// + /// Protected construction - for JSON deserialisation and non-session data (eg. prior to logon). + /// - Session index persistent to record sequence in which Session Data objects created. + /// - Session index should be zero for non-session data, eg. background tasks. + /// + protected SbmSessionData_Web(long sessionIdx, SbmSessionContext sessionContext) : + base(sessionIdx, sessionContext) { } - // Protected construction. + /// + /// Session Data constructor - prior to storage against session. + /// protected SbmSessionData_Web(SbmSessionContext sessionContext) : base(sessionContext) { @@ -31,24 +30,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App [JsonIgnore] public abstract bool KeepLoggedIn { get; } - //------------------------------------------------------------------- - // ToDo: Organisation configuration. - public String GetOrganisationOption(Sbm.OrganisationOption option, String context) { return null; } - public String GetOrganisationOption(String optionName, String context) { return null; } - public String GetOwnerOption_Value(Sbm.OrgOption_Value eCol) { return null; } - public String GetOwnerOption_Folder(Sbm.OrgOption_Folder eCol) { return null; } - public bool GetOwnerOption_AllowOption(Sbm.OrgOption_AllowOption eCol) { return false; } - public String GetOwnerOption_Caption(Sbm.OrgOption_Caption eCol, String defautValue) { return defautValue; } - public bool GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx eCol) { return false; } - public bool GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn eCol) { return false; } - public String GetOwnerOption_FieldLabel(SbmDbDfn.ColumnIdx eCol, String defautValue) { return defautValue; } - public int GetOwnerOption_Minutes(Sbm.OrgOption_Minutes eLimit, int defautValue) { return defautValue; } - public int GetOwnerOption_UpdateLimit(Sbm.OrgOption_PeriodDays eLimit, int defautValue) { return defautValue; } - public int GetOwnerOption_UpdateLimit(Sbm.OrgOption_PeriodWeeks eLimit, int defautValue) { return defautValue; } - public int GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals eNumDecimals, int defautValue = 2) { return defautValue; } - public Sbm.CommodityType GetOwnerOption_CommodityType(Sbm.OrgOption_CommodityType commodityTypeContext) { return Sbm.CommodityType.Unknown; } - public SysId GetOwnerOption_StockLocation(Sbm.OrgOption_StockLocation eLoc) { return null; } - //------------------------------------------------------------------- } //======================================================================= diff --git a/SaBusMgrCoreWeb/Web/App/SbmSystem_Web.cs b/SaBusMgrCoreWeb/Web/App/SbmSystem_Web.cs index 06f2e69..77bbed0 100644 --- a/SaBusMgrCoreWeb/Web/App/SbmSystem_Web.cs +++ b/SaBusMgrCoreWeb/Web/App/SbmSystem_Web.cs @@ -14,7 +14,7 @@ using System.Text; namespace Sarand.BusinessMgr.Net.Core.Web.App { //======================================================================= - public class SbmSystem_Web : SbmSystem_Dbas + public abstract class SbmSystem_Web : SbmSystem_Dbas { //------------------------------------------------------------------- // Data members. diff --git a/SaBusMgrCoreWeb/Web/App/SbmUserContext_Web.cs b/SaBusMgrCoreWeb/Web/App/SbmUserContext_Web.cs deleted file mode 100644 index ae2119a..0000000 --- a/SaBusMgrCoreWeb/Web/App/SbmUserContext_Web.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Sarand.BusinessMgr.Net.Standard.Base.App; -using Sarand.BusinessMgr.Net.Standard.Base.Bus; -using Sarand.BusinessMgr.Net.Standard.Dbas.App; -using Sarand.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.Security; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Sarand.BusinessMgr.Net.Core.Web.App -{ - //======================================================================= - public class SbmUserContext_Web : SbmUserContext_Dbas - { - //------------------------------------------------------------------- - // Data members. - - //------------------------------------------------------------------- - // Construction. - public SbmUserContext_Web(SbmSessionContext sessionContext) : base(sessionContext) - { - } - - //------------------------------------------------------------------- - // Properties. - - //------------------------------------------------------------------- - // Modify properties - internal only. - public void RefreshUser(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOwners) - { - base.SetUserData(securityItemUser, affiliateUser, supervisedOwners); - } - - //------------------------------------------------------------------- - } - //======================================================================= -} diff --git a/SaBusMgrCoreWeb/Web/Controllers/SbmController_Base.cs b/SaBusMgrCoreWeb/Web/Controllers/SbmController_Base.cs index a46f055..c3b37de 100644 --- a/SaBusMgrCoreWeb/Web/Controllers/SbmController_Base.cs +++ b/SaBusMgrCoreWeb/Web/Controllers/SbmController_Base.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.Logging.Abstractions; using Sacs.Web.Components; using Sarand.BusinessMgr.Net.Core.Web.App; using Sarand.BusinessMgr.Net.Standard.Base.App; @@ -20,12 +19,7 @@ using Sarand.Net.Standard.Base.ItemOptions; using Sarand.Net.Standard.Base.ReferenceData; using Sarand.Net.Standard.Base.Security; using Sarand.Net.Standard.Base.UpdateLog; -using Sarand.Net.Standard.Base.Utils; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Sarand.BusinessMgr.Net.Core.Web.Controllers { @@ -34,8 +28,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers { //------------------------------------------------------------------- // Data members. - private SbmInternals internals; - private SbmInternals_Control internals_Control; //------------------------------------------------------------------- // Protected construction. @@ -52,10 +44,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers { if (disposing) { - if (internals != null) internals.Dispose(); - internals = null; - if (internals_Control != null) internals_Control.Dispose(); - internals_Control = null; } base.Dispose(disposing); } @@ -67,41 +55,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers public App.SbmAppConfig AppConfig { get { return App.AppConfig; } } public abstract SbmSessionContext SessionContext { get; } public abstract ISbmUserOrganisationContext UserContext_Core { get; } - // Business components. - public SbmInternals Internals { get { if (internals == null && UserContext_Core != null) { internals = new SbmInternals(UserContext_Core); } return internals; } } - public SbmInternals_Control Internals_Control { get { if (internals_Control == null) { internals_Control = new SbmInternals_Control(); } return internals_Control; } } - // Managers. - public SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } } - public SbmAssetMgr AssetMgr { get { return Internals.AssetMgr; } } - public SbmCommodityMgr CommodityMgr { get { return Internals.CommodityMgr; } } - public SbmPriceMgr PriceMgr { get { return Internals.PriceMgr; } } - public SbmTransactionMgr TransactionMgr { get { return Internals.TransactionMgr; } } - public SbmStockMgr StockMgr { get { return Internals.StockMgr; } } - public SbmProcessMgr ProcessMgr { get { return Internals.ProcessMgr; } } - public SbmDataItemMgr DataItemMgr { get { return Internals.DataItemMgr; } } - // Control. - protected SbmcAccountMgr ControlAccountMgr { get { return Internals_Control.ControlAccountMgr; } } - protected SbmcInstanceMgr ControlInstanceMgr { get { return Internals_Control.ControlInstanceMgr; } } - protected SbmcItemMgr ControlItemMgr { get { return Internals_Control.ControlItemMgr; } } - // Consoles. - public SbmSessionConsole SessionConsole { get { return Internals.SessionConsole; } } - public SaDiaryConsole DiaryConsole { get { return Internals.DiaryConsole; } } - public SaSecurityConsole SecurityConsole { get { return Internals.SecurityConsole; } } - public SaCodeTypeConsole CodeTypeConsole { get { return Internals.CodeTypeConsole; } } - public SaReferenceDataConsole ReferenceDataConsole { get { return Internals.ReferenceDataConsole; } } - public SaUpdateLogConsole UpdateLogConsole { get { return Internals.UpdateLogConsole; } } - public SaInterfaceConsole InterfaceConsole { get { return Internals.InterfaceConsole; } } - public SaItemDocConsole ItemDocConsole { get { return Internals.ItemDocConsole; } } - public SaItemOptionConsole ItemOptionConsole { get { return Internals.ItemOptionConsole; } } - public SaItemDataConsole ItemDataConsole { get { return Internals.ItemDataConsole; } } - // Configurations. - public SbmStockControlConfig StockControlConfig { get { return Internals.StockControlConfig; } } - public SbmRequirementCostingConfig RequirementCostingConfig { get { return Internals.RequirementCostingConfig; } } - // System codes. - public List GetCodesOfType(Sbm.SystemCode systemCode) { return Internals.GetSystemCodes(systemCode); } - // Email. - public SaEmailConfig EmailConfig { get { return Internals.EmailConfig; } } - public SbmEmailConsole EmailConsole { get { return Internals.EmailConsole; } } //------------------------------------------------------------------- // Action execution events. diff --git a/SaBusMgrCoreWeb/Web/Models/SbmModel_Base.cs b/SaBusMgrCoreWeb/Web/Models/SbmModel_Base.cs index 76031f1..e3f64a0 100644 --- a/SaBusMgrCoreWeb/Web/Models/SbmModel_Base.cs +++ b/SaBusMgrCoreWeb/Web/Models/SbmModel_Base.cs @@ -271,44 +271,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models return new SelectList(codes, "Code", "Desc"); } - /// List of Address Types for dropdown. - public IEnumerable GetAddressTypeCodesForSelect() - { - return new SelectList(GetCodesOfType(Sbm.SystemCode.AddressType), "Code", "Desc"); - } - - /// List of Affiliate Types for dropdown. - public IEnumerable GetAffiliateTypeCodesForSelect() - { - return new SelectList(GetCodesOfType(Sbm.SystemCode.AffiliateType), "Code", "Desc"); - } - - /// List of Association Types for dropdown. - public IEnumerable GetAssociationTypeCodesForSelect() - { - List associationTypes = GetCodesOfType(Sbm.SystemCode.AssociationType); - associationTypes.RemoveAll(item => item.Type == (short)Sbm.AssociationType.Internal); - foreach (Sbm.AssociationType associationType in EnumUtil.GetValues()) - { - if (!SessionConsole.AllowAssociationType(associationType)) - associationTypes.RemoveAll(item => item.Type == (short)associationType); - } - return new SelectList(associationTypes, "Code", "Desc"); - } - - /// List of Commodity Types for dropdown. - public IEnumerable GetCommodityTypeCodesForSelect() - { - return new SelectList(GetCodesOfType(Sbm.SystemCode.CommodityType), "Code", "Desc"); - } - - /// List of Asset Types for dropdown. - public IEnumerable GetAssetTypeCodesForSelect() - { - - return new SelectList(GetCodesOfType(Sbm.SystemCode.AssetType), "Code", "Desc"); - } - //------------------------------------------------------------------- // Form properties. /// diff --git a/SaBusMgrStandardBase/Base/App/Sbm.cs b/SaBusMgrStandardBase/Base/App/Sbm.cs index faabef4..0a70899 100644 --- a/SaBusMgrStandardBase/Base/App/Sbm.cs +++ b/SaBusMgrStandardBase/Base/App/Sbm.cs @@ -1855,6 +1855,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App public enum AssetType { Unknown = 0, + Any = Unknown, // NB Do not change the positive values, as tied to the database. General = 10, Furniture = 11, @@ -1863,8 +1864,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App } public enum AssetIncomeType { - Unknown = 0, None = 0, + Unknown = 0, // NB Do not change the positive values, as tied to the database. Sale = 10, Rental = 20, @@ -1874,8 +1875,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App // Vehicles. public enum VehicleType { - Any = -1, Unknown = 0, + Any = Unknown, // NB Do not change the positive values, as tied to the database. Car = 10, Minibus = 11, diff --git a/SaBusMgrStandardBase/Base/App/SbmAppConfig.cs b/SaBusMgrStandardBase/Base/App/SbmAppConfig.cs index e85fb3d..da8dccc 100644 --- a/SaBusMgrStandardBase/Base/App/SbmAppConfig.cs +++ b/SaBusMgrStandardBase/Base/App/SbmAppConfig.cs @@ -8,12 +8,12 @@ using System; namespace Sarand.BusinessMgr.Net.Standard.Base.App { - //======================================================================= - /// - /// Application configuration: - /// - Availability of UI components - menu options, views etc. - /// - public static class SbmAppConfig + //======================================================================= + /// + /// Application configuration: + /// - Availability of UI components - menu options, views etc. + /// + public static class SbmAppConfig { private const String ClassName = nameof(SbmAppConfig); @@ -21,8 +21,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App // A p p l i c a t i o n V i e w s //------------------------------------------------------------------- // Jul-2021 SessionConfig parameter added to avoid local creation. To be reviewed/replaced. - public static bool IsViewApplicable(SbmSessionConsole sessionConsole, Sbm.View view) + public static bool IsViewApplicable(SbmInternals internals, Sbm.View view) { + SbmSessionConsole sessionConsole = internals.SessionConsole; ISbmSecurityProfile_Core securityProfile = sessionConsole.UserContext.SecurityProfile_Core; switch (view) { @@ -231,14 +232,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App case Sbm.View.SystemUsers: if (!sessionConsole.AllowOption(Sbm.ConfigOption.Contacts)) return false; // Interfaces must be available. - using (SaInterfaceConsole interfaceConsole = SbmGlobals.Application.CreateInterfaceConsole(sessionConsole.UserContext)) - { - if (interfaceConsole == null || !interfaceConsole.DatabaseIsValid) return false; - // System Account & User tables must be available. - ISacsDatabase busMgrDb = SbmGlobals.Application.GetBusMgrDatabase(sessionConsole.UserContext.SessionContext); - if (!SbmGlobals.Application.DbTableExists(busMgrDb, SbmDbDfn.TableIdx.SystemAccount)) return false; - if (!SbmGlobals.Application.DbTableExists(busMgrDb, SbmDbDfn.TableIdx.SystemUser)) return false; - } + if (internals.InterfaceConsole == null || !internals.InterfaceConsole.DatabaseIsValid) return false; + // System Account & User tables must be available. + ISacsDatabase busMgrDb = SbmGlobals.Application.GetBusMgrDatabase(sessionConsole.UserContext.SessionContext); + if (!SbmGlobals.Application.DbTableExists(busMgrDb, SbmDbDfn.TableIdx.SystemAccount)) return false; + if (!SbmGlobals.Application.DbTableExists(busMgrDb, SbmDbDfn.TableIdx.SystemUser)) return false; return true; } @@ -268,17 +266,17 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App //------------------------------------------------------------------- // A p p l i c a t i o n M e n u //------------------------------------------------------------------- - public static bool IsMenuOptionApplicable(SbmSessionConsole sessionConsole, Sbm.MenuOption menuOption) + public static bool IsMenuOptionApplicable(SbmInternals internals, Sbm.MenuOption menuOption) { - if (!sessionConsole.UserContext.ValidUser) + if (!internals.SessionConsole.UserContext.ValidUser) { // ToDo Only Login menu option available. return false; } - Sbm.View view = GetViewForMenuOption(sessionConsole.UserContext.SessionContext, menuOption); + Sbm.View view = GetViewForMenuOption(internals.SessionConsole.UserContext.SessionContext, menuOption); if (view != Sbm.View.Unknown) // View options. - return IsViewApplicable(sessionConsole, GetViewForMenuOption(sessionConsole.UserContext.SessionContext, menuOption)); + return IsViewApplicable(internals, GetViewForMenuOption(internals.SessionConsole.UserContext.SessionContext, menuOption)); // Non-view options. switch (menuOption) @@ -296,7 +294,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App //----------------------------------------------------------- // Actions. case Sbm.MenuOption.Timesheet: - return sessionConsole.AllowOption(Sbm.ConfigOption.TimeRecording); + return internals.SessionConsole.AllowOption(Sbm.ConfigOption.TimeRecording); //----------------------------------------------------------- } SaLogger.Warn($"{SysUtil.Fn} Unsupport menu option - {menuOption.ToString()}"); diff --git a/SaBusMgrStandardBase/Base/App/SbmApplication.cs b/SaBusMgrStandardBase/Base/App/SbmApplication.cs index d674750..46d4949 100644 --- a/SaBusMgrStandardBase/Base/App/SbmApplication.cs +++ b/SaBusMgrStandardBase/Base/App/SbmApplication.cs @@ -84,20 +84,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App // Email configuration. public abstract SbmEmailConfig EmailConfig { get; } - //------------------------------------------------------------------- - // Create consoles. - public abstract SbmSessionConsole CreateSessionConsole(ISbmUserOrganisationContext userContext); - public abstract SaDiaryConsole CreateDiaryConsole(ISbmUserOrganisationContext userContext); - public abstract SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext); - public abstract SaCodeTypeConsole CreateCodeTypeConsole(ISbmUserOrganisationContext userContext); - public abstract SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext); - public abstract SaItemDataConsole CreateItemDataConsole(ISbmUserOrganisationContext userContext); - public abstract SaItemDocConsole CreateItemDocConsole(ISbmUserOrganisationContext userContext); - public abstract SaItemOptionConsole CreateItemOptionConsole(ISbmUserOrganisationContext userContext); - public abstract SaInterfaceConsole CreateInterfaceConsole(ISbmUserOrganisationContext userContext); - public abstract SaUpdateLogConsole CreateUpdateLogConsole(ISbmUserOrganisationContext userContext); - public abstract SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext); - //------------------------------------------------------------------- } //======================================================================= diff --git a/SaBusMgrStandardBase/Base/App/SbmInternals.cs b/SaBusMgrStandardBase/Base/App/SbmInternals.cs index b5ded4a..417800c 100644 --- a/SaBusMgrStandardBase/Base/App/SbmInternals.cs +++ b/SaBusMgrStandardBase/Base/App/SbmInternals.cs @@ -3,6 +3,7 @@ using Sarand.BusinessMgr.Net.Standard.Base.Consoles; using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Mgr; using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; +using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.CodeTypes; using Sarand.Net.Standard.Base.Core; @@ -31,12 +32,30 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App // Definitions. /// - /// Internal User Context for read-only database access when this class is used outside of user specific sessions. - /// - data caches etc. + /// Internal core Session Data for Core database access when this + /// class is used outside of user specific core sessions, eg. + /// - Pre-login. + /// - Data caches. + /// - Control application session interacting with a core database. /// - private class SbmUserContext_Internal : SbmUserContext + private class SbmSessionData_Internals : SbmSessionData, ISbmUserOrganisationContext { - public SbmUserContext_Internal(SbmSessionContext sessionContext) : base(sessionContext) { } + public SbmSessionData_Internals(SbmSessionContext sessionContext) : base(sessionContext) { } + // User properties. + public override string UserEmailAddress => ""; + public override string UserDisplayName => ""; + public override bool ValidUser => false; + public SysId UserSecurityItemId => new SysId(); + public SysId UserAffiliateId => new SysId(); + public override DbUpdateInfo DbUpdateInfo => new DbUpdateInfo(UserSecurityItemId, UserDisplayName, SacsSystem.ComputerName); + // User security. + public ISbmSecurityProfile_Core SecurityProfile_Core => throw new NotImplementedException(); + // Organisation. + public SysId OrganisationAffiliateId => new SysId(); + public Sbm.AffiliateType OrganisationAffiliateType => Sbm.AffiliateType.Unknown; + public SysId OrganisationAssociationId => new SysId(); + public string OrganisationDisplayName => ""; + public string OrganisationInterfaceContext => ""; } //------------------------------------------------------------------- @@ -82,11 +101,15 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App //------------------------------------------------------------------- // Construction. + /// + /// Sessionless construction - minimal context information. + /// public SbmInternals(SbmSessionContext sessionContext) { - UserContext = new SbmUserContext_Internal(sessionContext); + UserContext = new SbmSessionData_Internals(sessionContext); ReadOnly = true; } + // Session dependent construction. public SbmInternals(ISbmUserOrganisationContext userContext) { UserContext = userContext; @@ -207,6 +230,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App public List AssociationTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.AssociationType); } } public List CommodityTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.CommodityType); } } public List AssetTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.AssetType); } } + public List VehicleTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.VehicleType); } } public List TransactionTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.TransactionType); } } //------------------------------------------------------------------- @@ -305,7 +329,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.sessionConsole == null) - con.sessionConsole = Application.CreateSessionConsole(UserContext); + con.sessionConsole = SbmGlobals.System.CreateSessionConsole(UserContext); return con.sessionConsole; } } @@ -314,7 +338,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.diaryConsole == null) - con.diaryConsole = Application.CreateDiaryConsole(UserContext); + con.diaryConsole = SbmGlobals.System.CreateDiaryConsole(UserContext); return con.diaryConsole; } } @@ -323,7 +347,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.securityConsole == null) - con.securityConsole = Application.CreateSecurityConsole(UserContext); + con.securityConsole = SbmGlobals.System.CreateSecurityConsole(UserContext); return con.securityConsole; } } @@ -332,7 +356,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.codeTypeConsole == null) - con.codeTypeConsole = Application.CreateCodeTypeConsole(UserContext); + con.codeTypeConsole = SbmGlobals.System.CreateCodeTypeConsole(UserContext); return con.codeTypeConsole; } } @@ -341,7 +365,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.referenceDataConsole == null) - con.referenceDataConsole = Application.CreateReferenceDataConsole(UserContext); + con.referenceDataConsole = SbmGlobals.System.CreateReferenceDataConsole(UserContext); return con.referenceDataConsole; } } @@ -350,7 +374,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.updateLogConsole == null) - con.updateLogConsole = Application.CreateUpdateLogConsole(UserContext); + con.updateLogConsole = SbmGlobals.System.CreateUpdateLogConsole(UserContext); return con.updateLogConsole; } } @@ -359,7 +383,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.interfaceConsole == null) - con.interfaceConsole = Application.CreateInterfaceConsole(UserContext); + con.interfaceConsole = SbmGlobals.System.CreateInterfaceConsole(UserContext); return con.interfaceConsole; } } @@ -368,7 +392,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.itemDocConsole == null) - con.itemDocConsole = Application.CreateItemDocConsole(UserContext); + con.itemDocConsole = SbmGlobals.System.CreateItemDocConsole(UserContext); return con.itemDocConsole; } } @@ -377,7 +401,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.itemOptionConsole == null) - con.itemOptionConsole = Application.CreateItemOptionConsole(UserContext); + con.itemOptionConsole = SbmGlobals.System.CreateItemOptionConsole(UserContext); return con.itemOptionConsole; } } @@ -386,20 +410,20 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App get { if (con.itemDataConsole == null) - con.itemDataConsole = Application.CreateItemDataConsole(UserContext); + con.itemDataConsole = SbmGlobals.System.CreateItemDataConsole(UserContext); return con.itemDataConsole; } } //------------------------------------------------------------------- // Email. - public SaEmailConfig EmailConfig { get { return Application.EmailConfig; } } + public SbmEmailConfig EmailConfig { get { return Application.EmailConfig; } } public SbmEmailConsole EmailConsole { get { if (con.emailConsole == null) - con.emailConsole = Application.CreateEmailConsole(UserContext); + con.emailConsole = SbmGlobals.System.CreateEmailConsole(UserContext, EmailConfig); return con.emailConsole; } } diff --git a/SaBusMgrStandardBase/Base/App/SbmSecurityProfile.cs b/SaBusMgrStandardBase/Base/App/SbmSecurityProfile.cs index c5baea3..5e7a76e 100644 --- a/SaBusMgrStandardBase/Base/App/SbmSecurityProfile.cs +++ b/SaBusMgrStandardBase/Base/App/SbmSecurityProfile.cs @@ -27,9 +27,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App // Construction. [JsonConstructor] private SbmSecurityProfile() { } - public SbmSecurityProfile(ISbmUserOrganisationContext userContext, bool includeHostSecurityProfile) + public SbmSecurityProfile(bool includeHostSecurityProfile) { - this.UserContext = userContext; this.includeHostSecurityProfile = includeHostSecurityProfile; Admin = new AdminProfile(); Manage = new ManageProfile(); @@ -40,8 +39,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App //------------------------------------------------------------------- // Properties. - [JsonIgnore] - public ISbmUserOrganisationContext UserContext { get; } //------------------------------------------------------------------- // Refresh profile. @@ -271,7 +268,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App return true; // Check if any other statuses for this type of transaction are allowed. - foreach (TypeCodeDesc statusCat in SbmTransaction.GetTransactionStatusCats(securityProfile.UserContext, transactionType)) + foreach (TypeCodeDesc statusCat in SbmTransaction.GetTransactionStatusCats(transactionType)) { SbmTransaction.StatusCat transactionStatusCatOther = (SbmTransaction.StatusCat)statusCat.Type; // Ignore the transaction status category. @@ -388,6 +385,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App } public bool UserCanCreateItemType(Sbm.ItemType itemType) { + if (userSecurityProfile?.SystemAdmin ?? false) return true; if (!ItemTypeIsAllowed(itemType)) return false; switch (itemType) { @@ -434,6 +432,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App } public bool UserCanUpdateItemType(Sbm.ItemType itemType) { + if (userSecurityProfile?.SystemAdmin ?? false) return true; switch (itemType) { case Sbm.ItemType.SecItem: return IsSecurityRightGranted(Sbm.SecurityRight.Security_Admin); diff --git a/SaBusMgrStandardBase/Base/App/SbmSessionData.cs b/SaBusMgrStandardBase/Base/App/SbmSessionData.cs index 6635d94..0dff21d 100644 --- a/SaBusMgrStandardBase/Base/App/SbmSessionData.cs +++ b/SaBusMgrStandardBase/Base/App/SbmSessionData.cs @@ -1,68 +1,20 @@ using Newtonsoft.Json; -using Sarand.BusinessMgr.Net.Standard.Base.Bus; using Sarand.BusinessMgr.Net.Standard.Base.Core; -using Sarand.BusinessMgr.Net.Standard.Base.Mgr; -using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Helpers; -using Sarand.Net.Standard.Base.Security; -using Sarand.Net.Standard.Base.Utils; using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; namespace Sarand.BusinessMgr.Net.Standard.Base.App { //======================================================================= - public abstract class SbmSessionData + /// + /// Basic user session data, shared by Portal and Control applications. + /// + public abstract class SbmSessionData : ISbmUserContext { //------------------------------------------------------------------- - private static long sessionIdxRoot = SacsRandomHelper.GetInt32(1000, 1999); + // Definitions. - //------------------------------------------------------------------- - // Construction. - /// Protected constructor for deserialisation only. - protected SbmSessionData(long sessionIdx, int itemIdx, SbmSessionContext sessionContext) - { - SessionIdx = sessionIdx; - ItemIdx = itemIdx; - SessionContext = sessionContext; - } - /// - /// Plain constructor. - /// - SessionContext must be supplied. - /// - protected SbmSessionData(SbmSessionContext sessionContext) - { - SessionIdx = ++sessionIdxRoot; - ItemIdx = 1000; - SessionContext = sessionContext; - } - - //------------------------------------------------------------------- - // Properties. - - // Session and Item indexers. - public long SessionIdx { get; } - public int ItemIdx { get; private set; } - [JsonIgnore] - public int NextItemIdx { get { return ++ItemIdx; } } - - // Session context. - public SbmSessionContext SessionContext { get; } - - // User properties. - [JsonIgnore] - public abstract String UserEmailAddress { get; } - [JsonIgnore] - public abstract String UserDisplayName { get; } - [JsonIgnore] - public abstract bool ValidUser { get; } - [JsonIgnore] - public abstract DbUpdateInfo DbUpdateInfo { get; } - - //------------------------------------------------------------------- // User. public class UserData { @@ -91,6 +43,61 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App } } + //------------------------------------------------------------------- + // Data members. + private static long sessionIdxNext { get; set; } = SacsRandomHelper.GetInt32(100001, 199999); + private static long dataIdxNext { get; set; } = 1000001; + + //------------------------------------------------------------------- + // Construction. + /// + /// Constructor to persist the Session index, eg. for deserialisation from Session. + /// - Session index of zero indicates sessionless data, eg. background tasks. + /// - Session index less than zero will assign a new value. + /// + protected SbmSessionData(long sessionIdx, SbmSessionContext sessionContext) + { + SessionIdx = sessionIdx >= 0 ? sessionIdx : sessionIdxNext++; + DataIdx = dataIdxNext++; + SessionContext = sessionContext; + } + /// + /// Main constructor. + /// - SessionContext must be supplied. + /// + protected SbmSessionData(SbmSessionContext sessionContext) + { + SessionIdx = sessionIdxNext++; + DataIdx = dataIdxNext++; + SessionContext = sessionContext; + } + + //------------------------------------------------------------------- + // Properties. + + /// + /// Session Index - assigned in sequence and persistent when data is serialised/deserialised. + /// + public long SessionIdx { get; } + /// + /// Data Index - assigned in sequence for each object constructed. + /// + public long DataIdx { get; } + + // Session context. + public SbmSessionContext SessionContext { get; } + + // User properties. + [JsonIgnore] + public abstract String UserEmailAddress { get; } + [JsonIgnore] + public abstract String UserDisplayName { get; } + [JsonIgnore] + public abstract bool ValidUser { get; } + [JsonIgnore] + public abstract DbUpdateInfo DbUpdateInfo { get; } + + //------------------------------------------------------------------- } //======================================================================= diff --git a/SaBusMgrStandardBase/Base/App/SbmSystem.cs b/SaBusMgrStandardBase/Base/App/SbmSystem.cs index e80aec0..f04acf5 100644 --- a/SaBusMgrStandardBase/Base/App/SbmSystem.cs +++ b/SaBusMgrStandardBase/Base/App/SbmSystem.cs @@ -3,7 +3,16 @@ using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Mgr; using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.CodeTypes; using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Diary; +using Sarand.Net.Standard.Base.Interfaces; +using Sarand.Net.Standard.Base.ItemData; +using Sarand.Net.Standard.Base.ItemDocs; +using Sarand.Net.Standard.Base.ItemOptions; +using Sarand.Net.Standard.Base.ReferenceData; +using Sarand.Net.Standard.Base.Security; +using Sarand.Net.Standard.Base.UpdateLog; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; @@ -110,6 +119,20 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App public abstract SbmcInstanceMgr CreateControlInstanceMgr(); public abstract SbmcItemMgr CreateControlItemMgr(); + //------------------------------------------------------------------- + // Consoles. + public abstract SbmSessionConsole CreateSessionConsole(ISbmUserOrganisationContext userContext); + public abstract SaDiaryConsole CreateDiaryConsole(ISbmUserOrganisationContext userContext); + public abstract SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext); + public abstract SaCodeTypeConsole CreateCodeTypeConsole(ISbmUserOrganisationContext userContext); + public abstract SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext); + public abstract SaItemDataConsole CreateItemDataConsole(ISbmUserOrganisationContext userContext); + public abstract SaItemDocConsole CreateItemDocConsole(ISbmUserOrganisationContext userContext); + public abstract SaItemOptionConsole CreateItemOptionConsole(ISbmUserOrganisationContext userContext); + public abstract SaInterfaceConsole CreateInterfaceConsole(ISbmUserOrganisationContext userContext); + public abstract SaUpdateLogConsole CreateUpdateLogConsole(ISbmUserOrganisationContext userContext); + public abstract SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext, SbmEmailConfig emailConfig); + //------------------------------------------------------------------- // A p p l i c a t i o n P r o p e r t i e s //------------------------------------------------------------------- diff --git a/SaBusMgrStandardBase/Base/App/SbmUserContext.cs b/SaBusMgrStandardBase/Base/App/SbmUserContext.cs deleted file mode 100644 index d8c7a95..0000000 --- a/SaBusMgrStandardBase/Base/App/SbmUserContext.cs +++ /dev/null @@ -1,198 +0,0 @@ -using Sarand.BusinessMgr.Net.Standard.Base.Bus; -using Sarand.BusinessMgr.Net.Standard.Base.Core; -using Sarand.BusinessMgr.Net.Standard.Base.Mgr; -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.ItemOptions; -using Sarand.Net.Standard.Base.Security; -using Sarand.Net.Standard.Base.Utils; -using System; -using System.Collections.Generic; - -namespace Sarand.BusinessMgr.Net.Standard.Base.App -{ - //======================================================================= - public class SbmUserContext : ISbmUserOrganisationContext - { - //------------------------------------------------------------------- - // Definitions. - - // User profile. - public class UserData - { - protected UserData() { } - protected readonly List supervisedOwners = new List(); - /// User Security Item Id. - public SysId SecurityItemId { get; protected set; } = new SysId(); - /// User Affiliate Id. - public SysId AffiliateId { get; protected set; } = new SysId(); - /// User first name. - public String FirstName { get; protected set; } = ""; - /// User last name. - public String LastName { get; protected set; } = ""; - /// User display name. - public String DisplayName { get; protected set; } = ""; - /// User email address. - public String EmailAddress { get; protected set; } = ""; - /// User managed associations - Id and display name. - public List SupervisedOrganisations { get { return new List(supervisedOwners); } } - } - private class UserData_Internal : UserData - { - internal UserData_Internal() { } - internal void Clear() - { - SecurityItemId = new SysId(); - AffiliateId = new SysId(); - FirstName = ""; - LastName = ""; - DisplayName = ""; - EmailAddress = ""; - supervisedOwners.Clear(); - } - internal void Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOwners) - { - SecurityItemId = SysId.InvalidOnNull(securityItemUser?.Id ?? null); - AffiliateId = SysId.InvalidOnNull(affiliateUser?.Id ?? null); - FirstName = StringUtil.EmptyOnNull(affiliateUser?.FirstName ?? "").TrimAll(); - LastName = StringUtil.EmptyOnNull(affiliateUser?.LastName ?? "").TrimAll(); - DisplayName = StringUtil.EmptyOnNull(affiliateUser?.GetDisplayName() ?? "").TrimAll(); - EmailAddress = StringUtil.EmptyOnNull(securityItemUser?.EmailAddress ?? ""); - this.supervisedOwners.Clear(); - this.supervisedOwners.AddRange(supervisedOwners); - } - } - - // Owner profile - selected organisation to manage. - public class OrganisationData - { - internal OrganisationData() { } - /// Organisation Affiliate Id. - public SysId AffiliateId { get; protected set; } = new SysId(); - /// Organisation Affiliate Type. - public Sbm.AffiliateType AffiliateType { get; protected set; } = Sbm.AffiliateType.Unknown; - /// Organisation display name. - public String DisplayName { get; protected set; } = ""; - /// Organisation Interface context - to qualify interfaces belonging to the organisation. - public String InterfaceContext { get; protected set; } = ""; - /// Organisation 'Internal' Association Id. - public SysId AssociationId { get; protected set; } = new SysId(); - } - private class OrganisationData_Internal : OrganisationData - { - internal OrganisationData_Internal() { } - internal void Clear() - { - AffiliateId = new SysId(); - AffiliateType = Sbm.AffiliateType.Unknown; - DisplayName = ""; - InterfaceContext = ""; - } - internal void Refresh(SbmAffiliate affiliateOrganisation, SbmAssociation associationInternal, String interfaceContext) - { - AffiliateId = SysId.InvalidOnNull(affiliateOrganisation.Id); - AffiliateType = affiliateOrganisation.AffiliateType; - DisplayName = StringUtil.EmptyOnNull(affiliateOrganisation.GetDisplayName()).TrimAll(); - InterfaceContext = StringUtil.EmptyOnNull(interfaceContext); - AssociationId = associationInternal.Id; - } - } - - //------------------------------------------------------------------- - // Data members. - private readonly UserData_Internal userData = new UserData_Internal(); - private readonly OrganisationData_Internal organisationData; - - //------------------------------------------------------------------- - // Construction. - protected SbmUserContext(SbmSessionContext sessionContext) - { - SessionContext = sessionContext; - organisationData = new OrganisationData_Internal(); - securityProfile = new SbmSecurityProfile(this, true); - } - - //------------------------------------------------------------------- - // Properties. - public SbmSessionContext SessionContext { get; protected set; } - - // User properties. - public UserData User { get { return userData; } } - /// User Security Item Id. - public SysId UserSecurityItemId { get { return User?.SecurityItemId; } } - /// User Affiliate Id. - public SysId UserAffiliateId { get { return User?.AffiliateId; } } - /// User display name. - public String UserDisplayName { get { return userData?.DisplayName; } } - /// User email address. - public String UserEmailAddress { get { return userData?.EmailAddress; } } - public bool ValidUser { get { return SysId.IsValid(userData.SecurityItemId) && SysId.IsValid(userData?.AffiliateId); } } - public DbUpdateInfo DbUpdateInfo { get { return new DbUpdateInfo(userData?.AffiliateId, userData?.DisplayName ?? "", SacsSystem.ComputerName); } } - - // Organisation properties. - public OrganisationData Organisation { get { return organisationData; } } - /// Organisation Affiliate Id. - public SysId OrganisationAffiliateId { get { return Organisation?.AffiliateId; } } - /// Organisation Affiliate Type. - public Sbm.AffiliateType OrganisationAffiliateType { get { return Organisation?.AffiliateType ?? Sbm.AffiliateType.Unknown; } } - /// Organisation 'Internal' Association Id. - public SysId OrganisationAssociationId { get { return Organisation?.AssociationId; } } - /// Organisation display name. - public String OrganisationDisplayName { get { return Organisation?.DisplayName; } } - /// Organisation Interface context - to qualify interfaces belonging to the organisation. - public String OrganisationInterfaceContext { get { return Organisation?.InterfaceContext; } } - public List SupervisedOrganisations { get { return new List(userData.SupervisedOrganisations); } } - - //------------------------------------------------------------------- - // Security profile. - private SbmSecurityProfile securityProfile { get; set; } - public ISbmSecurityProfile_Core SecurityProfile_Core { get { return securityProfile; } } - - //------------------------------------------------------------------- - // Modify properties - internal only. - protected void SetUserData(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOwners) - { - userData.Refresh(securityItemUser, affiliateUser, supervisedOwners); - } - protected void ClearUserData() - { - userData.Clear(); - organisationData.Clear(); - SetSecurityProfile(new SbmSecurityProfile(this, true)); - } - protected void SetOrganisationData(SysId affiliateIdOrganisation) - { - // Interface context for selected organisation. - String interfaceContext = SbmAccountMgr.GetInterfaceContext(affiliateIdOrganisation); - - if (SysId.IsValid(affiliateIdOrganisation)) - { - using (SbmAccountMgr accountMgr = SbmGlobals.System.CreateAccountMgr(this)) - // Affiliate. - using (SbmAffiliate affiliateOrganisation = accountMgr.GetAffiliateById(affiliateIdOrganisation)) - // 'Internal' association. - using (SbmAssociation associationInternal = accountMgr.GetAssociationByOwnerTypeTarget(affiliateIdOrganisation, Sbm.AssociationType.Internal, affiliateIdOrganisation)) - - if (affiliateOrganisation != null && associationInternal != null) - { - // Refresh the organisation properties. - organisationData.Refresh(affiliateOrganisation, associationInternal, interfaceContext); - } - else ClearOrganisationData(); - } - } - protected void ClearOrganisationData() - { - organisationData.Clear(); - } - protected void SetSecurityProfile(SbmSecurityProfile securityProfile) - { - this.securityProfile = securityProfile; - } - - //------------------------------------------------------------------- - } - //======================================================================= -} diff --git a/SaBusMgrStandardBase/Base/Bus/SbmAccountsDfn-Sage.cs b/SaBusMgrStandardBase/Base/Bus/SbmAccountsDfn-Sage.cs index 1e5fa65..b5034bd 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmAccountsDfn-Sage.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmAccountsDfn-Sage.cs @@ -281,7 +281,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus { // Only populated when needed as reads Code Types from db. contexts_StockCategoryAction = new List(); - using (SaCodeTypeConsole codeTypeConsole = SbmGlobals.Application.CreateCodeTypeConsole(UserContext)) + using (SaCodeTypeConsole codeTypeConsole = SbmGlobals.System.CreateCodeTypeConsole(UserContext)) { codes_StockCategoryAction = codeTypeConsole.GetCodeDescsForCodeType(SbmSystem.GetCodeTypeCode(Sbm.ApplCodeType.CommodityCategory)); foreach (CodeDesc commodityCategory in codes_StockCategoryAction) diff --git a/SaBusMgrStandardBase/Base/Bus/SbmAffiliate.cs b/SaBusMgrStandardBase/Base/Bus/SbmAffiliate.cs index 98d87b8..e793fec 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmAffiliate.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmAffiliate.cs @@ -336,7 +336,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus private readonly Data data = new Data(); public static readonly Byte Flag_Prospect = 0x01; public static readonly Byte Flag_KeepLoggedIn_Portal = 0x02; - public static readonly Byte Flag_KeepLoggedIn_Control = 0x03; //------------------------------------------------------------------- // Construction. @@ -731,11 +730,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus get { return GetFlag(Flag_KeepLoggedIn_Portal); } set { SetFlag(Flag_KeepLoggedIn_Portal, value); } } - public bool KeepLoggedIn_Control - { - get { return GetFlag(Flag_KeepLoggedIn_Control); } - set { SetFlag(Flag_KeepLoggedIn_Control, value); } - } //------------------------------------------------------------------- // A s s o c i a t e d D a t a E l e m e n t s diff --git a/SaBusMgrStandardBase/Base/Bus/SbmAsset.cs b/SaBusMgrStandardBase/Base/Bus/SbmAsset.cs index 4e7ae37..43b6307 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmAsset.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmAsset.cs @@ -408,6 +408,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus return DataValue.TriStateType.Unknown; } + //------------------------------------------------------------------- + // Utilities. + public ItemId GetItemId() + { + return new ItemId((short)Sbm.ItemType.Asset, Id); + } + //------------------------------------------------------------------- // Properties. public Data GetData() { return data.Clone(); } diff --git a/SaBusMgrStandardBase/Base/Bus/SbmAssetCategory.cs b/SaBusMgrStandardBase/Base/Bus/SbmAssetCategory.cs index cbd88fc..b120b55 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmAssetCategory.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmAssetCategory.cs @@ -249,6 +249,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Utilities. + public ItemId GetItemId() + { + return new ItemId((short)Sbm.ItemType.AssetCategory, Id); + } //------------------------------------------------------------------- // Properties. diff --git a/SaBusMgrStandardBase/Base/Bus/SbmAssetProcess.cs b/SaBusMgrStandardBase/Base/Bus/SbmAssetProcess.cs index c008032..f21181b 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmAssetProcess.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmAssetProcess.cs @@ -120,6 +120,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Data members. private readonly Data data = new Data(); + //------------------------------------------------------------------- // Construction. protected SbmAssetProcess(ISbmUserOrganisationContext userContext, SysId id, SysId assetId, SysId processId) : base(userContext, id) @@ -160,6 +161,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Utilities. + public ItemId GetItemId() + { + return new ItemId((short)Sbm.ItemType.AssetProcess, Id); + } + //------------------------------------------------------------------- // Properties. public Data GetData() { return data.Clone(); } @@ -171,6 +177,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus // Populate individual properties to ensure that 'Changed' indicator is kept up to date. this.data.PopulateFrom(data); } + //------------------------------------------------------------------- // Attributes. public SysId AssetId diff --git a/SaBusMgrStandardBase/Base/Bus/SbmCommodity.cs b/SaBusMgrStandardBase/Base/Bus/SbmCommodity.cs index 8da103c..0412bfd 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmCommodity.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmCommodity.cs @@ -1862,7 +1862,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus { SbmAccountMgr accountMgr = null; List lValue = new List(); - using (SbmSessionConsole sessionConsole = SbmGlobals.Application.CreateSessionConsole(userContext)) + using (SbmSessionConsole sessionConsole = SbmGlobals.System.CreateSessionConsole(userContext)) { // Commodities to exclude. if (IdsIncluded.Count > 0) lValue.Add("Included commodities", IdsIncluded.Count.ToString()); diff --git a/SaBusMgrStandardBase/Base/Bus/SbmTransaction.cs b/SaBusMgrStandardBase/Base/Bus/SbmTransaction.cs index c7fd66a..ec33308 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmTransaction.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmTransaction.cs @@ -794,7 +794,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Status Categories. - public static List GetTransactionStatusCats(ISbmUserOrganisationContext userContext, Sbm.TransactionType transactionType) + public static List GetTransactionStatusCats(Sbm.TransactionType transactionType) { List statusCats = new List(); List statusCatsFull = SbmSystem.GetSystemCodes(Sbm.SystemCode.TransactionStatusCat); @@ -804,8 +804,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus // and SapphireConsole::UseInProgressTaxDateAsTaxPoint(). // Transaction types that have no 'Pending' stage. case Sbm.TransactionType.SalesLead: - statusCats.AddRange(statusCatsFull.FindAll(item => item.Type == (int)StatusCat.Open)); - statusCats.AddRange(statusCatsFull.FindAll(item => item.Type == (int)StatusCat.Closed)); + statusCats.AddRange(statusCatsFull.FindAll(item => item.Type == (int)StatusCat.Open || item.Type == (int)StatusCat.Closed)); break; // Transaction types that have no 'Open' stage. case Sbm.TransactionType.ProformaSalesOrder: @@ -813,8 +812,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus case Sbm.TransactionType.ProformaPurchaseOrder: case Sbm.TransactionType.PurchaseDelivery: case Sbm.TransactionType.ProformaSalesInvoice: - statusCats.AddRange(statusCatsFull.FindAll(item => item.Type == (int)StatusCat.Pending)); - statusCats.AddRange(statusCatsFull.FindAll(item => item.Type == (int)StatusCat.Closed)); + statusCats.AddRange(statusCatsFull.FindAll(item => item.Type == (int)StatusCat.Pending || item.Type == (int)StatusCat.Closed)); break; default: // All other types have the complete set. @@ -869,7 +867,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus // Nov-08 Current thinking is that the only differences is whether the 'In Progress' date has been specified and whether that should be used in preference to the 'Raised' date. if (DateUtil.IsValid(inProgress) && (transactionStatusCat == SbmTransaction.StatusCat.Open || transactionStatusCat == SbmTransaction.StatusCat.Closed)) { - using (SbmSessionConsole sessionConsole = SbmGlobals.Application.CreateSessionConsole(userContext)) + using (SbmSessionConsole sessionConsole = SbmGlobals.System.CreateSessionConsole(userContext)) { if (sessionConsole != null && sessionConsole.UseInProgressTaxDateAsTaxPoint(transactionType)) return inProgress; diff --git a/SaBusMgrStandardBase/Base/Bus/SbmVehicle.cs b/SaBusMgrStandardBase/Base/Bus/SbmVehicle.cs index d10b771..07f54f0 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmVehicle.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmVehicle.cs @@ -369,6 +369,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Utilities. + public ItemId GetItemId() + { + return new ItemId((short)Sbm.ItemType.Vehicle, Id); + } //------------------------------------------------------------------- // Properties. @@ -560,6 +564,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus public enum StatusCat { Any, + ActiveOnly, + NotDeleted, + DeletedOnly } /// /// Item list parameters. @@ -579,7 +586,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus public String VinPartial { get; set; } public String MakeCode { get; set; } public String ClassDescPartial { get; set; } - public String RestrictToActive { get; set; } /// Vehicle status. public StatusCat StatusCat { get; set; } = StatusCat.Any; // Utilities. diff --git a/SaBusMgrStandardBase/Base/Bus/SbmVehicleClass.cs b/SaBusMgrStandardBase/Base/Bus/SbmVehicleClass.cs index d74d818..fb3a8eb 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmVehicleClass.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmVehicleClass.cs @@ -268,6 +268,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Utilities. + public ItemId GetItemId() + { + return new ItemId((short)Sbm.ItemType.VehicleClass, Id); + } + public bool MatchesModel(String makeCode, String model) { if (MakeCode != makeCode) return false; diff --git a/SaBusMgrStandardBase/Base/Bus/SbmVehicleEvent.cs b/SaBusMgrStandardBase/Base/Bus/SbmVehicleEvent.cs index 1efca21..e061ae1 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmVehicleEvent.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmVehicleEvent.cs @@ -222,6 +222,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Utilities. + public ItemId GetItemId() + { + return new ItemId((short)Sbm.ItemType.VehicleEvent, Id); + } //------------------------------------------------------------------- // Properties. diff --git a/SaBusMgrStandardBase/Base/Bus/SbmVehicleFeature.cs b/SaBusMgrStandardBase/Base/Bus/SbmVehicleFeature.cs index 233e404..2fb89ec 100644 --- a/SaBusMgrStandardBase/Base/Bus/SbmVehicleFeature.cs +++ b/SaBusMgrStandardBase/Base/Bus/SbmVehicleFeature.cs @@ -200,6 +200,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus //------------------------------------------------------------------- // Utilities. + public ItemId GetItemId() + { + return new ItemId((short)Sbm.ItemType.VehicleFeature, Id); + } + public bool PublishInPreferenceTo(SbmVehicleFeature vehicleFeature) { // True if different types: diff --git a/SaBusMgrStandardBase/Base/Consoles/SbmCoreInstanceConsole_Base.cs b/SaBusMgrStandardBase/Base/Consoles/SbmCoreInstanceConsole_Base.cs index 0d678cf..8f8076b 100644 --- a/SaBusMgrStandardBase/Base/Consoles/SbmCoreInstanceConsole_Base.cs +++ b/SaBusMgrStandardBase/Base/Consoles/SbmCoreInstanceConsole_Base.cs @@ -52,6 +52,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles public SysId SecurityItemId { get; set; } public String Code { get; set; } public String Password { get; set; } + public bool PasswordSet { get; set; } } public UserData User { get; private set; } = new UserData(); public void ClearUser() { User = new UserData(); } @@ -94,7 +95,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles //------------------------------------------------------------------- // Utilities. - public abstract SaSecurityConsole CreateSecurityConsole(); //------------------------------------------------------------------- /// @@ -205,6 +205,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles if (!SysId.IsValid(initData.User.SecurityItemId)) return SetErrorState("User security item not found."); } + + if (Internals_Core.SecurityConsole.RequiresPopulation()) + return SetErrorState("Security Database requires population."); } catch (Exception exc) { @@ -288,8 +291,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles // Retrieve existing Organisation. SbmAffiliate affiliateOrganisation = Internals_Core.AccountMgr.GetAffiliateById(initData.Organisation.AffiliateId); + if (affiliateOrganisation == null && SysId.IsValid(initData.Organisation.AffiliateId)) + return SetErrorState("Identified Organisation Contact not found."); if (affiliateOrganisation != null && !affiliateOrganisation.IsOrganisation()) - return SetErrorState("Identified contact is not an organisation."); + return SetErrorState("Identified Contact is not an organisation."); if (affiliateOrganisation == null) affiliateOrganisation = Internals_Core.AccountMgr.GetAffiliateByTypeName(Sbm.AffiliateType.AnyOrganisation, initData.Organisation.Name); if (affiliateOrganisation == null) @@ -328,7 +333,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles disposables.Add(associationInternal); if (associationInternal != null && SysId.IsValid(initData.Organisation.AssociationId) && !associationInternal.Id.Equals(initData.Organisation.AssociationId)) // Failed to validate existing Internal Association against supplied Association Id. - return SetErrorState($"Supplied Internal Association Id ({initData.Organisation.AssociationId}) doesn't match existing association ({associationInternal.Id})."); + return SetErrorState($"Identified Internal Association (Id. {initData.Organisation.AssociationId}) doesn't match existing association ({associationInternal.Id})."); if (associationInternal == null && SysId.IsValid(initData.Organisation.AssociationId)) { // No existing Internal Association found for Organisation - retrieve specified Association. @@ -361,8 +366,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles // Security. // Core security console. - SaSecurityConsole securityConsole = CreateSecurityConsole(); - disposables.Add(securityConsole); + SaSecurityConsole securityConsole = Internals_Core.SecurityConsole; // Initialise security data if required. if (securityConsole.RequiresPopulation() && !securityConsole.PopulateSecurityRights(DbUpdateInfo_Core)) @@ -399,7 +403,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles // Populate User Security Item properties. securityItemUser.EmailAddress = initData.User.Email; - securityConsole.SetPassword(securityItemUser, initData.User.Password); + if (initData.User.PasswordSet) + securityConsole.SetPassword(securityItemUser, initData.User.Password); if (!securityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo_Core)) return SetErrorState($"Failed to update User Security Item - {securityConsole.ErrorStateMessage}."); diff --git a/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Base.cs b/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Base.cs new file mode 100644 index 0000000..90d702d --- /dev/null +++ b/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Base.cs @@ -0,0 +1,22 @@ +using Sarand.Net.Standard.Base.Dbas; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Sarand.BusinessMgr.Net.Standard.Base.Core +{ + //======================================================================= + /// + /// Session data - Common User properties associated with either a Core or Control user session. + /// + public interface ISbmSessionData_Base : ISbmUserContext + { + //------------------------------------------------------------------- + // Properties. + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Control.cs b/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Control.cs new file mode 100644 index 0000000..5820fa6 --- /dev/null +++ b/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Control.cs @@ -0,0 +1,22 @@ +using Sarand.Net.Standard.Base.Dbas; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Sarand.BusinessMgr.Net.Standard.Base.Core +{ + //======================================================================= + /// + /// Control Session data - User properties associated with a Control user session. + /// + public interface ISbmSessionData_Control : ISbmSessionData_Base, ISbmUserContext + { + //------------------------------------------------------------------- + // Properties. + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Core.cs b/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Core.cs new file mode 100644 index 0000000..1cff4cc --- /dev/null +++ b/SaBusMgrStandardBase/Base/Core/ISbmSessionData_Core.cs @@ -0,0 +1,21 @@ +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Dbas; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Sarand.BusinessMgr.Net.Standard.Base.Core +{ + //======================================================================= + /// + /// Core Session data - User and Organisation properties associated with a Core user session. + /// + public interface ISbmSessionData_Core : ISbmUserOrganisationContext + { + //------------------------------------------------------------------- + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Affiliate.cs b/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Affiliate.cs index 1bc5dbf..9d37378 100644 --- a/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Affiliate.cs +++ b/SaBusMgrStandardBase/Base/Mgr/SbmAccountMgr_Affiliate.cs @@ -367,11 +367,21 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr public abstract List GetAffiliateList(SbmAffiliate.Params prm); public abstract DbResultSet ExecuteAffiliateQuery(List columns, SbmAffiliate.Params prm); - public List GetAffiliatesSupervisedBy(SysId affiliateIdUser) + public bool IsAffiliateSupervisedBy(SysId affiliateIdContact, SysId affiliateIdSupervisor) { List affiliateIdNames = new List(); SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); - prmAffiliate.AffiliateIdAssocTarget = affiliateIdUser; + prmAffiliate.AffiliateIdAssocOwner = affiliateIdContact; + prmAffiliate.AffiliateIdAssocTarget = affiliateIdSupervisor; + prmAffiliate.TargetSupervised = SbmAffiliate.Params.Supervised.Yes; + return GetAffiliateCount(prmAffiliate) > 0; + } + + public List GetAffiliatesSupervisedBy(SysId affiliateIdSupervisor) + { + List affiliateIdNames = new List(); + SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); + prmAffiliate.AffiliateIdAssocTarget = affiliateIdSupervisor; prmAffiliate.TargetSupervised = SbmAffiliate.Params.Supervised.Yes; foreach (SbmAffiliate affiliate in GetAffiliateList(prmAffiliate)) { diff --git a/SaBusMgrStandardBase/Base/Mgr/SbmAssetMgr_AssetCategory.cs b/SaBusMgrStandardBase/Base/Mgr/SbmAssetMgr_AssetCategory.cs index 7ea2264..495b908 100644 --- a/SaBusMgrStandardBase/Base/Mgr/SbmAssetMgr_AssetCategory.cs +++ b/SaBusMgrStandardBase/Base/Mgr/SbmAssetMgr_AssetCategory.cs @@ -18,6 +18,21 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr //******************************************************************* // Utilities. + public bool AssetCategoryHasAssets(SysId assetCategoryId) + { + return GetAssetCountForAssetCategory(assetCategoryId) > 0; + } + + public long GetAssetCountForAssetCategory(SysId assetCategoryId) + { + ClearErrorState(); + if (!SysId.IsValid(assetCategoryId)) return 0; + SbmAsset.Params prmAsset = new SbmAsset.Params(); + prmAsset.IdsIncluded.Add(assetCategoryId); + prmAsset.StatusCat = SbmAsset.StatusCat.Any; + return GetAssetCount(prmAsset); + } + //------------------------------------------------------------------- // Retrieve individual items. //------------------------------------------------------------------- diff --git a/SaBusMgrStandardDbas/Dbas/App/SbmSystem_Dbas.cs b/SaBusMgrStandardDbas/Dbas/App/SbmSystem_Dbas.cs index 16c5c98..8932c15 100644 --- a/SaBusMgrStandardDbas/Dbas/App/SbmSystem_Dbas.cs +++ b/SaBusMgrStandardDbas/Dbas/App/SbmSystem_Dbas.cs @@ -15,7 +15,7 @@ using System.IO; namespace Sarand.BusinessMgr.Net.Standard.Dbas.App { //======================================================================= - public class SbmSystem_Dbas : SbmSystem + public abstract class SbmSystem_Dbas : SbmSystem { //------------------------------------------------------------------- // Static initialisation. @@ -34,7 +34,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.App //------------------------------------------------------------------- // Construction. - public SbmSystem_Dbas(PropertySet properties) : base(properties) + protected SbmSystem_Dbas(PropertySet properties) : base(properties) { if (IsExtendedLogging(ExtendedLogginOption.DbQueryExecution)) { diff --git a/SaBusMgrStandardDbas/Dbas/App/SbmUserContext_Dbas.cs b/SaBusMgrStandardDbas/Dbas/App/SbmUserContext_Dbas.cs deleted file mode 100644 index 60c596b..0000000 --- a/SaBusMgrStandardDbas/Dbas/App/SbmUserContext_Dbas.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Sarand.BusinessMgr.Net.Standard.Base.App; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Sarand.BusinessMgr.Net.Standard.Dbas.App -{ - public class SbmUserContext_Dbas : SbmUserContext - { - //------------------------------------------------------------------- - // Data members. - - //------------------------------------------------------------------- - // Construction. - public SbmUserContext_Dbas(SbmSessionContext sessionContext) : base(sessionContext) - { - } - - //------------------------------------------------------------------- - } -} diff --git a/SaBusMgrStandardDbas/Dbas/Consoles/SbmItemOptionConsole_Dbas.cs b/SaBusMgrStandardDbas/Dbas/Consoles/SbmItemOptionConsole_Dbas.cs index 843172e..37917ef 100644 --- a/SaBusMgrStandardDbas/Dbas/Consoles/SbmItemOptionConsole_Dbas.cs +++ b/SaBusMgrStandardDbas/Dbas/Consoles/SbmItemOptionConsole_Dbas.cs @@ -16,9 +16,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles { //------------------------------------------------------------------- // Data members. - private SbmAccountMgr accountMgr = null; - private SaInterfaceConsole interfaceConsole; - private SaUpdateLogConsole updateLogConsole; + private SbmInternals internals; //------------------------------------------------------------------- // Construction. @@ -30,8 +28,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles { if (disposing) { - if (accountMgr != null) accountMgr.Dispose(); accountMgr = null; - if (updateLogConsole != null) updateLogConsole.Dispose(); updateLogConsole = null; + if (internals != null) internals.Dispose(); internals = null; } base.Dispose(disposing); } @@ -40,27 +37,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles // Properties. public ISbmUserOrganisationContext UserContext { get; set; } public SbmSessionContext SessionContext { get { return UserContext.SessionContext; } } + private SbmInternals Internals { get { if (internals == null) { internals = new SbmInternals(UserContext); } return internals; } } public override short ItemOptionDataType { get { return (short)Sbm.ItemType.ItemOption; } } - private SbmAccountMgr AccountMgr { get { if (accountMgr == null) accountMgr = SbmGlobals.System.CreateAccountMgr(UserContext); return accountMgr; } } + private SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } } // Consoles. - public SaInterfaceConsole InterfaceConsole - { - get - { - if (interfaceConsole == null) - interfaceConsole = SbmGlobals.Application.CreateInterfaceConsole(UserContext); - return interfaceConsole; - } - } - public override SaUpdateLogConsole UpdateLogConsole - { - get - { - if (updateLogConsole == null) - updateLogConsole = SbmGlobals.Application.CreateUpdateLogConsole(UserContext); - return updateLogConsole; - } - } + public SaInterfaceConsole InterfaceConsole { get { return Internals.InterfaceConsole; } } + public override SaUpdateLogConsole UpdateLogConsole { get { return Internals.UpdateLogConsole; } } //------------------------------------------------------------------- // I t e m O p t i o n D e f i n i t i o n s diff --git a/SaBusMgrStandardDbas/Dbas/Consoles/SbmReferenceDataConsole_Dbas.cs b/SaBusMgrStandardDbas/Dbas/Consoles/SbmReferenceDataConsole_Dbas.cs index 553d900..5a82690 100644 --- a/SaBusMgrStandardDbas/Dbas/Consoles/SbmReferenceDataConsole_Dbas.cs +++ b/SaBusMgrStandardDbas/Dbas/Consoles/SbmReferenceDataConsole_Dbas.cs @@ -11,7 +11,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles { //------------------------------------------------------------------- // Data members. - private SaUpdateLogConsole updateLogConsole; + private SbmInternals internals; //------------------------------------------------------------------- // Construction. @@ -24,15 +24,16 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles { if (disposing) { - if (updateLogConsole != null) updateLogConsole.Dispose(); updateLogConsole = null; + if (internals != null) internals.Dispose(); internals = null; } base.Dispose(disposing); } //------------------------------------------------------------------- // Properties. - public SbmSessionContext SessionContext { get; } public ISbmUserOrganisationContext UserContext { get; } + public SbmSessionContext SessionContext { get { return UserContext.SessionContext; } } + private SbmInternals Internals { get { if (internals == null) { internals = new SbmInternals(UserContext); } return internals; } } // Item types. public override short LanguageItemType { get { return (short)Sbm.ItemDataType.Unknown; } } public override short RegionItemType { get { return (short)Sbm.ItemDataType.Region; } } @@ -40,15 +41,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles public override short TaxCodeItemType { get { return (short)Sbm.ItemDataType.Unknown; } } public override short UnitMeasureItemType { get { return (short)Sbm.ItemDataType.Unknown; } } // Consoles. - public override SaUpdateLogConsole UpdateLogConsole - { - get - { - if (updateLogConsole == null) - updateLogConsole = SbmGlobals.Application.CreateUpdateLogConsole(UserContext); - return updateLogConsole; - } - } + public override SaUpdateLogConsole UpdateLogConsole { get { return Internals.UpdateLogConsole; } } //------------------------------------------------------------------- } diff --git a/SaBusMgrStandardDbas/Dbas/Consoles/SbmSecurityConsole_Dbas.cs b/SaBusMgrStandardDbas/Dbas/Consoles/SbmSecurityConsole_Dbas.cs index 6a30dc0..d3cbf8c 100644 --- a/SaBusMgrStandardDbas/Dbas/Consoles/SbmSecurityConsole_Dbas.cs +++ b/SaBusMgrStandardDbas/Dbas/Consoles/SbmSecurityConsole_Dbas.cs @@ -132,7 +132,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles if ((fullList || bValidTransType) && SessionConsole.AllowTransactionType(transType)) { // Retrieve status categories for transaction type: - foreach (TypeCodeDesc transactionStatus in GetTransactionStatusCats(transType)) + foreach (TypeCodeDesc transactionStatus in SbmTransaction.GetTransactionStatusCats(transType)) { SbmTransaction.StatusCat transStatusCat = (SbmTransaction.StatusCat)transactionStatus.Type; String sDesc = transactionType.Desc + " - " + transactionType.Desc; @@ -146,43 +146,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles } //------------------------------------------------------------------- - // Status Cats - private List GetTransactionStatusCats(Sbm.TransactionType eType) - { - List transactionStatusCats = new List(); - List transactionStatusCatsAllowed = Internals.GetSystemCodes(Sbm.SystemCode.TransactionStatusCat); - switch (eType) - { - // NB Changes here may also need to be made in SapTransaction::GetTaxEffectiveDate() - // and SapphireConsole::UseInProgressTaxDateAsTaxPoint(): - // Transaction types that have no 'Pending' stage: - case Sbm.TransactionType.SalesLead: - transactionStatusCats.AddRange(transactionStatusCatsAllowed.Where(item => item.Type == (int)SbmTransaction.StatusCat.Open || item.Type == (int)SbmTransaction.StatusCat.Closed)); - break; - // Transaction types that have no 'Open' stage: - case Sbm.TransactionType.ProformaSalesOrder: - case Sbm.TransactionType.SalesDispatch: - case Sbm.TransactionType.ProformaPurchaseOrder: - case Sbm.TransactionType.PurchaseDelivery: - case Sbm.TransactionType.ProformaSalesInvoice: - transactionStatusCats.AddRange(transactionStatusCatsAllowed.Where(item => item.Type == (int)SbmTransaction.StatusCat.Pending || item.Type == (int)SbmTransaction.StatusCat.Closed)); - break; - default: - // All other types have the complete set: - transactionStatusCats = transactionStatusCatsAllowed; - break; - } - return transactionStatusCats; - } - //------------------------------------------------------------------- - // Status Id. + // TRansaction Status Id. private SysId GetTransactionTypeStatusId(Sbm.TransactionType transactionType, SbmTransaction.StatusCat transactionStatusCat) { return new SysId(((int)transactionType * 100) + (int)transactionStatusCat); } - //------------------------------------------------------------------- - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // R e g i t e r S e c u r i t y R i g h t s //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/SaBusMgrStandardDbas/Dbas/Consoles/SbmUpdateLogConsole_Dbas.cs b/SaBusMgrStandardDbas/Dbas/Consoles/SbmUpdateLogConsole_Dbas.cs index 0e59aad..7994c61 100644 --- a/SaBusMgrStandardDbas/Dbas/Consoles/SbmUpdateLogConsole_Dbas.cs +++ b/SaBusMgrStandardDbas/Dbas/Consoles/SbmUpdateLogConsole_Dbas.cs @@ -14,7 +14,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles { //------------------------------------------------------------------- // Data members. - private SaSecurityConsole securityConsole; + private SbmInternals internals; //------------------------------------------------------------------- // Construction. @@ -27,7 +27,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles { if (disposing) { - if (securityConsole != null) securityConsole.Dispose(); securityConsole = null; + if (internals != null) internals.Dispose(); internals = null; } base.Dispose(disposing); } @@ -36,16 +36,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles // Properties. public ISbmUserOrganisationContext UserContext { get; } public SbmSessionContext SessionContext { get { return UserContext.SessionContext; } } + private SbmInternals Internals { get { if (internals == null) { internals = new SbmInternals(UserContext); } return internals; } } // Consoles. - public SaSecurityConsole SecurityConsole - { - get - { - if (securityConsole == null) - securityConsole = SbmGlobals.Application.CreateSecurityConsole(UserContext); - return securityConsole; - } - } + public SaSecurityConsole SecurityConsole { get { return Internals.SecurityConsole; } } //------------------------------------------------------------------- // Get name for User Id. diff --git a/SaBusMgrStandardDbas/Dbas/Mgr/Control/SbmcInstanceMgr_Dbas-Repository.cs b/SaBusMgrStandardDbas/Dbas/Mgr/Control/SbmcInstanceMgr_Dbas-Repository.cs index 45d1c06..aff2211 100644 --- a/SaBusMgrStandardDbas/Dbas/Mgr/Control/SbmcInstanceMgr_Dbas-Repository.cs +++ b/SaBusMgrStandardDbas/Dbas/Mgr/Control/SbmcInstanceMgr_Dbas-Repository.cs @@ -66,7 +66,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr if (count == 0) return null; if (count != 1) { - SetErrorState("Multiple Repositoryes found"); + SetErrorState("Multiple Repositories found"); return null; } SbmcRepository repository = null; diff --git a/SaBusMgrStandardDbas/Dbas/Mgr/SbmAccountMgr_Dbas-Affiliate.cs b/SaBusMgrStandardDbas/Dbas/Mgr/SbmAccountMgr_Dbas-Affiliate.cs index e6c6061..493c8ad 100644 --- a/SaBusMgrStandardDbas/Dbas/Mgr/SbmAccountMgr_Dbas-Affiliate.cs +++ b/SaBusMgrStandardDbas/Dbas/Mgr/SbmAccountMgr_Dbas-Affiliate.cs @@ -775,7 +775,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr // User Id. String colAffiliate_UserId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_UserId, aliasAffiliate); if (SysId.IsValid(prm.UserId)) - filter.Add(colAffiliate_UserId + "=" + SysId.ToString(prm.UserId)); + filter.Add($"{colAffiliate_UserId}={SysId.ToString(prm.UserId)}"); // System User Interface. if (SysId.IsValid(prm.InterfaceIdExcludeSystemUsers)) @@ -786,25 +786,29 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr qrySystemUser.Tables.Add(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.SystemUser), aliasSystemUser); qrySystemUser.Columns.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SystemUser_Id, aliasSystemUser)); qrySystemUser.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SystemUser_AffiliateId, aliasSystemUser) + "=" + colAffiliate_Id); - filter.Add("NOT EXISTS (" + qrySystemUser.BuildQuery() + ")"); + filter.Add($"NOT EXISTS ({qrySystemUser.BuildQuery()})"); } //--------------------------------------------------------------- // Common properties. // Partial Notes. - if (!StringUtil.IsEmpty(prm.EmailPartial)) - filter.Add(colAffiliate_Notes + " LIKE '%" + DbQuery.FormatForLike(prm.NotesPartial) + "%'"); + if (!StringUtil.IsEmpty(prm.NotesPartial)) + filter.Add($"{colAffiliate_Notes} LIKE '%{DbQuery.FormatForLike(prm.NotesPartial)}%'"); // Status. - if (prm.StatusCat == SbmAffiliate.StatusCat.CurrentOnly) - filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + "='" + StatusCurrent + "'"); - else if (prm.StatusCat == SbmAffiliate.StatusCat.OnHoldOnly) - filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + "='" + SacsSystem.GetStatusCode(SaStatus.OnHold) + "'"); - else if (prm.StatusCat == SbmAffiliate.StatusCat.NotDeleted) - filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + "!='" + SacsSystem.GetStatusCode(SaStatus.Deleted) + "'"); - else if (prm.StatusCat == SbmAffiliate.StatusCat.DeletedOnly) - filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate) + "='" + SacsSystem.GetStatusCode(SaStatus.Deleted) + "'"); + if (prm.StatusCat != SbmAffiliate.StatusCat.Any) + { + String colStatus = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Status, aliasAffiliate); + if (prm.StatusCat == SbmAffiliate.StatusCat.CurrentOnly) + filter.Add($"{colStatus}='{StatusCurrent}'"); + else if (prm.StatusCat == SbmAffiliate.StatusCat.OnHoldOnly) + filter.Add($"{colStatus}='{SacsSystem.GetStatusCode(SaStatus.OnHold)}'"); + else if (prm.StatusCat == SbmAffiliate.StatusCat.NotDeleted) + filter.Add($"{colStatus}!='{SacsSystem.GetStatusCode(SaStatus.Deleted)}'"); + else if (prm.StatusCat == SbmAffiliate.StatusCat.DeletedOnly) + filter.Add($"{colStatus}='{SacsSystem.GetStatusCode(SaStatus.Deleted)}'"); + } if (filter.Count < 1 && prm.IncludeDefaultFilter) filter.Add("1=1"); return filter; diff --git a/SaBusMgrStandardDbas/Dbas/Mgr/SbmAssetMgr_Dbas-Vehicle.cs b/SaBusMgrStandardDbas/Dbas/Mgr/SbmAssetMgr_Dbas-Vehicle.cs index d6167f1..9fdfc9e 100644 --- a/SaBusMgrStandardDbas/Dbas/Mgr/SbmAssetMgr_Dbas-Vehicle.cs +++ b/SaBusMgrStandardDbas/Dbas/Mgr/SbmAssetMgr_Dbas-Vehicle.cs @@ -493,13 +493,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr List filter = new List(); // Vehicle Id. - String includedIds = prm.IdsIncluded.Concat(","); String colVehicle_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaVehicle_Id, aliasVehicle); - if (!StringUtil.IsEmpty(includedIds)) - filter.Add($"{colVehicle_Id} IN ({includedIds})"); - String excludedIds = prm.IdsExcluded.Concat(","); - if (!StringUtil.IsEmpty(excludedIds)) - filter.Add($"{colVehicle_Id} NOT IN ({excludedIds})"); + if (prm.IdsIncluded.HasValidIds()) + filter.Add($"{colVehicle_Id} IN ({prm.IdsIncluded.Concat(",")})"); + if (prm.IdsExcluded.HasValidIds()) + filter.Add($"{colVehicle_Id} NOT IN ({prm.IdsExcluded.Concat(",")})"); + //--------------------------------------------------------------- // Vehicle Class. String colVehicle_VehicleClassId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaVehicle_VehicleClassId, aliasVehicle); @@ -519,14 +518,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr } //--------------------------------------------------------------- // Partial Registration. - String regNumber = DbQuery.FormatForCondition(prm.RegNumberPartial); - if (!StringUtil.IsEmpty(regNumber)) - filter.Add($"{DbQuery.FormatFn_Left(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaVehicle_RegNumber, aliasVehicle), prm.RegNumberPartial.Length)}='{regNumber}'"); + if (!StringUtil.IsBlank(prm.RegNumberPartial)) + filter.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaVehicle_RegNumber, aliasVehicle)} Like '%{DbQuery.FormatForLike(prm.RegNumberPartial)}%'"); // Partial VIN: - String vin = DbQuery.FormatForCondition(prm.VinPartial); - if (!StringUtil.IsEmpty(vin)) - filter.Add($"{DbQuery.FormatFn_Left(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaVehicle_VIN, aliasVehicle), prm.VinPartial.Length)}='{vin}'"); + if (!StringUtil.IsBlank(prm.VinPartial)) + filter.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaVehicle_VIN, aliasVehicle)} Like '%{DbQuery.FormatForLike(prm.VinPartial)}%'"); //--------------------------------------------------------------- // Associated Assets. @@ -555,10 +552,17 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr } } //--------------------------------------------------------------- - // Restrict to active: - String colVehicle_Status = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaVehicle_Status, aliasVehicle); - if (!StringUtil.IsEmpty(prm.RestrictToActive)) - filter.Add($"{colVehicle_Status}='{StatusActive}'"); + // Status. + if (prm.StatusCat != SbmVehicle.StatusCat.Any) + { + String colStatus = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.SaVehicle_Status, aliasVehicle); + if (prm.StatusCat == SbmVehicle.StatusCat.ActiveOnly) + filter.Add($"{colStatus}='{StatusCurrent}'"); + else if (prm.StatusCat == SbmVehicle.StatusCat.NotDeleted) + filter.Add($"{colStatus}!='{SacsSystem.GetStatusCode(SaStatus.Deleted)}'"); + else if (prm.StatusCat == SbmVehicle.StatusCat.DeletedOnly) + filter.Add($"{colStatus}='{SacsSystem.GetStatusCode(SaStatus.Deleted)}'"); + } if (filter.Count < 1 && prm.IncludeDefaultFilter) filter.Add("1=1"); return filter; diff --git a/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Control_Tester.cs b/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Control_Tester.cs deleted file mode 100644 index 7946cbf..0000000 --- a/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Control_Tester.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Sarand.BusinessMgr.Test.Web.Control.App -{ - //======================================================================= - [TestClass] - class SbmApplication_Control_Tester : SbmControlApp_Tester_Base - { - //------------------------------------------------------------------- - [TestMethod] - public void Test_SbmApplication_Control_CTR() - { - Assert.IsNotNull(App); - } - - //------------------------------------------------------------------- - } - //======================================================================= -} diff --git a/SaBusMgrTest_Control/Web/Control/App/SbmApplication_SessionData_Tester.cs b/SaBusMgrTest_Control/Web/Control/App/SbmApplication_SessionData_Tester.cs new file mode 100644 index 0000000..5d374ca --- /dev/null +++ b/SaBusMgrTest_Control/Web/Control/App/SbmApplication_SessionData_Tester.cs @@ -0,0 +1,94 @@ +using Microsoft.ApplicationInsights.Extensibility.Implementation; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Newtonsoft.Json; +using Sarand.BusinessMgr.Net.Core.Web.Controllers; +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.Mgr; +using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; +using Sarand.BusinessMgr.Web.Control.App; +using Sarand.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Security; +using Sarand.Net.Standard.Base.Utils; +using System; +using System.Collections.Generic; + +namespace Sarand.BusinessMgr.Test.Web.Control.App +{ + //======================================================================= + [TestClass] + public class SbmApplication_SessionData_Tester : SbmApplication_Tester_Base + { + //------------------------------------------------------------------- + // Data members. + + //------------------------------------------------------------------- + // Construction. + public SbmApplication_SessionData_Tester() + { + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_SessionData_Serialization() + { + using (DisposableCollection disposables = new DisposableCollection()) + { + // Internals. + SbmcAccountMgr accountMgr = Internals_Control.ControlAccountMgr; + Assert.IsNotNull(accountMgr); + + // User account. + SbmcUserAccount userAccount = accountMgr.GetUserAccountByEmailAddress("andy@sarand.com"); + disposables.Add(userAccount); + Assert.IsNotNull(userAccount); + + // Session Context? + SbmSessionContext? sessionContext_Core = null; + + // Populate User Session. + SbmSessionData_Control sessionData = new SbmSessionData_Control(sessionContext_Core, userAccount); + Assert.IsNotNull(sessionData); + Assert.IsTrue(!StringUtil.IsBlank(sessionData.Base64IV_ControlApp)); + Assert.IsTrue(sessionData.SessionIdx >= 100000); + Assert.IsTrue(sessionData.DataIdx >= 1000000); + + // Validate user session. + Assert.IsNotNull(sessionData.User); + + // User details. + Assert.AreEqual(userAccount.Id, sessionData.User.UserAccountId); + Assert.AreEqual(userAccount.EmailAddress, sessionData.User.EmailAddress); + Assert.AreEqual(userAccount.FirstName, sessionData.User.FirstName); + Assert.AreEqual(userAccount.LastName, sessionData.User.LastName); + Assert.AreEqual(userAccount.GetDisplayName(), sessionData.User.DisplayName); + + + // Serialise data. + string sessionDataJson = JsonConvert.SerializeObject(sessionData); + Assert.IsNotNull(sessionDataJson); + + // Deserialise data. + SbmSessionData_Control? sessionDataDeserialized = JsonConvert.DeserializeObject(sessionDataJson, SbmController_Web.SbmSessionDataJsonSerializerSettings); + Assert.IsNotNull(sessionDataDeserialized); + + // Validate deserialised data. + Assert.IsTrue(!StringUtil.IsBlank(sessionDataDeserialized.Base64IV_ControlApp)); + Assert.AreEqual(sessionData.Base64IV_ControlApp, sessionDataDeserialized.Base64IV_ControlApp); + Assert.AreEqual(sessionData.SessionIdx, sessionDataDeserialized.SessionIdx); + Assert.IsTrue(sessionDataDeserialized.DataIdx > sessionData.DataIdx); + + // User details. + Assert.IsNotNull(sessionDataDeserialized.User); + Assert.AreEqual(userAccount.Id, sessionDataDeserialized.User.UserAccountId); + Assert.AreEqual(userAccount.EmailAddress, sessionDataDeserialized.User.EmailAddress); + Assert.AreEqual(userAccount.FirstName, sessionDataDeserialized.User.FirstName); + Assert.AreEqual(userAccount.LastName, sessionDataDeserialized.User.LastName); + Assert.AreEqual(userAccount.GetDisplayName(), sessionDataDeserialized.User.DisplayName); + } + } + } + //======================================================================= +} diff --git a/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Tester.cs b/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Tester.cs new file mode 100644 index 0000000..1b29a6d --- /dev/null +++ b/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Tester.cs @@ -0,0 +1,145 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Sarand.BusinessMgr.Net.Core.Web.App; +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; +using Sarand.BusinessMgr.Net.Standard.Base.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; +using Sarand.BusinessMgr.Web.Control.Consoles; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Dbas; +using Sarand.Net.Standard.Base.Security; + +namespace Sarand.BusinessMgr.Test.Web.Control.App +{ + //======================================================================= + [TestClass] + public class SbmApplication_Tester : SbmApplication_Tester_Base + { + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_Application() + { + // Application. + Assert.IsNotNull(App); + Assert.IsNotNull(App_Web); + Assert.IsNotNull(App_Control); + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_ControlDatabase() + { + // Control database. + ISacsDatabase db = App.GetControlDatabase(); + Assert.IsNotNull(db); + + // Tables. + Assert.IsTrue(db.TableExists(SbmDbDfn_Control.GetTableName(SbmDbDfn_Control.TableIdx.Owner))); + Assert.IsTrue(db.TableExists(SbmDbDfn_Control.GetTableName(SbmDbDfn_Control.TableIdx.Repository))); + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_TemplateDatabase() + { + // Template database. + ISacsDatabase db = App.GetTemplateDatabase(); + Assert.IsNotNull(db); + + // Tables. + Assert.IsTrue(db.TableExists(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate))); + Assert.IsTrue(db.TableExists(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Commodity))); + Assert.IsTrue(db.TableExists(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Transaction, false))); + Assert.IsTrue(db.TableExists(SaSecurityDbDfn.GetTableName(SaSecurityDbDfn.TableIdx.SaSecItem))); + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_Internals_Control() + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + // Control internals. + Assert.IsNotNull(Internals_Control); + + // Owners. + Assert.IsNotNull(Internals_Control.ControlInstanceMgr); + SbmcOwner.Params prmOwner = new SbmcOwner.Params(); + prmOwner.StatusCat = SbmcOwner.StatusCat.ActiveOnly; + Assert.IsTrue(Internals_Control.ControlInstanceMgr.GetOwnerCount(prmOwner) > 0); + + // Repositories. + Assert.IsNotNull(Internals_Control.ControlInstanceMgr); + SbmcRepository.Params prmRepository = new SbmcRepository.Params(); + prmRepository.StatusCat = SbmcRepository.StatusCat.ActiveOnly; + Assert.IsTrue(Internals_Control.ControlInstanceMgr.GetRepositoryCount(prmRepository) > 0); + } + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_CoreInstanceConsole() + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + // Repository. + SbmcRepository repository = GetRandomActiveRepository(); + disposables.Add(repository); + Assert.IsNotNull(repository); + + // Instance console. + SbmCoreInstanceConsole_Base instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); + disposables.Add(instanceConsole); + Assert.IsNotNull(instanceConsole); + } + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_Internals_Core() + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + // Repository. + SbmcRepository repository = GetRandomActiveRepository(); + disposables.Add(repository); + Assert.IsNotNull(repository); + + // Instance console. + SbmCoreInstanceConsole_Base instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); + disposables.Add(instanceConsole); + Assert.IsNotNull(instanceConsole); + } + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_SessionContexts() + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + // Repository. + SbmcRepository repository = GetRandomActiveRepository(); + disposables.Add(repository); + Assert.IsNotNull(repository); + + SbmCoreInstanceConsole_Base instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); + disposables.Add(instanceConsole); + Assert.IsNotNull(instanceConsole); + + // Session Context. + ushort sessionIdx = App_Control.GetCoreSessionIndexForControlRepository(repository.OwnerId, repository.Id); + SbmSessionContext sessionContext = App_Control.GetSessionContextByIndex(sessionIdx); + Assert.IsNotNull(sessionContext); + Assert.AreEqual(sessionIdx, sessionContext.Index); + } + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Tester_Base.cs b/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Tester_Base.cs new file mode 100644 index 0000000..1475707 --- /dev/null +++ b/SaBusMgrTest_Control/Web/Control/App/SbmApplication_Tester_Base.cs @@ -0,0 +1,114 @@ +using DocumentFormat.OpenXml.EMMA; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Moq; +using Sarand.BusinessMgr.Net.Core.Web.App; +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; +using Sarand.BusinessMgr.Net.Standard.Base.Core; +using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; +using Sarand.BusinessMgr.Web.Control.App; +using Sarand.BusinessMgr.Web.Control.Consoles; +using Sarand.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Dbas; +using System; + +namespace Sarand.BusinessMgr.Test.Web.Control.App +{ + //======================================================================= + public class SbmApplication_Tester_Base : SacsDisposable + { + //------------------------------------------------------------------- + // Application. + private class SbmApplication_Control_Test : SbmApplication_Control + { + public SbmApplication_Control_Test(IConfiguration configuration, IWebHostEnvironment env) : + base(configuration) + { + InitEnvironment(env); + } + } + + //------------------------------------------------------------------- + // Data members. + + //------------------------------------------------------------------- + // Construction. + protected SbmApplication_Tester_Base() + { + // Application. + Mock mockConfiguration = new Mock(); + Mock mockEnvironment = new Mock(); + mockEnvironment.Setup(m => m.EnvironmentName).Returns(Environments.Development); + mockEnvironment.Setup(m => m.ContentRootPath).Returns(@"D:\Sarand\Projects\Users\AHoward\VS2022\BusinessMgr\Workspace\SaBusinessMgrCoreWebControl"); + App_Control = new SbmApplication_Control_Test(mockConfiguration.Object, mockEnvironment.Object); + Internals_Control = new SbmInternals_Control(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + Internals_Control.Dispose(); + } + } + + //------------------------------------------------------------------- + // Properties. + protected SbmApplication App { get { return App_Control; } } + protected SbmApplication_Web App_Web { get { return App_Control; } } + protected SbmApplication_Control App_Control { get; } + protected SbmSessionData_Control SessionData_Control { get; } + protected SbmInternals_Control Internals_Control { get; } + + // Utilities. + protected SbmInternals_Control CreateInternalsControl() { return new SbmInternals_Control(); } + + //------------------------------------------------------------------- + // Core Instance Console. + protected SbmCoreInstanceConsole_Control CreateCoreInstanceConsole(String instanceContext) + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + SbmcRepository repository = Internals_Control.ControlInstanceMgr.GetRepositoryByContext(instanceContext); + disposables.Add(repository); + return new SbmCoreInstanceConsole_Control(SessionData_Control, repository); + } + } + + //------------------------------------------------------------------- + // Repositories. + + /// + /// Retrieve an active repository, randomly selected. + /// + protected SbmcRepository GetRandomActiveRepository() + { + // Repository. + SbmcRepository.Params prmRepository = new SbmcRepository.Params(); + prmRepository.StatusCat = SbmcRepository.StatusCat.ActiveOnly; + prmRepository.RandomOrder = true; + prmRepository.ResultsPaging.Set(1, 1); + return Internals_Control.ControlInstanceMgr.GetRepositoryList(prmRepository).First(); + } + + /// + /// Retrieve an active repository by context. + /// + protected SbmcRepository GetActiveRepositoryByContext(String repositoryContext) + { + // Repository. + SbmcRepository.Params prmRepository = new SbmcRepository.Params(); + prmRepository.ContextsIncluded.Add(repositoryContext); + prmRepository.StatusCat = SbmcRepository.StatusCat.ActiveOnly; + prmRepository.ResultsPaging.Set(1, 1); + return Internals_Control.ControlInstanceMgr.GetRepositoryList(prmRepository).First(); + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusMgrTest_Control/Web/Control/App/SbmSessionData_Control_Test.cs b/SaBusMgrTest_Control/Web/Control/App/SbmSessionData_Control_Test.cs deleted file mode 100644 index 3987904..0000000 --- a/SaBusMgrTest_Control/Web/Control/App/SbmSessionData_Control_Test.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Microsoft.ApplicationInsights.Extensibility.Implementation; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; -using Sarand.BusinessMgr.Net.Core.Web.Controllers; -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.Mgr; -using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; -using Sarand.BusinessMgr.Web.Control.App; -using Sarand.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.Security; -using Sarand.Net.Standard.Base.Utils; -using System; -using System.Collections.Generic; - -namespace Sarand.BusinessMgr.Test.Web.Control.App -{ - //======================================================================= - [TestClass] - public class SbmSessionData_Control_Test : SbmControlApp_Tester_Base - { - //------------------------------------------------------------------- - // Data members. - - //------------------------------------------------------------------- - // Construction. - public SbmSessionData_Control_Test() - { - } - - //------------------------------------------------------------------- - [TestMethod] - public void Test_SbmSessionData_Control_Serialization() - { - - // Internals. - SbmcAccountMgr accountMgr = Internals_Control.ControlAccountMgr; - Assert.IsNotNull(accountMgr); - - // User account. - SbmcUserAccount userAccount = accountMgr.GetUserAccountByEmailAddress("andy@sarand.com"); - Assert.IsNotNull(userAccount); - - // Session Context? - SbmSessionContext sessionContext_Core = null; - - // Populate User Session. - SbmSessionData_Control sessionData = new SbmSessionData_Control(sessionContext_Core, userAccount); - Assert.IsNotNull(sessionData); - Assert.IsTrue(!StringUtil.IsBlank(sessionData.Base64IV_ControlApp)); - Assert.IsTrue(sessionData.SessionIdx >= 1000); - Assert.IsTrue(sessionData.ItemIdx >= 1000); - - // Validate user session. - Assert.IsNotNull(sessionData.User); - - // User details. - Assert.AreEqual(userAccount.Id, sessionData.User.UserAccountId); - Assert.AreEqual(userAccount.EmailAddress, sessionData.User.EmailAddress); - Assert.AreEqual(userAccount.FirstName, sessionData.User.FirstName); - Assert.AreEqual(userAccount.LastName, sessionData.User.LastName); - Assert.AreEqual(userAccount.GetDisplayName(), sessionData.User.DisplayName); - - - // Serialise data. - string sessionDataJson = JsonConvert.SerializeObject(sessionData); - Assert.IsNotNull(sessionDataJson); - - // Deserialise data. - SbmSessionData_Control? sessionDataDeserialized = JsonConvert.DeserializeObject(sessionDataJson, SbmController_Web.SbmSessionDataJsonSerializerSettings); - Assert.IsNotNull(sessionDataDeserialized); - - // Validate deserialised data. - Assert.IsTrue(!StringUtil.IsBlank(sessionDataDeserialized.Base64IV_ControlApp)); - Assert.AreEqual(sessionData.Base64IV_ControlApp, sessionDataDeserialized.Base64IV_ControlApp); - Assert.AreEqual(sessionData.SessionIdx, sessionDataDeserialized.SessionIdx); - Assert.AreEqual(sessionData.ItemIdx, sessionDataDeserialized.ItemIdx); - - // User details. - Assert.IsNotNull(sessionDataDeserialized.User); - Assert.AreEqual(userAccount.Id, sessionDataDeserialized.User.UserAccountId); - Assert.AreEqual(userAccount.EmailAddress, sessionDataDeserialized.User.EmailAddress); - Assert.AreEqual(userAccount.FirstName, sessionDataDeserialized.User.FirstName); - Assert.AreEqual(userAccount.LastName, sessionDataDeserialized.User.LastName); - Assert.AreEqual(userAccount.GetDisplayName(), sessionDataDeserialized.User.DisplayName); - } - } - //======================================================================= -} diff --git a/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Database_Tester.cs b/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Database_Tester.cs index 09d3fad..a8be453 100644 --- a/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Database_Tester.cs +++ b/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Database_Tester.cs @@ -1,6 +1,8 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Sarand.BusinessMgr.Net.Core.Web.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Helpers; using Sarand.Net.Standard.Base.Security; @@ -12,7 +14,7 @@ namespace Sarand.BusinessMgr.Test.Web.Portal.App { //======================================================================= [TestClass] - public class SbmApplication_Database_Tester : SbmPortalApp_Tester_Base + public class SbmApplication_Database_Tester : SbmApplication_Tester_Base { //------------------------------------------------------------------- private static Regex reHex = new Regex("^(?:[A-F0-9]{2})+$", RegexOptions.IgnoreCase); @@ -21,15 +23,24 @@ namespace Sarand.BusinessMgr.Test.Web.Portal.App [TestMethod] public void Test_PasswordEncoding() { - using (SbmSecurityConsole_Web securityConsole = new SbmSecurityConsole_Web(UserContext)) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) { + // Session configuration. + string repositoryContext = "Mimo"; + SbmSessionContext sessionContext = CreateCoreInstanceConsole(repositoryContext); + Assert.IsNotNull(sessionContext); + SbmInternals internals = new SbmInternals(GetSessionData(sessionContext, repositoryContext)); + disposables.Add(internals); + + SaSecurityConsole securityConsole = internals.SecurityConsole; - Assert.IsNotNull(BusMgrDatabase); StringAssert.Matches(securityConsole.EncodePassword_Hex(""), reHex); // Iterate using random filename (8.3). for (int i = 0; i < 1000; i++) StringAssert.Matches(securityConsole.EncodePassword_Hex(Path.GetRandomFileName()), reHex); + } } @@ -37,11 +48,19 @@ namespace Sarand.BusinessMgr.Test.Web.Portal.App [TestMethod] public void Test_PasswordCompare() { - Assert.IsNotNull(BusMgrDatabase); Dictionary passwordHashes = new Dictionary(); - using (SbmSecurityConsole_Web securityConsole = new SbmSecurityConsole_Web(UserContext)) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) { + // Session configuration. + string repositoryContext = "Mimo"; + SbmSessionContext sessionContext = CreateCoreInstanceConsole(repositoryContext); + Assert.IsNotNull(sessionContext); + SbmInternals internals = new SbmInternals(GetSessionData(sessionContext, repositoryContext)); + disposables.Add(internals); + + SaSecurityConsole securityConsole = internals.SecurityConsole; // Iterate using random filename (8.3). for (int i = 0; i < 200; i++) diff --git a/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Portal_Tester.cs b/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Portal_Tester.cs index cb0ef2e..db62d73 100644 --- a/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Portal_Tester.cs +++ b/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Portal_Tester.cs @@ -1,17 +1,84 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; +using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Dbas; +using Sarand.Net.Standard.Base.Security; +using Sarand.Net.Standard.Dbas.Base; namespace Sarand.BusinessMgr.Test.Web.Portal.App { - //======================================================================= - [TestClass] - class SbmApplication_Portal_Tester : SbmPortalApp_Tester_Base - { - //------------------------------------------------------------------- - [TestMethod] - public void Test_SbmApplication_Portal_CTR() - { - Assert.IsNotNull(App); - } + //======================================================================= + [TestClass] + public class SbmApplication_Portal_Tester : SbmApplication_Tester_Base + { + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_Application() + { + // Application. + Assert.IsNotNull(App); + Assert.IsNotNull(AppWeb); + Assert.IsNotNull(AppPortal); + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_ControlDatabase() + { + // Control database. + ISacsDatabase db = App.GetControlDatabase(); + Assert.IsNotNull(db); + + // Tables. + Assert.IsTrue(db.TableExists(SbmDbDfn_Control.GetTableName(SbmDbDfn_Control.TableIdx.Owner))); + Assert.IsTrue(db.TableExists(SbmDbDfn_Control.GetTableName(SbmDbDfn_Control.TableIdx.Repository))); + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_TemplateDatabase() + { + // Template database. + ISacsDatabase db = App.GetTemplateDatabase(); + Assert.IsNull(db); + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_ControlInternals() + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + // Control database. + SbmInternals_Control internalsControl = new SbmInternals_Control(); + disposables.Add(internalsControl); + Assert.IsNotNull(internalsControl); + + // Owners. + Assert.IsNotNull(internalsControl.ControlInstanceMgr); + SbmcOwner.Params prmOwner = new SbmcOwner.Params(); + Assert.IsTrue(internalsControl.ControlInstanceMgr.GetOwnerCount(prmOwner) > 0); + + // Repositories. + Assert.IsNotNull(internalsControl.ControlInstanceMgr); + SbmcRepository.Params prmRepository = new SbmcRepository.Params(); + Assert.IsTrue(internalsControl.ControlInstanceMgr.GetRepositoryCount(prmRepository) > 0); + } + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_SessionContexts() + { + SbmSessionContext sesionContext = AppPortal.GetControlSessionContextByRepositoryContext("Unknown"); + Assert.IsNull(sesionContext); + + sesionContext = AppPortal.GetControlSessionContextByRepositoryContext("Mimo"); + Assert.IsNotNull(sesionContext); + } //------------------------------------------------------------------- } diff --git a/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_SessionData_Tester.cs b/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_SessionData_Tester.cs new file mode 100644 index 0000000..f11d7a2 --- /dev/null +++ b/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_SessionData_Tester.cs @@ -0,0 +1,160 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Newtonsoft.Json; +using Sarand.BusinessMgr.Net.Core.Web.Controllers; +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Bus; +using Sarand.BusinessMgr.Net.Standard.Base.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.Mgr; +using Sarand.BusinessMgr.Web.Portal.App; +using Sarand.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Dbas; +using Sarand.Net.Standard.Base.Helpers; +using Sarand.Net.Standard.Base.Security; +using Sarand.Net.Standard.Base.Utils; +using System; +using System.Collections.Generic; + +namespace Sarand.BusinessMgr.Test.Web.Portal.App +{ + //======================================================================= + [TestClass] + public class SbmApplication_SessionData_Tester : SbmApplication_Tester_Base + { + //------------------------------------------------------------------- + // Data members. + + //------------------------------------------------------------------- + // Construction. + public SbmApplication_SessionData_Tester() + { + } + + //------------------------------------------------------------------- + [TestMethod] + public void Test_Application_SessionData_Serialization() + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + // Session configuration. + string repositoryContext = "Mimo"; + SbmSessionContext sessionContext = CreateCoreInstanceConsole(repositoryContext); + Assert.IsNotNull(sessionContext); + SbmInternals internals = new SbmInternals(GetSessionData(sessionContext, repositoryContext)); + disposables.Add(internals); + ISacsDatabase busMgrDatabase = AppPortal.GetBusMgrDatabase(sessionContext); + + // Internals. + SaSecurityConsole securityConsole = internals.SecurityConsole; + Assert.IsNotNull(securityConsole); + securityConsole.RegisterSecurityRights(); + SbmAccountMgr accountMgr = internals.AccountMgr; + Assert.IsNotNull(accountMgr); + + // Session Console. + SbmSessionConsole sessionConsole = SbmSessionConsole.CreateConsole(internals.UserContext); + + // Security item. + SaSecurityItem securityItemUser = securityConsole.GetUserByEmail("andy@sarand.com"); + Assert.IsNotNull(securityItemUser); + + // Security profile. + + // User account. + SbmAffiliate affiliateUser = accountMgr.GetAffiliateByUserId(securityItemUser.Id); + Assert.IsNotNull(affiliateUser); + + // Organisations. + List supervisedOrganisations = accountMgr.GetAffiliatesSupervisedBy(affiliateUser.Id); + Assert.IsNotNull(supervisedOrganisations); + Assert.IsTrue(supervisedOrganisations.Count > 0); + SysId affiliateIdOrganisation = supervisedOrganisations[0].Id; + SbmAssociation associationOrganisation = accountMgr.GetAssociationByOwnerTypeTarget(affiliateIdOrganisation, Sbm.AssociationType.Internal, affiliateIdOrganisation); + Assert.IsNotNull(associationOrganisation); + SbmAffiliate affiliateOrganisation = accountMgr.GetAffiliateById(affiliateIdOrganisation); + Assert.IsNotNull(affiliateOrganisation); + + + // Populate User Session. + SbmSessionData_Portal sessionData = new SbmSessionData_Portal(sessionContext, repositoryContext, securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation); + Assert.IsNotNull(sessionData); + + // Validate user session. + Assert.IsNotNull(sessionData.User); + + // Security item. + Assert.AreEqual(securityItemUser.Id, sessionData.User.SecurityItemId); + Assert.AreEqual(securityItemUser.EmailAddress, sessionData.User.EmailAddress); + + // Security profile. + sessionData.SecurityProfile_Core.RefreshProfile(sessionConsole, securityConsole, securityItemUser.Id, securityConsole.GetRegisteredRights()); + Assert.IsTrue(sessionData.SecurityProfile_Core.UserCanCreateContacts()); + Assert.IsTrue(sessionData.SecurityProfile_Core.UserCanViewFinancials()); + + // User details. + Assert.AreEqual(affiliateUser.Id, sessionData.User.AffiliateId); + Assert.AreEqual(affiliateUser.FirstName, sessionData.User.FirstName); + Assert.AreEqual(affiliateUser.LastName, sessionData.User.LastName); + Assert.AreEqual(affiliateUser.GetDisplayName(), sessionData.User.DisplayName); + + // Organisation details. + Assert.AreEqual(affiliateOrganisation.Id, sessionData.OrganisationAffiliateId); + Assert.AreEqual(associationOrganisation.Id, sessionData.OrganisationAssociationId); + + // User profile. + sessionData.Profile.Filter.AssociationId = new SysId(SacsRandomHelper.GetInt32(1000, 1999)); + + + // Serialise data. + string sessionDataJson = JsonConvert.SerializeObject(sessionData); + Assert.IsNotNull(sessionDataJson); + + // Deserialise data. + SbmSessionData_Portal sessionDataDeserialized = JsonConvert.DeserializeObject(sessionDataJson, SbmController_Web.SbmSessionDataJsonSerializerSettings); + Assert.IsNotNull(sessionDataDeserialized); + string sessionDataJsonDeserialized = JsonConvert.SerializeObject(sessionDataDeserialized); + + // Validate deserialised data. + Assert.IsTrue(!StringUtil.IsBlank(sessionData.Base64IV_PortalApp)); + Assert.IsTrue(!StringUtil.IsBlank(sessionDataDeserialized.Base64IV_PortalApp)); + Assert.AreEqual(sessionData.Base64IV_PortalApp, sessionDataDeserialized.Base64IV_PortalApp); + Assert.IsTrue(sessionData.SessionIdx >= 1000); + Assert.AreEqual(sessionData.SessionIdx, sessionDataDeserialized.SessionIdx); + Assert.IsTrue(sessionData.DataIdx >= 1000000); + Assert.IsTrue(sessionDataDeserialized.DataIdx > sessionData.DataIdx); + Assert.AreEqual(repositoryContext, sessionDataDeserialized.RepositoryContext); + + // Security item. + Assert.IsNotNull(sessionDataDeserialized.User); + Assert.AreEqual(securityItemUser.Id, sessionDataDeserialized.User.SecurityItemId); + Assert.AreEqual(securityItemUser.EmailAddress, sessionDataDeserialized.User.EmailAddress); + + // Security profile. + sessionData.SecurityProfile_Core.RefreshProfile(sessionConsole, securityConsole, securityItemUser.Id, securityConsole.GetRegisteredRights()); + Assert.IsNotNull(sessionDataDeserialized.SecurityProfile_Core); + Assert.AreEqual(sessionData.SecurityProfile_Core.UserCanCreateContacts(), sessionDataDeserialized.SecurityProfile_Core.UserCanCreateContacts()); + Assert.IsTrue(sessionDataDeserialized.SecurityProfile_Core.UserCanCreateContacts()); + Assert.AreEqual(sessionData.SecurityProfile_Core.UserCanViewFinancials(), sessionDataDeserialized.SecurityProfile_Core.UserCanViewFinancials()); + Assert.IsTrue(sessionDataDeserialized.SecurityProfile_Core.UserCanViewFinancials()); + + // User details. + Assert.AreEqual(affiliateUser.Id, sessionDataDeserialized.User.AffiliateId); + Assert.AreEqual(affiliateUser.FirstName, sessionDataDeserialized.User.FirstName); + Assert.AreEqual(affiliateUser.LastName, sessionDataDeserialized.User.LastName); + Assert.AreEqual(affiliateUser.GetDisplayName(), sessionDataDeserialized.User.DisplayName); + + // Organisation details. + Assert.AreEqual(affiliateOrganisation.Id, sessionDataDeserialized.Organisation.AffiliateId); + Assert.AreEqual(associationOrganisation.Id, sessionDataDeserialized.Organisation.AssociationId); + Assert.AreEqual(affiliateOrganisation.Name, sessionDataDeserialized.Organisation.DisplayName); + + // User profile. + Assert.IsTrue(SysId.ToLong(sessionData.Profile.Filter.AssociationId) >= 1000); + Assert.AreEqual(sessionData.Profile.Filter.AssociationId, sessionDataDeserialized.Profile.Filter.AssociationId); + + } + } + } + //======================================================================= +} diff --git a/SaBusMgrTest_Control/Web/Control/App/SbmControlApp_Tester_Base.cs b/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Tester_Base.cs similarity index 59% rename from SaBusMgrTest_Control/Web/Control/App/SbmControlApp_Tester_Base.cs rename to SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Tester_Base.cs index 4cccda5..0655f25 100644 --- a/SaBusMgrTest_Control/Web/Control/App/SbmControlApp_Tester_Base.cs +++ b/SaBusMgrTest_Portal/Web/Portal/App/SbmApplication_Tester_Base.cs @@ -6,23 +6,23 @@ using Moq; using Sarand.BusinessMgr.Net.Core.Web.App; using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; +using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; -using Sarand.BusinessMgr.Web.Control.App; -using Sarand.BusinessMgr.Web.Control.Consoles; +using Sarand.BusinessMgr.Web.Portal.App; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; using System; -namespace Sarand.BusinessMgr.Test.Web.Control.App +namespace Sarand.BusinessMgr.Test.Web.Portal.App { //======================================================================= - public class SbmControlApp_Tester_Base + public class SbmApplication_Tester_Base : SacsDisposable { //------------------------------------------------------------------- // Application. - private class SbmApplication_Control_Test : SbmApplication_Control + private class SbmApplication_Portal_Test : SbmApplication_Portal { - public SbmApplication_Control_Test(IConfiguration configuration, IWebHostEnvironment env) : + public SbmApplication_Portal_Test(IConfiguration configuration, IWebHostEnvironment env) : base(configuration) { InitEnvironment(env); @@ -34,42 +34,45 @@ namespace Sarand.BusinessMgr.Test.Web.Control.App //------------------------------------------------------------------- // Construction. - protected SbmControlApp_Tester_Base() + protected SbmApplication_Tester_Base() { // Application. Mock mockConfiguration = new Mock(); Mock mockEnvironment = new Mock(); mockEnvironment.Setup(m => m.EnvironmentName).Returns(Environments.Development); - mockEnvironment.Setup(m => m.ContentRootPath).Returns(@"D:\Sarand\Projects\Users\AHoward\VS2022\BusinessMgr\Workspace\SaBusinessMgrCoreWebControl"); - App = new SbmApplication_Control_Test(mockConfiguration.Object, mockEnvironment.Object); + mockEnvironment.Setup(m => m.ContentRootPath).Returns(@"D:\Sarand\Projects\Users\AHoward\VS2022\BusinessMgr\Workspace\SaBusinessMgrCoreWebPortal"); + AppPortal = new SbmApplication_Portal_Test(mockConfiguration.Object, mockEnvironment.Object); Internals_Control = new SbmInternals_Control(); } + protected override void Dispose(bool disposing) + { + if (disposing) + { + Internals_Control.Dispose(); + } + } + //------------------------------------------------------------------- // Properties. - protected SbmApplication_Control App { get; } + protected SbmApplication App { get { return AppPortal; } } + protected SbmApplication_Web AppWeb { get { return AppPortal; } } + protected SbmApplication_Portal AppPortal { get; } protected SbmInternals_Control Internals_Control { get; } //------------------------------------------------------------------- // User Context. - public static SbmUserContext GetUserContext(SbmSessionContext sessionContext) + public static SbmSessionData_Portal GetSessionData(SbmSessionContext sessionContext, String repositoryContext) { - SbmUserContext userContext = new SbmUserContext_Web(sessionContext); - - return userContext; + SbmSessionData_Portal sessionData = new SbmSessionData_Portal(sessionContext, repositoryContext, null, null, null, null); + return sessionData; } //------------------------------------------------------------------- - // Core Instance Console. - protected SbmCoreInstanceConsole_Control CreateCoreInstanceConsole(String instanceContext) + // Session Context. + protected SbmSessionContext CreateCoreInstanceConsole(String instanceContext) { - // Record disposable items as they are created so all can be disposed when needed. - using (DisposableCollection disposables = new DisposableCollection()) - { - SbmcRepository repository = Internals_Control.ControlInstanceMgr.GetRepositoryByContext(instanceContext); - disposables.Add(repository); - return new SbmCoreInstanceConsole_Control(repository); - } + return AppPortal.GetControlSessionContextByRepositoryContext(instanceContext); } //------------------------------------------------------------------- diff --git a/SaBusMgrTest_Portal/Web/Portal/App/SbmPortalApp_Tester_Base.cs b/SaBusMgrTest_Portal/Web/Portal/App/SbmPortalApp_Tester_Base.cs deleted file mode 100644 index 11ea432..0000000 --- a/SaBusMgrTest_Portal/Web/Portal/App/SbmPortalApp_Tester_Base.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Hosting; -using Moq; -using Sarand.BusinessMgr.Net.Core.Web.App; -using Sarand.BusinessMgr.Net.Standard.Base.App; -using Sarand.BusinessMgr.Web.Portal.App; -using Sarand.Net.Standard.Base.Dbas; - -namespace Sarand.BusinessMgr.Test.Web.Portal.App -{ - //======================================================================= - public class SbmPortalApp_Tester_Base - { - //------------------------------------------------------------------- - // Application. - private class SbmApplication_Portal_Test : SbmApplication_Portal - { - public SbmApplication_Portal_Test(IConfiguration configuration, IWebHostEnvironment env) : - base(configuration) - { - InitEnvironment(env); - } - } - - //------------------------------------------------------------------- - // Data members. - - //------------------------------------------------------------------- - // Construction. - protected SbmPortalApp_Tester_Base() - { - // Application. - Mock mockConfiguration = new Mock(); - Mock mockEnvironment = new Mock(); - mockEnvironment.Setup(m => m.EnvironmentName).Returns(Environments.Development); - mockEnvironment.Setup(m => m.ContentRootPath).Returns(@"D:\Sarand\Projects\Users\AHoward\VS2022\BusinessMgr\Workspace\SaBusinessMgrCoreWebPortal"); - App = new SbmApplication_Portal_Test(mockConfiguration.Object, mockEnvironment.Object); - - // Session configuration. - SessionContextIdx = App.GetSessionContextIdxs()[0]; - SessionContext = App.GetSessionContextByIndex(SessionContextIdx); - Internals = new SbmInternals(GetUserContext(SessionContext)); - UserContext = GetUserContext(SessionContext); - } - - //------------------------------------------------------------------- - // Properties. - protected ushort SessionContextIdx { get; } - protected SbmApplication_Portal App { get; } - protected SbmSessionContext SessionContext { get; } - protected ISacsDatabase BusMgrDatabase { get { return App.GetBusMgrDatabase(SessionContext); } } - protected SbmInternals Internals { get; } - protected SbmUserContext UserContext { get; } - - //------------------------------------------------------------------- - // User Context. - public static SbmUserContext GetUserContext(SbmSessionContext sessionContext) - { - SbmUserContext userContext = new SbmUserContext_Web(sessionContext); - - return userContext; - } - - //------------------------------------------------------------------- - } - //======================================================================= -} diff --git a/SaBusMgrTest_Portal/Web/Portal/App/SbmSessionData_Portal_Test.cs b/SaBusMgrTest_Portal/Web/Portal/App/SbmSessionData_Portal_Test.cs deleted file mode 100644 index e9c9dff..0000000 --- a/SaBusMgrTest_Portal/Web/Portal/App/SbmSessionData_Portal_Test.cs +++ /dev/null @@ -1,149 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; -using Sarand.BusinessMgr.Net.Core.Web.Controllers; -using Sarand.BusinessMgr.Net.Standard.Base.App; -using Sarand.BusinessMgr.Net.Standard.Base.Bus; -using Sarand.BusinessMgr.Net.Standard.Base.Consoles; -using Sarand.BusinessMgr.Net.Standard.Base.Mgr; -using Sarand.BusinessMgr.Web.Portal.App; -using Sarand.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.Helpers; -using Sarand.Net.Standard.Base.Security; -using Sarand.Net.Standard.Base.Utils; -using System; -using System.Collections.Generic; - -namespace Sarand.BusinessMgr.Test.Web.Portal.App -{ - //======================================================================= - [TestClass] - public class SbmSessionData_Portal_Test : SbmPortalApp_Tester_Base - { - //------------------------------------------------------------------- - // Data members. - - //------------------------------------------------------------------- - // Construction. - public SbmSessionData_Portal_Test() - { - } - - //------------------------------------------------------------------- - [TestMethod] - public void Test_SbmSessionData_Portal_Serialization() - { - - // Internals. - SaSecurityConsole securityConsole = App.CreateSecurityConsole(UserContext); - Assert.IsNotNull(securityConsole); - securityConsole.RegisterSecurityRights(); - SbmAccountMgr accountMgr = Internals.AccountMgr; - Assert.IsNotNull(accountMgr); - - // Session Console. - SbmSessionConsole sessionConsole = SbmSessionConsole.CreateConsole(UserContext); - - // Database context. - string repositoryContext = "SBMDB4321"; - - // Security item. - SaSecurityItem securityItemUser = securityConsole.GetUserByEmail("andy@sarand.com"); - Assert.IsNotNull(securityItemUser); - - // Security profile. - - // User account. - SbmAffiliate affiliateUser = accountMgr.GetAffiliateByUserId(securityItemUser.Id); - Assert.IsNotNull(affiliateUser); - - // Organisations. - List supervisedOrganisations = accountMgr.GetAffiliatesSupervisedBy(affiliateUser.Id); - Assert.IsNotNull(supervisedOrganisations); - Assert.IsTrue(supervisedOrganisations.Count > 0); - SysId affiliateIdOrganisation = supervisedOrganisations[0].Id; - SbmAssociation associationOrganisation = accountMgr.GetAssociationByOwnerTypeTarget(affiliateIdOrganisation, Sbm.AssociationType.Internal, affiliateIdOrganisation); - Assert.IsNotNull(associationOrganisation); - SbmAffiliate affiliateOrganisation = accountMgr.GetAffiliateById(affiliateIdOrganisation); - Assert.IsNotNull(affiliateOrganisation); - - - // Populate User Session. - SbmSessionData_Portal sessionData = new SbmSessionData_Portal(SessionContext, repositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation); - Assert.IsNotNull(sessionData); - - // Validate user session. - Assert.IsNotNull(sessionData.User); - - // Security item. - Assert.AreEqual(securityItemUser.Id, sessionData.User.SecurityItemId); - Assert.AreEqual(securityItemUser.EmailAddress, sessionData.User.EmailAddress); - - // Security profile. - sessionData.SecurityProfile_Core.RefreshProfile(sessionConsole, securityConsole, securityItemUser.Id, securityConsole.GetRegisteredRights()); - Assert.IsTrue(sessionData.SecurityProfile_Core.UserCanCreateContacts()); - Assert.IsTrue(sessionData.SecurityProfile_Core.UserCanViewFinancials()); - - // User details. - Assert.AreEqual(affiliateUser.Id, sessionData.User.AffiliateId); - Assert.AreEqual(affiliateUser.FirstName, sessionData.User.FirstName); - Assert.AreEqual(affiliateUser.LastName, sessionData.User.LastName); - Assert.AreEqual(affiliateUser.GetDisplayName(), sessionData.User.DisplayName); - - // Organisation details. - Assert.AreEqual(affiliateOrganisation.Id, sessionData.OrganisationAffiliateId); - Assert.AreEqual(associationOrganisation.Id, sessionData.OrganisationAssociationId); - - // User profile. - sessionData.Profile.Filter.AssociationId = new SysId(SacsRandomHelper.GetInt32(1000, 1999)); - - - // Serialise data. - string sessionDataJson = JsonConvert.SerializeObject(sessionData); - Assert.IsNotNull(sessionDataJson); - - // Deserialise data. - SbmSessionData_Portal sessionDataDeserialized = JsonConvert.DeserializeObject(sessionDataJson, SbmController_Web.SbmSessionDataJsonSerializerSettings); - Assert.IsNotNull(sessionDataDeserialized); - string sessionDataJsonDeserialized = JsonConvert.SerializeObject(sessionDataDeserialized); - - // Validate deserialised data. - Assert.IsTrue(!StringUtil.IsBlank(sessionData.Base64IV_PortalApp)); - Assert.IsTrue(!StringUtil.IsBlank(sessionDataDeserialized.Base64IV_PortalApp)); - Assert.AreEqual(sessionData.Base64IV_PortalApp, sessionDataDeserialized.Base64IV_PortalApp); - Assert.IsTrue(sessionData.SessionIdx >= 1000); - Assert.AreEqual(sessionData.SessionIdx, sessionDataDeserialized.SessionIdx); - Assert.IsTrue(sessionData.ItemIdx >= 1000); - Assert.AreEqual(sessionData.ItemIdx, sessionDataDeserialized.ItemIdx); - Assert.AreEqual(repositoryContext, sessionDataDeserialized.RepositoryContext); - - // Security item. - Assert.IsNotNull(sessionDataDeserialized.User); - Assert.AreEqual(securityItemUser.Id, sessionDataDeserialized.User.SecurityItemId); - Assert.AreEqual(securityItemUser.EmailAddress, sessionDataDeserialized.User.EmailAddress); - - // Security profile. - sessionData.SecurityProfile_Core.RefreshProfile(sessionConsole, securityConsole, securityItemUser.Id, securityConsole.GetRegisteredRights()); - Assert.IsNotNull(sessionDataDeserialized.SecurityProfile_Core); - Assert.AreEqual(sessionData.SecurityProfile_Core.UserCanCreateContacts(), sessionDataDeserialized.SecurityProfile_Core.UserCanCreateContacts()); - Assert.IsTrue(sessionDataDeserialized.SecurityProfile_Core.UserCanCreateContacts()); - Assert.AreEqual(sessionData.SecurityProfile_Core.UserCanViewFinancials(), sessionDataDeserialized.SecurityProfile_Core.UserCanViewFinancials()); - Assert.IsTrue(sessionDataDeserialized.SecurityProfile_Core.UserCanViewFinancials()); - - // User details. - Assert.AreEqual(affiliateUser.Id, sessionDataDeserialized.User.AffiliateId); - Assert.AreEqual(affiliateUser.FirstName, sessionDataDeserialized.User.FirstName); - Assert.AreEqual(affiliateUser.LastName, sessionDataDeserialized.User.LastName); - Assert.AreEqual(affiliateUser.GetDisplayName(), sessionDataDeserialized.User.DisplayName); - - // Organisation details. - Assert.AreEqual(affiliateOrganisation.Id, sessionDataDeserialized.Organisation.AffiliateId); - Assert.AreEqual(associationOrganisation.Id, sessionDataDeserialized.Organisation.AssociationId); - Assert.AreEqual(affiliateOrganisation.Name, sessionDataDeserialized.Organisation.DisplayName); - - // User profile. - Assert.IsTrue(SysId.ToLong(sessionData.Profile.Filter.AssociationId) >= 1000); - Assert.AreEqual(sessionData.Profile.Filter.AssociationId, sessionDataDeserialized.Profile.Filter.AssociationId); - } - } - //======================================================================= -} diff --git a/SaBusinessMgrCoreWebControl/Control/App/SbmApplication_Control.cs b/SaBusinessMgrCoreWebControl/Control/App/SbmApplication_Control.cs index 86a96e9..898a8ec 100644 --- a/SaBusinessMgrCoreWebControl/Control/App/SbmApplication_Control.cs +++ b/SaBusinessMgrCoreWebControl/Control/App/SbmApplication_Control.cs @@ -93,7 +93,7 @@ namespace Sarand.BusinessMgr.Web.Control.App try { propertySet = new PropertySet(); - SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Web(propertySet))); + SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Control(this, propertySet))); Configuration = configuration; } catch (Exception exc) @@ -193,19 +193,9 @@ namespace Sarand.BusinessMgr.Web.Control.App // Consoles. //------------------------------------------------------------------- - public override SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext) + public static SbmEmailConsole_Control CreateEmailConsole_Control(SbmEmailConfig emailConfig) { - return new SbmSecurityConsole_Web(userContext); - } - - public override SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext) - { - return null; - } - - public override SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext) - { - return new SbmEmailConsole_Control(EmailConfig); + return new SbmEmailConsole_Control(emailConfig); } //------------------------------------------------------------------- diff --git a/SaBusinessMgrCoreWebControl/Control/App/SbmSessionData_Control.cs b/SaBusinessMgrCoreWebControl/Control/App/SbmSessionData_Control.cs index 1491731..82f4850 100644 --- a/SaBusinessMgrCoreWebControl/Control/App/SbmSessionData_Control.cs +++ b/SaBusinessMgrCoreWebControl/Control/App/SbmSessionData_Control.cs @@ -14,17 +14,18 @@ using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Utils; using DocumentFormat.OpenXml.Wordprocessing; +using Sarand.BusinessMgr.Net.Standard.Base.Core; namespace Sarand.BusinessMgr.Web.Control.App { //======================================================================= - public class SbmSessionData_Control : SbmSessionData_Web + public class SbmSessionData_Control : SbmSessionData_Web, ISbmSessionData_Control { //------------------------------------------------------------------- // Construction. [JsonConstructor] - private SbmSessionData_Control(long sessionIdx, int itemIdx, SbmSessionContext sessionContext) : - base(sessionIdx, itemIdx, sessionContext) + private SbmSessionData_Control(long sessionIdx, SbmSessionContext sessionContext) : + base(sessionIdx, sessionContext) { } /// /// SessionData construction. diff --git a/SaBusinessMgrCoreWebControl/Control/App/SbmSystem_Control.cs b/SaBusinessMgrCoreWebControl/Control/App/SbmSystem_Control.cs new file mode 100644 index 0000000..34081a3 --- /dev/null +++ b/SaBusinessMgrCoreWebControl/Control/App/SbmSystem_Control.cs @@ -0,0 +1,100 @@ +using Newtonsoft.Json.Serialization; +using NPOI.SS.Formula.Functions; +using Sarand.BusinessMgr.Net.Core.Web.App; +using Sarand.BusinessMgr.Net.Core.Web.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.Core; +using Sarand.BusinessMgr.Web.Control.Consoles; +using Sarand.Net.Standard.Base.CodeTypes; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Diary; +using Sarand.Net.Standard.Base.Interfaces; +using Sarand.Net.Standard.Base.ItemData; +using Sarand.Net.Standard.Base.ItemDocs; +using Sarand.Net.Standard.Base.ItemOptions; +using Sarand.Net.Standard.Base.ReferenceData; +using Sarand.Net.Standard.Base.Security; +using Sarand.Net.Standard.Base.UpdateLog; +using System; +using static Sarand.BusinessMgr.Net.Core.Web.App.SbmAppConfig; + +namespace Sarand.BusinessMgr.Web.Control.App +{ + //======================================================================= + public class SbmSystem_Control : SbmSystem_Web + { + //------------------------------------------------------------------- + // Data members. + private readonly SbmApplication_Control app_Control; + + //------------------------------------------------------------------- + // Construction. + public SbmSystem_Control(SbmApplication_Control app, PropertySet properties) : base(properties) + { + app_Control = app; + } + + //------------------------------------------------------------------- + // Consoles. + //------------------------------------------------------------------- + + public override SbmSessionConsole CreateSessionConsole(ISbmUserOrganisationContext userContext) + { + return SbmSessionConsole.CreateConsole(userContext); + } + + public override SaDiaryConsole CreateDiaryConsole(ISbmUserOrganisationContext userContext) + { + throw new NotImplementedException(); + } + + public override SaCodeTypeConsole CreateCodeTypeConsole(ISbmUserOrganisationContext userContext) + { + return new SbmCodeTypeConsole_Web(userContext); + } + + public override SaItemDataConsole CreateItemDataConsole(ISbmUserOrganisationContext userContext) + { + throw new NotImplementedException(); + } + + public override SaItemDocConsole CreateItemDocConsole(ISbmUserOrganisationContext userContext) + { + throw new NotImplementedException(); + } + + public override SaItemOptionConsole CreateItemOptionConsole(ISbmUserOrganisationContext userContext) + { + return new SbmItemOptionConsole_Web(userContext); + } + + public override SaInterfaceConsole CreateInterfaceConsole(ISbmUserOrganisationContext userContext) + { + throw new NotImplementedException(); + } + + public override SaUpdateLogConsole CreateUpdateLogConsole(ISbmUserOrganisationContext userContext) + { + return new SbmUpdateLogConsole_Web(userContext); + } + + public override SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext) + { + return new SbmSecurityConsole_Web(userContext); + } + + public override SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext) + { + throw new NotImplementedException(); + } + + public override SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext, SbmEmailConfig emailConfig) + { + return SbmApplication_Control.CreateEmailConsole_Control(emailConfig); + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusinessMgrCoreWebControl/Control/App/SbmUserContext_Control.cs b/SaBusinessMgrCoreWebControl/Control/App/SbmUserContext_Control.cs deleted file mode 100644 index 3cd5164..0000000 --- a/SaBusinessMgrCoreWebControl/Control/App/SbmUserContext_Control.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Sarand.BusinessMgr.Net.Standard.Base.App; -using Sarand.BusinessMgr.Net.Standard.Base.Core; -using Sarand.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.Dbas; -using System; - -namespace Sarand.BusinessMgr.Web.Control.App -{ - //======================================================================= - /// - /// Wrapper class to allow access to core internals from Control application. - /// - public class SbmUserContext_Control : ISbmUserOrganisationContext - { - //------------------------------------------------------------------- - public SbmUserContext_Control(SbmSessionData_Control sessionData) - { - SessionData = sessionData; - } - - //------------------------------------------------------------------- - // Properties. - private SbmSessionData_Control SessionData { get; } - - //------------------------------------------------------------------- - /// Session Context - Identifies database connections etc. - public SbmSessionContext SessionContext { get { return null; } } - - //------------------------------------------------------------------- - // User properties. - /// User Security Item Id. - public SysId UserSecurityItemId { get { return null; } } - /// User Affiliate Id. - public SysId UserAffiliateId { get { return null; } } - /// User display name. - public String UserDisplayName { get { return SessionData.UserDisplayName; } } - /// User email address. - public String UserEmailAddress { get { return SessionData.UserEmailAddress; } } - /// Does the context represent a valid user account. - public bool ValidUser { get { return SessionData.ValidUser; } } - /// Database update info - user session specific properties for database inserts/updates. - public DbUpdateInfo DbUpdateInfo { get { return SessionData.DbUpdateInfo; } } - - //------------------------------------------------------------------- - /// Security profile - what the user is allowed to do based on security roles and groups. - public ISbmSecurityProfile_Core SecurityProfile_Core { get; } - - //------------------------------------------------------------------- - // Organisation properties. - - /// Organisation Affiliate Id. - public SysId OrganisationAffiliateId { get; } - - /// Organisation Affiliate Type. - public Sbm.AffiliateType OrganisationAffiliateType { get; } - - /// Organisation 'Internal' Association Id. - public SysId OrganisationAssociationId { get; } - - /// Organisation display name. - public String OrganisationDisplayName { get; } - - /// Organisation Interface context - to qualify interfaces belonging to the organisation. - public String OrganisationInterfaceContext { get; } - - //------------------------------------------------------------------- - // Organisation configuration. - public String GetOrganisationOption(Sbm.OrganisationOption option, String context) { return ""; } - public String GetOrganisationOption(String optionName, String context) { return ""; } - public String GetOwnerOption_Value(Sbm.OrgOption_Value eCol) { return ""; } - public String GetOwnerOption_Folder(Sbm.OrgOption_Folder eCol) { return ""; } - public bool GetOwnerOption_AllowOption(Sbm.OrgOption_AllowOption eCol) { return false; } - public String GetOwnerOption_Caption(Sbm.OrgOption_Caption eCol, String defaultValue) { return ""; } - public bool GetOwnerOption_ShowField(SbmDbDfn.ColumnIdx eCol) { return false; } - public bool GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn eCol) { return false; } - public String GetOwnerOption_FieldLabel(SbmDbDfn.ColumnIdx eCol, String defautValue) { return ""; } - public int GetOwnerOption_Minutes(Sbm.OrgOption_Minutes eLimit, int defautValue) { return 0; } - public int GetOwnerOption_UpdateLimit(Sbm.OrgOption_PeriodDays eLimit, int defautValue) { return 0; } - public int GetOwnerOption_UpdateLimit(Sbm.OrgOption_PeriodWeeks eLimit, int defautValue) { return 0; } - public int GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals eNumDecimals, int defautValue = 2) { return 2; } - public Sbm.CommodityType GetOwnerOption_CommodityType(Sbm.OrgOption_CommodityType commodityTypeContext) { return Sbm.CommodityType.Unknown; } - public SysId GetOwnerOption_StockLocation(Sbm.OrgOption_StockLocation eLoc) { return null; } - - //------------------------------------------------------------------- - } - //======================================================================= -} diff --git a/SaBusinessMgrCoreWebControl/Control/Consoles/SbmCoreInstanceConsole_Control.cs b/SaBusinessMgrCoreWebControl/Control/Consoles/SbmCoreInstanceConsole_Control.cs index 1bad76c..7e8b53d 100644 --- a/SaBusinessMgrCoreWebControl/Control/Consoles/SbmCoreInstanceConsole_Control.cs +++ b/SaBusinessMgrCoreWebControl/Control/Consoles/SbmCoreInstanceConsole_Control.cs @@ -2,6 +2,7 @@ using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; using Sarand.BusinessMgr.Net.Standard.Base.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Web.Control.App; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; @@ -25,16 +26,17 @@ namespace Sarand.BusinessMgr.Web.Control.Consoles //------------------------------------------------------------------- // Data members. private readonly SacsDatabase coreDatabase; - private readonly SysId organisationId; + private readonly SysId ownerId; private readonly SysId repositoryId; private SbmInternals internals; //------------------------------------------------------------------- // Construction. - public SbmCoreInstanceConsole_Control(SbmcRepository repository) + public SbmCoreInstanceConsole_Control(SbmSessionData_Control sessionData_Control, SbmcRepository repository) { - organisationId = repository.OwnerId; + ownerId = repository.OwnerId; repositoryId = repository.Id; + this.SessionData_Control = sessionData_Control; // Repository connection. SacsDatabaseConsole.OdbcConfig config = GetRepositoryOdbcConfig(repository); @@ -52,7 +54,8 @@ namespace Sarand.BusinessMgr.Web.Control.Consoles //------------------------------------------------------------------- // Properties. - public SbmApplication_Control App { get { return SbmApplication_Control.Instance; } } + public static SbmApplication_Control App_Control { get { return SbmApplication_Control.Instance; } } + public SbmSessionData_Control SessionData_Control { get; } public override ISacsDatabase Database_Core { get { return coreDatabase; } } public override SbmInternals Internals_Core { get { if (internals == null) { internals = CreateCoreInternals(); } return internals; } } public override DbUpdateInfo DbUpdateInfo_Core { get { return Internals_Core.DbUpdateInfo; } } @@ -70,24 +73,13 @@ namespace Sarand.BusinessMgr.Web.Control.Consoles } /// Core internals for accessing core managers etc. - public SbmInternals CreateCoreInternals() + protected SbmInternals CreateCoreInternals() { - ushort sessionIndex = App.GetCoreSessionIndexForControlRepository(organisationId, repositoryId); - SbmSessionContext sessionContext = new SbmSessionContext_Web(sessionIndex, Sbm.Application.WebControl); - SbmUserContext userContext = new SbmUserContext_Web(sessionContext); - return new SbmInternals(userContext); + ushort sessionIndex = App_Control.GetCoreSessionIndexForControlRepository(ownerId, repositoryId); + SbmSessionContext sessionContext = App_Control.GetSessionContextByIndex(sessionIndex); + return new SbmInternals(sessionContext); } - /// - /// Create core security console. - /// - /// - public override SaSecurityConsole CreateSecurityConsole() - { - return App.CreateSecurityConsole(internals.UserContext); - } - - //------------------------------------------------------------------- } //======================================================================= diff --git a/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/CoreDatabaseController-Ajax.cs b/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/CoreDatabaseController-Ajax.cs index e217812..bce8db2 100644 --- a/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/CoreDatabaseController-Ajax.cs +++ b/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/CoreDatabaseController-Ajax.cs @@ -76,7 +76,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance } // Repository Console. - SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(repository); + SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); disposables.Add(instanceConsole); // Columns. diff --git a/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/RepositoryController-Ajax.cs b/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/RepositoryController-Ajax.cs index 76564bc..3bdd831 100644 --- a/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/RepositoryController-Ajax.cs +++ b/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/RepositoryController-Ajax.cs @@ -233,7 +233,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance RefreshModel(model); // Record disposable items as they are created so all can be disposed when needed. - using (DisposableCollection disposables = new DisposableCollection()) + using (DisposableCollection disposables = new DisposableCollection()) { // Identify item. @@ -252,7 +252,8 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance responseData.repository.Id = SysId.ToString(repository.Id); // Repository console. - SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(repository); + SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); + disposables.Add(instanceConsole); if (!instanceConsole.HasErrorState()) { // Validate database. diff --git a/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/RepositoryInitController-Ajax.cs b/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/RepositoryInitController-Ajax.cs index f6e0f94..10d5bbd 100644 --- a/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/RepositoryInitController-Ajax.cs +++ b/SaBusinessMgrCoreWebControl/Control/Controllers/Instance/RepositoryInitController-Ajax.cs @@ -128,27 +128,19 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance responseData.Repository.OwnerId = $"{SysId.ToLong(owner.Id)}"; responseData.Repository.OwnerName = owner.Name; - // Repository Console. - SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(repository); + // Core Instance Console. + SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); disposables.Add(instanceConsole); - // Core internals. - SbmInternals internals = instanceConsole.CreateCoreInternals(); - disposables.Add(internals); - - // Core security console. - SaSecurityConsole securityConsole = App.CreateSecurityConsole(internals.UserContext); - disposables.Add(securityConsole); - // Query Organisations. SbmAssociation.Params prm = new SbmAssociation.Params(); prm.AssociationType = Sbm.AssociationType.Internal; prm.StatusCat = SbmAssociation.StatusCat.Current; - foreach (SbmAssociation association in internals.AccountMgr.GetAssociationList(prm)) + foreach (SbmAssociation association in instanceConsole.Internals_Core.AccountMgr.GetAssociationList(prm)) { // Retrieve Organisation details. disposables.Add(association); - SbmAffiliate affiliateOrganisation = internals.AccountMgr.GetAffiliateById(association.AffiliateIdOwner); + SbmAffiliate affiliateOrganisation = instanceConsole.Internals_Core.AccountMgr.GetAffiliateById(association.AffiliateIdOwner); disposables.Add(affiliateOrganisation); // Organisation details. @@ -167,27 +159,30 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance prmAffiliateUser.AffiliateIdAssocOwner = affiliateOrganisation.Id; prmAffiliateUser.AssociationType = Sbm.AssociationType.Member; prmAffiliateUser.StatusCat = SbmAffiliate.StatusCat.CurrentOnly; - foreach (SbmAffiliate affiliateUser in internals.AccountMgr.GetAffiliateList(prmAffiliateUser)) + prmAffiliateUser.SortColumns.Add(instanceConsole.Internals_Core.AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Id)); + foreach (SbmAffiliate affiliateUser in instanceConsole.Internals_Core.AccountMgr.GetAffiliateList(prmAffiliateUser)) { disposables.Add(affiliateUser); // Lookup security details. if (!SysId.IsValid(affiliateUser.UserId)) continue; - SaSecurityItem securityUser = securityConsole.GetSecurityItemById(SaSecurity.ItemType.User, affiliateUser.UserId); - disposables.Add(securityUser); - if (securityUser == null) continue; + SaSecurityItem securityItemUser = instanceConsole.Internals_Core.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, affiliateUser.UserId); + disposables.Add(securityItemUser); + if (securityItemUser == null) continue; // Confirm security rights (SuperUser). - SaSecurityProfile securityProfile = securityConsole.GetUserSecurityProfile(securityUser.Id); - if (!securityProfile.Rights.Any(right => right.Code.EqualsCI(SaSecurityConsole.GroupCode_Super))) continue; + SaSecurityProfile securityProfile = instanceConsole.Internals_Core.SecurityConsole.GetUserSecurityProfile(securityItemUser.Id); + if (!securityProfile.Groups.Any(group => group.Code.EqualsCI(SaSecurityConsole.GroupCode_Super))) continue; // Add User to the Organisation. RepositoryUserData userData = new RepositoryUserData() { + AffiliateId = SysId.ToString(affiliateUser.Id), + SecurityItemId = SysId.ToString(securityItemUser.Id), FirstName = affiliateUser.FirstName, LastName = affiliateUser.LastName, - Email = StringUtil.OnBlank(securityUser.EmailAddress, affiliateUser.Email), - Code = securityUser.Code, + Email = StringUtil.OnBlank(securityItemUser.EmailAddress, affiliateUser.Email), + Code = securityItemUser.Code, }; organisation.Users.Add(userData); } @@ -241,13 +236,156 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } + // Core Instance Console. + SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); + disposables.Add(instanceConsole); + + // Validate Existing Organisation properties. + if (StringUtil.ToBool(model.Organisation.Exists)) + { + // Validate existing Organisation Affiliate. + SysId affiliateIdOrganisation = SysId.ToSysId(model.Organisation.AffiliateId); + if (!SysId.IsValid(affiliateIdOrganisation)) + { + SaLogger.Warn($"{SysUtil.Fn} Affiliate Id not specified for existing Organisation."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + + // Validate Organisation Affiliate. + SbmAffiliate affiliateOrganisation = instanceConsole.Internals_Core.AccountMgr.GetAffiliateById(affiliateIdOrganisation); + disposables.Add(affiliateOrganisation); + if (affiliateOrganisation == null) + { + SaLogger.Warn($"{SysUtil.Fn} Affiliate not found for existing Organisation. Id: {model.Organisation.AffiliateId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + if (!affiliateOrganisation.IsOrganisation()) + { + SaLogger.Warn($"{SysUtil.Fn} Affiliate for existing Organisation is not an organisation. Id: {model.Organisation.AffiliateId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + + + // Validate existing Organisation Internal Association. + SysId associationIdInternal = SysId.ToSysId(model.Organisation.AssociationId); + if (!SysId.IsValid(associationIdInternal)) + { + SaLogger.Warn($"{SysUtil.Fn} Association Id not specified for existing Organisation."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + else + { + // Validate Internal Association. + SbmAssociation associationOrganisation = instanceConsole.Internals_Core.AccountMgr.GetAssociationById(associationIdInternal); + disposables.Add(associationOrganisation); + if (associationOrganisation == null) + { + SaLogger.Warn($"{SysUtil.Fn} Association not found for existing Organisation. Id: {model.Organisation.AssociationId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + if (!associationOrganisation.AffiliateIdOwner.Equals(affiliateIdOrganisation)) + { + SaLogger.Warn($"{SysUtil.Fn} Association for existing Organisation does not match Owner Affiliate. Id: {model.Organisation.AssociationId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + if (!associationOrganisation.AffiliateIdTarget.Equals(affiliateIdOrganisation)) + { + SaLogger.Warn($"{SysUtil.Fn} Association for existing Organisation does not match Target Affiliate. Id: {model.Organisation.AssociationId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + if (!associationOrganisation.IsInternal()) + { + SaLogger.Warn($"{SysUtil.Fn} Association for existing Organisation is not internal. Id: {model.Organisation.AssociationId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + } + } + else + { + // Organisation does not exist. + if (!SysId.IsValid(SysId.ToSysId(model.Organisation.AffiliateId))) + { + SaLogger.Warn($"{SysUtil.Fn} Affiliate Id specified for new Organisation. Id: {model.Organisation.AffiliateId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + if (!SysId.IsValid(SysId.ToSysId(model.Organisation.AssociationId))) + { + SaLogger.Warn($"{SysUtil.Fn} Association Id specified for new Organisation. Id: {model.Organisation.AssociationId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + } + + // Validate Existing User properties. + if (StringUtil.ToBool(model.User.Exists)) + { + // Validate existing User Affiliate. + SysId affiliateIdUser = SysId.ToSysId(model.User.AffiliateId); + if (!SysId.IsValid(affiliateIdUser)) + { + SaLogger.Warn($"{SysUtil.Fn} Affiliate Id not specified for existing User."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + + // Validate User Affiliate. + SbmAffiliate affiliateUser = instanceConsole.Internals_Core.AccountMgr.GetAffiliateById(affiliateIdUser); + disposables.Add(affiliateUser); + if (affiliateUser == null) + { + SaLogger.Warn($"{SysUtil.Fn} Affiliate not found for existing User. Id: {model.User.AffiliateId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + if (!affiliateUser.IsIndividual()) + { + SaLogger.Warn($"{SysUtil.Fn} Affiliate for existing User is not an individual. Id: {model.User.AffiliateId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + + // Validate existing User Security Item. + SysId secItemIdUser = SysId.ToSysId(model.User.SecurityItemId); + if (!SysId.IsValid(secItemIdUser)) + { + SaLogger.Warn($"{SysUtil.Fn} Security Item Id not specified for existing User."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + else + { + // Validate User Security Item. + SaSecurityItem securityItemUser = instanceConsole.Internals_Core.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, secItemIdUser); + disposables.Add(securityItemUser); + if (securityItemUser == null) + { + SaLogger.Warn($"{SysUtil.Fn} Security Item not found for existing User. Id: {model.User.SecurityItemId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + if (!securityItemUser.Id.Equals(affiliateUser.UserId)) + { + SaLogger.Warn($"{SysUtil.Fn} Security Item for existing User does not match User Id on Affilliate. Expected: {model.User.SecurityItemId}. Found: {affiliateUser.UserId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + } + } + else + { + // User does not exist. + if (!SysId.IsValid(SysId.ToSysId(model.User.AffiliateId))) + { + SaLogger.Warn($"{SysUtil.Fn} Affiliate Id specified for new User. Id: {model.User.AffiliateId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + if (!SysId.IsValid(SysId.ToSysId(model.User.SecurityItemId))) + { + SaLogger.Warn($"{SysUtil.Fn} Security Item Id specified for new User. Id: {model.User.SecurityItemId}."); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); + } + } + // Validate item properties. model.ValidateRepositoryData(responseData, repository); if (responseData.HasControlErrors()) return Json(responseData); // Repository Console. - SbmCoreInstanceConsole_Control repositoryConsole = new SbmCoreInstanceConsole_Control(repository); + SbmCoreInstanceConsole_Control repositoryConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); disposables.Add(repositoryConsole); SbmCoreInstanceConsole_Base.RepositoryInitialisationData repoInitData = new SbmCoreInstanceConsole_Base.RepositoryInitialisationData(); @@ -264,6 +402,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance repoInitData.User.SecurityItemId = SysId.ToSysId(model.User.SecurityItemId); repoInitData.User.Code = model.User.Code; repoInitData.User.Password = model.User.Password; + repoInitData.User.PasswordSet = StringUtil.ToBool(model.User.PasswordSet); if (!repositoryConsole.InitialiseRepository(repoInitData)) return Json(responseData.SetMessage(messageTitle, repositoryConsole.ErrorStateMessage)); diff --git a/SaBusinessMgrCoreWebControl/Control/Controllers/SbmController_Control.cs b/SaBusinessMgrCoreWebControl/Control/Controllers/SbmController_Control.cs index cf7ed45..fa56036 100644 --- a/SaBusinessMgrCoreWebControl/Control/Controllers/SbmController_Control.cs +++ b/SaBusinessMgrCoreWebControl/Control/Controllers/SbmController_Control.cs @@ -1,25 +1,23 @@ -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; -using NPOI.SS.Formula.Functions; +using Newtonsoft.Json; using Sarand.BusinessMgr.Net.Core.Web.App; -using Sarand.BusinessMgr.Web.Control.App; -using Sarand.BusinessMgr.Web.Control.Consoles; using Sarand.BusinessMgr.Net.Core.Web.Controllers; using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; using Sarand.BusinessMgr.Net.Standard.Base.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.Core; +using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; +using Sarand.BusinessMgr.Web.Control.App; +using Sarand.BusinessMgr.Web.Control.Consoles; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Email; using Sarand.Net.Standard.Base.Helpers; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Web; -using Sarand.BusinessMgr.Net.Standard.Base.Core; -using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Database; -using System.Net.Mail; namespace Sarand.BusinessMgr.Web.Control.Controllers { @@ -28,28 +26,55 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers { //------------------------------------------------------------------- // Data members. + private SbmInternals_Control internals_Control; + private SbmEmailConsole_Control emailConsole; //------------------------------------------------------------------- // Protected construction. protected SbmController_Control(SbmLocaliser localiser, Microsoft.Extensions.Logging.ILogger logger) : base(localiser) { } + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (internals_Control != null) internals_Control.Dispose(); internals_Control = null; + } + base.Dispose(disposing); + } + + //------------------------------------------------------------------- + // Properties. + public SbmInternals_Control Internals_Control { get { if (internals_Control == null) { internals_Control = new SbmInternals_Control(); } return internals_Control; } } + protected SbmcAccountMgr ControlAccountMgr { get { return Internals_Control.ControlAccountMgr; } } + protected SbmcInstanceMgr ControlInstanceMgr { get { return Internals_Control.ControlInstanceMgr; } } + protected SbmcItemMgr ControlItemMgr { get { return Internals_Control.ControlItemMgr; } } //------------------------------------------------------------------- // Session data. //------------------------------------------------------------------- /// Control session data + protected SbmApplication_Control App_Control { get { return SbmApplication_Control.Instance; } } protected SbmSessionData_Control SessionData_Control { get { return SessionData as SbmSessionData_Control; } } - public override ISbmUserOrganisationContext UserContext_Core { get { return new SbmUserContext_Control(SessionData_Control); } } + public override ISbmUserOrganisationContext UserContext_Core => throw new NotImplementedException(); protected override SbmSessionData_Web DeserializeSessionData(String sessionDataJson) { return JsonConvert.DeserializeObject(sessionDataJson, SbmSessionDataJsonSerializerSettings); } //------------------------------------------------------------------- - // Globals. + // Email console. //------------------------------------------------------------------- - public SbmEmailConsole_Control EmailConsole_Control { get { return Internals.EmailConsole as SbmEmailConsole_Control; } } + public SaEmailConfig EmailConfig { get { return App_Control.EmailConfig; } } + public SbmEmailConsole_Control EmailConsole_Control + { + get + { + if (emailConsole == null) + emailConsole = SbmApplication_Control.CreateEmailConsole_Control(App_Control.EmailConfig); + return emailConsole; + } + } //------------------------------------------------------------------- // User Session. @@ -88,7 +113,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers userAccount.LastInvalidLoginAt = null; if (!ControlAccountMgr.UpdateUserAccount(userAccount, DbUpdateInfo)) { - SaLogger.Warn($"{SysUtil.Fn} Failed to update User Account for " + userAccount.EmailAddress + ": " + AccountMgr.ErrorStateMessage); + SaLogger.Warn($"{SysUtil.Fn} Failed to update User Account for " + userAccount.EmailAddress + ": " + ControlAccountMgr.ErrorStateMessage); errorMessage = Localiser["security.msg.signin.invalid"]; return false; } diff --git a/SaBusinessMgrCoreWebControl/Control/Controllers/Security/SecurityController-Ajax.cs b/SaBusinessMgrCoreWebControl/Control/Controllers/Security/SecurityController-Ajax.cs index 1197114..530202e4 100644 --- a/SaBusinessMgrCoreWebControl/Control/Controllers/Security/SecurityController-Ajax.cs +++ b/SaBusinessMgrCoreWebControl/Control/Controllers/Security/SecurityController-Ajax.cs @@ -370,7 +370,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers emailData.AddressesTo.Add(userAccount.EmailAddress); emailData.Subject = controller.Localiser["caption.request.password"]; PopulateRequestPasswordEmailBody(controller, emailData, userAccount, onlineContext); - return controller.EmailConsole.SendEmail(emailData); + return controller.EmailConsole_Control.SendEmail(emailData); } private static void PopulateRequestPasswordEmailBody(SbmController_Control controller, SaEmailData emailData, SbmcUserAccount userAccount, bool onlineContext) { diff --git a/SaBusinessMgrCoreWebControl/Control/Models/Instance/Model_RepositoryInit.cs b/SaBusinessMgrCoreWebControl/Control/Models/Instance/Model_RepositoryInit.cs index 1d77d7f..daea964 100644 --- a/SaBusinessMgrCoreWebControl/Control/Models/Instance/Model_RepositoryInit.cs +++ b/SaBusinessMgrCoreWebControl/Control/Models/Instance/Model_RepositoryInit.cs @@ -61,6 +61,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance // Organisation. public class OrganisationData { + public String Exists { get; set; } public String AffiliateId { get; set; } public String AssociationId { get; set; } public String Name { get; set; } @@ -81,6 +82,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance // User. public class UserData { + public String Exists { get; set; } public String AffiliateId { get; set; } public String SecurityItemId { get; set; } public String FirstName { get; set; } @@ -88,6 +90,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance public String Email { get; set; } public String Code { get; set; } public String Password { get; set; } + public String PasswordSet { get; set; } } public UserData User { get; } = new UserData(); public SysId GetUserAffiliateId() @@ -119,17 +122,9 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance //----------------------------------------------------------- // Repository Console. - SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(repository); + SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); disposables.Add(instanceConsole); - // Core internals. - SbmInternals internals = instanceConsole.CreateCoreInternals(); - disposables.Add(internals); - - // Core security console. - SaSecurityConsole securityConsole = ControlApp.CreateSecurityConsole(internals.UserContext); - disposables.Add(securityConsole); - //----------------------------------------------------------- // Organisation Name. if (Organisation.Name != null) @@ -143,7 +138,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance else { // Check that organisation name is not already in use. - if (internals.AccountMgr.OrganisationExistsByName(Organisation.Name, GetOrganisationAffiliateId())) + if (instanceConsole.Internals_Core.AccountMgr.OrganisationExistsByName(Organisation.Name, GetOrganisationAffiliateId())) responseData.SetControlError(controlName, Localiser["msg.validation.duplicate.value"]); } } @@ -221,7 +216,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance else { // Ensure that user name is not already in use. - SysId securityItemId = securityConsole.GetIdForItemCode(SaSecurity.ItemType.User, User.Code); + SysId securityItemId = instanceConsole.Internals_Core.SecurityConsole.GetIdForItemCode(SaSecurity.ItemType.User, User.Code); if (SysId.IsValid(securityItemId) && !securityItemId.Equals(GetUserSecurityItemId())) { @@ -230,7 +225,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance } // User Password. - if (User.Password != null) + if (User.Password != null && (StringUtil.ToBool(User.PasswordSet) || !StringUtil.ToBool(User.Exists))) { String controlName = GetControlName(Control.UserPassword); responseData.SetControlValue(controlName, User.Password); diff --git a/SaBusinessMgrCoreWebControl/Control/Models/SbmModel_Control.cs b/SaBusinessMgrCoreWebControl/Control/Models/SbmModel_Control.cs index 6338e11..fc5878a 100644 --- a/SaBusinessMgrCoreWebControl/Control/Models/SbmModel_Control.cs +++ b/SaBusinessMgrCoreWebControl/Control/Models/SbmModel_Control.cs @@ -23,9 +23,9 @@ namespace Sarand.BusinessMgr.Web.Control.Models //------------------------------------------------------------------- // Properties. - protected SbmApplication_Control ControlApp { get { return SbmApplication_Control.Instance; } } + protected SbmApplication_Control App_Control { get { return SbmApplication_Control.Instance; } } public SbmSessionData_Control SessionData_Control { get { return SessionData as SbmSessionData_Control; } } - public override ISbmUserOrganisationContext UserContext_Core { get { return new SbmUserContext_Control(SessionData_Control); } } + public override ISbmUserOrganisationContext UserContext_Core => throw new NotImplementedException(); //------------------------------------------------------------------- public IEnumerable GetInstanceContextsForSelect() diff --git a/SaBusinessMgrCoreWebControl/Localisation/SbmControlProperties.resx b/SaBusinessMgrCoreWebControl/Localisation/SbmControlProperties.resx index 62bc10a..3639f4b 100644 --- a/SaBusinessMgrCoreWebControl/Localisation/SbmControlProperties.resx +++ b/SaBusinessMgrCoreWebControl/Localisation/SbmControlProperties.resx @@ -453,4 +453,10 @@ Rows + + Update Vehicle + + + Create Vehicle + \ No newline at end of file diff --git a/SaBusinessMgrCoreWebControl/Views/Instance/Repository/Initialise.cshtml b/SaBusinessMgrCoreWebControl/Views/Instance/Repository/Initialise.cshtml index 695de0d..9a3559f 100644 --- a/SaBusinessMgrCoreWebControl/Views/Instance/Repository/Initialise.cshtml +++ b/SaBusinessMgrCoreWebControl/Views/Instance/Repository/Initialise.cshtml @@ -16,6 +16,7 @@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "RepositoryInitForm sbc-form", @onSubmit = "return false;" })) { @Html.Hidden("Repository.Id", "", new { @id = "", @class = "RepositoryId sbc-input" }) +
@Localiser["label.instance"]
@@ -55,6 +56,7 @@
@Localiser["label.organisation"]
+ @Html.Hidden("Organisation.Exists", "", new { @id = "", @class = "OrganisationExists sbc-input" }) @Html.Hidden("Organisation.AffiliateId", "", new { @id = "", @class = "OrganisationAffiliateId sbc-input" }) @Html.Hidden("Organisation.AssociationId", "", new { @id = "", @class = "OrganisationAssociationId sbc-input" }) @@ -128,8 +130,9 @@
@Localiser["label.user"]
+ @Html.Hidden("User.Exists", "", new { @id = "", @class = "UserExists sbc-input" }) @Html.Hidden("User.AffiliateId", "", new { @id = "", @class = "UserAffiliateId sbc-input" }) - @Html.Hidden("User.AssociationId", "", new { @id = "", @class = "UserSecurityItemId sbc-input" }) + @Html.Hidden("User.SecurityItemId", "", new { @id = "", @class = "UserSecurityItemId sbc-input" }) @* User FirstName *@
@@ -209,6 +212,7 @@
+ @Html.Hidden("User.PasswordSet", "", new { @id = "", @class = "UserPasswordSet sbc-input" }) @Html.Password("User.Password", "", new { @id = "", @class = "UserPassword sbc-input", @maxlength = Sbm.Config.Security.Password.MaxLength })
diff --git a/SaBusinessMgrCoreWebControl/wwwroot/js/sbc-ins-rep-init.js b/SaBusinessMgrCoreWebControl/wwwroot/js/sbc-ins-rep-init.js index 256e74c..f6cf54a 100644 --- a/SaBusinessMgrCoreWebControl/wwwroot/js/sbc-ins-rep-init.js +++ b/SaBusinessMgrCoreWebControl/wwwroot/js/sbc-ins-rep-init.js @@ -38,6 +38,8 @@ if (orgs.length) { let org = orgs[0]; + if (org.associationId && org.affiliateId) + $ctrls.filter('.OrganisationExists').val(1); $ctrls.filter('.OrganisationAssociationId').val(org.associationId); $ctrls.filter('.OrganisationAffiliateId').val(org.affiliateId); $ctrls.filter('.OrganisationName').val(org.name); @@ -48,8 +50,14 @@ if (usrs.length) { let usr = usrs[0]; + if (usr.affiliateId && usr.securityItemId) + $ctrls.filter('.UserExists').val(1); $ctrls.filter('.UserAffiliateId').val(usr.affiliateId); $ctrls.filter('.UserSecurityItemId').val(usr.securityItemId); + $ctrls.filter('.UserFirstName').val(usr.firstName); + $ctrls.filter('.UserLastName').val(usr.lastName); + $ctrls.filter('.UserEmail').val(usr.email); + $ctrls.filter('.UserCode').val(usr.code); } } sbc.openDialog(env.$dlg.init, 600, 640); @@ -61,7 +69,7 @@ env.ajax.initRepo = env.ajax.initRepo || { url: sbc.url.base + 'Instance/Repository/Ajax/Initialise', formSel: env.$frm.init, callbackFn: function (response) { ir.onInitRepo(env, response); } }; sbc.doAjaxRequest(env.ajax.initRepo, 50); } - ir.onInitRepo = function(env, response) + ir.onInitRepo = function (env, response) { sbc.debug('onInitRepo', env, response); sbc.refreshControlValues(response.controlValues); @@ -84,6 +92,7 @@ env.$dlg.init = env.$pnl.init.find('.RepositoryInitDlg').dialog(opt); env.$frm.init = env.$dlg.init.find('.RepositoryInitForm'); env.$frm.init.on('input', '.sbc-input, .sbc-textarea', function () { sbc.clearControlError(this); }).on('change', '.sbc-select', function () { sbc.clearControlError(this); }); + env.$frm.init.on('input', '.sbc-input.UserPassword', function () { env.$frm.init.find('.sbc-input.UserPasswordSet').val(1) }); }); //-------------------------------------------------------------- diff --git a/SaBusinessMgrCoreWebPortal/Portal/App/SbmApplication_Portal.cs b/SaBusinessMgrCoreWebPortal/Portal/App/SbmApplication_Portal.cs index 4ed82d8..52d3dad 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/App/SbmApplication_Portal.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/App/SbmApplication_Portal.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Sarand.BusinessMgr.Net.Core.Web.App; +using Sarand.BusinessMgr.Net.Core.Web.Consoles; using Sarand.BusinessMgr.Net.Core.Web.Control.Consoles; using Sarand.BusinessMgr.Net.Core.Web.Helpers; using Sarand.BusinessMgr.Net.Standard.Base.App; @@ -16,10 +17,18 @@ using Sarand.BusinessMgr.Web.Portal.Consoles; using Sarand.BusinessMgr.Web.Portal.Helpers; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.CodeTypes; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; +using Sarand.Net.Standard.Base.Diary; +using Sarand.Net.Standard.Base.Interfaces; using Sarand.Net.Standard.Base.IO; +using Sarand.Net.Standard.Base.ItemData; +using Sarand.Net.Standard.Base.ItemDocs; +using Sarand.Net.Standard.Base.ItemOptions; using Sarand.Net.Standard.Base.ReferenceData; +using Sarand.Net.Standard.Base.Security; +using Sarand.Net.Standard.Base.UpdateLog; using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Dbas.Base; using System; @@ -82,7 +91,7 @@ namespace Sarand.BusinessMgr.Web.Portal.App try { properties = new PropertySet(); - SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Web(properties))); + SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Portal(properties))); Configuration = configuration; } catch (Exception exc) @@ -159,12 +168,48 @@ namespace Sarand.BusinessMgr.Web.Portal.App public override SbmEmailConfig EmailConfig { get { return emailConfigs.Values.ToList().getConfigForSession(AppConfig); } } //------------------------------------------------------------------- - // Create Consoles. - public override SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext) + // Create consoles. + public SbmSessionConsole CreateSessionConsole(ISbmUserOrganisationContext userContext) + { + return SbmSessionConsole.CreateConsole(userContext); + } + public SaDiaryConsole CreateDiaryConsole(ISbmUserOrganisationContext userContext) + { + return null; + } + public SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext) + { + return new SbmSecurityConsole_Web(userContext); + } + public SaCodeTypeConsole CreateCodeTypeConsole(ISbmUserOrganisationContext userContext) + { + return new SbmCodeTypeConsole_Web(userContext); + } + public SaItemDataConsole CreateItemDataConsole(ISbmUserOrganisationContext userContext) + { + return null; + } + public SaItemDocConsole CreateItemDocConsole(ISbmUserOrganisationContext userContext) + { + return null; + } + public SaItemOptionConsole CreateItemOptionConsole(ISbmUserOrganisationContext userContext) + { + return new SbmItemOptionConsole_Web(userContext); + } + public SaInterfaceConsole CreateInterfaceConsole(ISbmUserOrganisationContext userContext) + { + return null; + } + public SaUpdateLogConsole CreateUpdateLogConsole(ISbmUserOrganisationContext userContext) + { + return new SbmUpdateLogConsole_Web(userContext); + } + public SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext) { return new SbmReferenceDataConsole_Portal(userContext); } - public override SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext) + public SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext) { return new SbmEmailConsole_Portal(EmailConfig); } diff --git a/SaBusinessMgrCoreWebPortal/Portal/App/SbmSessionData_Portal.cs b/SaBusinessMgrCoreWebPortal/Portal/App/SbmSessionData_Portal.cs index 433fb98..0bf8ceb 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/App/SbmSessionData_Portal.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/App/SbmSessionData_Portal.cs @@ -18,33 +18,46 @@ using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config; using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Database; using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Mgr; +using Sarand.Net.Standard.Base.App; namespace Sarand.BusinessMgr.Web.Portal.App { //======================================================================= - public class SbmSessionData_Portal : SbmSessionData_Web, ISbmUserOrganisationContext + public class SbmSessionData_Portal : SbmSessionData_Web, ISbmSessionData_Core { //------------------------------------------------------------------- // Construction. [JsonConstructor] - private SbmSessionData_Portal(long sessionIdx, int itemIdx, SbmSessionContext sessionContext) : - base(sessionIdx, itemIdx, sessionContext) + private SbmSessionData_Portal(long sessionIdx, SbmSessionContext sessionContext) : + base(sessionIdx, sessionContext) { - securityProfile = new SbmSecurityProfile(this, false); + securityProfile = new SbmSecurityProfile(false); Organisation = new OrganisationData_Portal(null, null); + User = new UserData_Portal(sessionContext, null, null); } /// - /// SessionData construction. - /// SessionContext and UserAccount must be supplied. - /// Organisation is optional. + /// Session Data construction for non-session data, eg. background tasks. + /// . /// - public SbmSessionData_Portal(SbmSessionContext sessionContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) : + public SbmSessionData_Portal(SbmSessionContext sessionContext) : + base(0, sessionContext) + { + securityProfile = new SbmSecurityProfile(false); + Organisation = new OrganisationData_Portal(null, null); + User = new UserData_Portal(sessionContext, null, null); + } + /// + /// Session Data construction. + /// - Session Context must be supplied. + /// - Other parameters are optional and can be added later via Refresh(). + /// + public SbmSessionData_Portal(SbmSessionContext sessionContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) : base(sessionContext) { RepositoryContext = repositoryContext; - securityProfile = new SbmSecurityProfile(this, false); + securityProfile = new SbmSecurityProfile(false); Organisation = new OrganisationData_Portal(associationOrganisation, affiliateOrganisation); - User = new UserData_Portal(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations); + User = new UserData_Portal(sessionContext, securityItemUser, affiliateUser); } //------------------------------------------------------------------- @@ -136,24 +149,10 @@ namespace Sarand.BusinessMgr.Web.Portal.App { [JsonConstructor] private UserData_Portal() { } - public UserData_Portal(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations) : + public UserData_Portal(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser) : base(sessionContext) { - if (securityItemUser != null) - { - SecurityItemId = securityItemUser.Id; - } - if (affiliateUser != null) - { - AffiliateId = affiliateUser.Id; - Refresh(securityItemUser, affiliateUser, supervisedOrganisations); - if (sessionContext.Application == Sbm.Application.WebControl) - KeepLoggedIn = affiliateUser.KeepLoggedIn_Control; - else if (sessionContext.Application == Sbm.Application.WebPortal) - KeepLoggedIn = affiliateUser.KeepLoggedIn_Portal; - else Debugger.Break(); - } - this.supervisedOrganisations = supervisedOrganisations ?? new List(); + Refresh(securityItemUser, affiliateUser); } public UserData_Portal(UserData userData) : base(userData) @@ -163,31 +162,36 @@ namespace Sarand.BusinessMgr.Web.Portal.App { SecurityItemId = userData_Portal.SecurityItemId; AffiliateId = userData_Portal.AffiliateId; - supervisedOrganisations = userData_Portal.supervisedOrganisations; } } // Properties. public SysId SecurityItemId { get; protected set; } public SysId AffiliateId { get; protected set; } public bool KeepLoggedIn { get; private set; } - /// User managed associations - Id and display name. - public List SupervisedOrganisations { get { return new List(supervisedOrganisations); } } - protected List supervisedOrganisations { get; } = new List(); // Utilities. - public bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations) + public bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser) { base.Refresh(); // Check that user matches the session. - if (!SysId.IsValid(SecurityItemId) || !SysId.IsValid(securityItemUser?.Id ?? null) || !SecurityItemId.Equals(securityItemUser.Id)) return false; - if (!SysId.IsValid(AffiliateId) || !SysId.IsValid(affiliateUser?.Id ?? null) || !AffiliateId.Equals(affiliateUser.Id)) return false; + if (!SysId.IsValid(securityItemUser?.Id) || (SysId.IsValid(SecurityItemId) && !SecurityItemId.Equals(securityItemUser.Id))) + { + SaLogger.Warn($"{SysUtil.Fn} Invalid - User Security Item doesn't match session. Expected Id: {SecurityItemId}. Found: {securityItemUser?.Id}."); + return false; + } + if (!SysId.IsValid(affiliateUser?.Id) || (SysId.IsValid(AffiliateId) && !AffiliateId.Equals(affiliateUser.Id))) + { + SaLogger.Warn($"{SysUtil.Fn} Invalid - User Affiliate doesn't match session. Expected Id: {AffiliateId}. Found: {affiliateUser?.Id}."); + return false; + } // Refresh properties. - EmailAddress = securityItemUser.EmailAddress; - Title = affiliateUser.Title; - FirstName = affiliateUser.FirstName; - LastName = affiliateUser.LastName; - DisplayName = affiliateUser.GetDisplayName(); - this.supervisedOrganisations.Clear(); - this.supervisedOrganisations.AddRange(supervisedOrganisations); + AffiliateId = affiliateUser?.Id ?? new SysId(); + SecurityItemId = securityItemUser?.Id ?? new SysId(); + EmailAddress = securityItemUser?.EmailAddress ?? ""; + Title = affiliateUser?.Title ?? ""; + FirstName = affiliateUser?.FirstName ?? ""; + LastName = affiliateUser?.LastName ?? ""; + DisplayName = affiliateUser?.GetDisplayName() ?? ""; + KeepLoggedIn = affiliateUser?.KeepLoggedIn_Portal ?? false; return true; } } @@ -195,13 +199,14 @@ namespace Sarand.BusinessMgr.Web.Portal.App /// Portal User details. public UserData_Portal User { get; private set; } + //------------------------------------------------------------------- /// - /// Update the user's contact details against the session. + /// Update the User and Organisation details against the Session Data. /// - User identity must match that already against the session. /// - public bool RefreshUser(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) + public bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) { - if (User != null && User.Refresh(securityItemUser, affiliateUser, supervisedOrganisations)) + if (User != null && User.Refresh(securityItemUser, affiliateUser)) { Organisation = new OrganisationData_Portal(associationOrganisation, affiliateOrganisation); return true; @@ -211,7 +216,7 @@ namespace Sarand.BusinessMgr.Web.Portal.App //------------------------------------------------------------------- /// - /// User Profile. + /// User Profile - persistent session properties relating to default population of views, forms etc. /// - Filter settings. /// public class UserProfileData diff --git a/SaBusinessMgrCoreWebPortal/Portal/App/SbmSystem_Portal.cs b/SaBusinessMgrCoreWebPortal/Portal/App/SbmSystem_Portal.cs new file mode 100644 index 0000000..cb01264 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Portal/App/SbmSystem_Portal.cs @@ -0,0 +1,82 @@ +using Sarand.BusinessMgr.Net.Core.Web.App; +using Sarand.BusinessMgr.Net.Core.Web.Consoles; +using Sarand.BusinessMgr.Net.Core.Web.Control.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.Consoles; +using Sarand.BusinessMgr.Net.Standard.Base.Core; +using Sarand.BusinessMgr.Web.Portal.Consoles; +using Sarand.Net.Standard.Base.CodeTypes; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Diary; +using Sarand.Net.Standard.Base.Interfaces; +using Sarand.Net.Standard.Base.ItemData; +using Sarand.Net.Standard.Base.ItemDocs; +using Sarand.Net.Standard.Base.ItemOptions; +using Sarand.Net.Standard.Base.ReferenceData; +using Sarand.Net.Standard.Base.Security; +using Sarand.Net.Standard.Base.UpdateLog; +using static Sarand.BusinessMgr.Net.Core.Web.App.SbmAppConfig; + +namespace Sarand.BusinessMgr.Web.Portal.App +{ + public class SbmSystem_Portal:SbmSystem_Web + { + //------------------------------------------------------------------- + // Data members. + + //------------------------------------------------------------------- + // Construction. + public SbmSystem_Portal(PropertySet properties) : base(properties) + { + } + + //------------------------------------------------------------------- + // Create consoles. + + public override SbmSessionConsole CreateSessionConsole(ISbmUserOrganisationContext userContext) + { + return SbmSessionConsole.CreateConsole(userContext); + } + public override SaDiaryConsole CreateDiaryConsole(ISbmUserOrganisationContext userContext) + { + return null; + } + public override SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext) + { + return new SbmSecurityConsole_Web(userContext); + } + public override SaCodeTypeConsole CreateCodeTypeConsole(ISbmUserOrganisationContext userContext) + { + return new SbmCodeTypeConsole_Web(userContext); + } + public override SaItemDataConsole CreateItemDataConsole(ISbmUserOrganisationContext userContext) + { + return null; + } + public override SaItemDocConsole CreateItemDocConsole(ISbmUserOrganisationContext userContext) + { + return null; + } + public override SaItemOptionConsole CreateItemOptionConsole(ISbmUserOrganisationContext userContext) + { + return new SbmItemOptionConsole_Web(userContext); + } + public override SaInterfaceConsole CreateInterfaceConsole(ISbmUserOrganisationContext userContext) + { + return null; + } + public override SaUpdateLogConsole CreateUpdateLogConsole(ISbmUserOrganisationContext userContext) + { + return new SbmUpdateLogConsole_Web(userContext); + } + public override SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext) + { + return new SbmReferenceDataConsole_Portal(userContext); + } + public override SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext, SbmEmailConfig emailConfig) + { + return new SbmEmailConsole_Portal(emailConfig); + } + + //------------------------------------------------------------------- + } +} diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/AssetCategoryController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/AssetCategoryController-Ajax.cs index 8425625..ec28258 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/AssetCategoryController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/AssetCategoryController-Ajax.cs @@ -1,9 +1,9 @@ using Microsoft.AspNetCore.Mvc; 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.Web.Portal.Models; using Sarand.BusinessMgr.Web.Portal.Models.Assets; +using Sarand.BusinessMgr.Web.Portal.Models.Commodities; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; @@ -14,19 +14,26 @@ using System.Collections.Generic; namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets { + //======================================================================= + // Portal Asset Category Controller - Ajax actions. //======================================================================= partial class AssetCategoryController { //------------------------------------------------------------------- - // Definitions. - - // AssetCategory data. + // Item data. private class AssetCategoryListData : AjaxResponse_Data.ItemData_Base { public String TypeDesc { get; set; } public String Code { get; set; } - public String DescBrief { get; set; } + public String Caption { get; set; } public long? AssetCount { get; set; } + // Fields. + public class FieldData + { + // Item property values keyed to match field name. + public Dictionary Value { get; } = new Dictionary(); + } + public FieldData Field { get; } = new FieldData(); } private class AssetCategoryItemData : AssetCategoryListData { @@ -35,33 +42,111 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets private void PopulateAssetCategoryResponseListData(SbmModel_Portal model, AssetCategoryListData data, SbmAssetCategory assetCategory) { data.Id = SysId.ToString(assetCategory.Id); - data.TypeDesc = Internals.AssetTypeCodes.GetDescForType(assetCategory.AssetType); + // Prominent properties for selecting and editing. data.Code = assetCategory.Code; - data.DescBrief = assetCategory.DescBrief; - data.StatusCode = assetCategory.StatusCode; - data.StatusDesc = assetCategory.StatusDesc; + data.Caption = assetCategory.DescBrief; + // Asset count. + long assetCount = Internals.AssetMgr.GetAssetCountForAssetCategory(assetCategory.Id); + if (assetCount > 0) data.AssetCount = assetCount; } private void PopulateAssetCategoryResponseItemData(SbmModel_Portal model, AssetCategoryItemData data, SbmAssetCategory assetCategory) { PopulateAssetCategoryResponseListData(model, data, assetCategory); + // Asset type - populate for list ('Type' property populated with desc) and form (Type Code & Desc). data.TypeCode = Internals.AssetTypeCodes.GetCodeForType(assetCategory.AssetType); - data.Notes = assetCategory.Notes; + data.TypeDesc = Internals.AssetTypeCodes.GetDescForType(assetCategory.AssetType); + data.Field.Value.Add($"{Model_AssetCategory.ItemField.Type}", Internals.AssetTypeCodes.GetDescForType(assetCategory.AssetType)); + // Asset Category properties. + data.Field.Value.Add($"{Model_AssetCategory.ItemField.Code}", assetCategory.Code); + data.Field.Value.Add($"{Model_AssetCategory.ItemField.Caption}", assetCategory.DescBrief); + // Common properties. + data.StatusCode = assetCategory.StatusCode; + data.StatusDesc = assetCategory.StatusDesc; + data.Field.Value.Add($"{Model_AssetCategory.ItemField.Status}", assetCategory.StatusDesc); + // Cleanse field values. + data.Field.Value.RemoveAll(item => StringUtil.IsBlank(item.Value)); + // Populate item list values that might be cleared during update after removing blank values to ensure that blank values are published. + data.Field.Value.Add($"{Model_AssetCategory.ItemField.Notes}", assetCategory.Notes); + data.Field.Value.Add($"{Model_AssetCategory.ItemField.UpdatedOn}", Localiser.FormatDate(assetCategory.UpdateStamp.On)); } //------------------------------------------------------------------- - // Get AssetCategory List ajax request. + // Asset Category configuration. //------------------------------------------------------------------- - private class AjaxResponse_AssetCategoryList : AjaxResponse_Data + private class AjaxResponse_AssetCategoryConfig : AjaxResponse_Data { // Construction. - public AjaxResponse_AssetCategoryList(SbmModel_Portal model) : base(model) { } - // AssetCategory list. - public List AssetCategories { get; } = new List(); + public AjaxResponse_AssetCategoryConfig(SbmModel_Portal model) : base(model) { } + // Configuration. + public Model_AssetCategory.ListConfigData Config { get; } = new Model_AssetCategory.ListConfigData(); + public Model_AssetCategory.ItemConfigData ConfigItemNew { get; } = new Model_AssetCategory.ItemConfigData(); // Reference data. + public List AssetTypes { get; } = new List(); + public List IncomeTypes { get; } = new List(); public List Statuses { get; } = new List(); public List StatusesCreate { get; } = new List(); public String StatusCodeDefault { get; set; } } + // Ajax request. + [HttpPost] + [Route("Assets/AssetCategory/Ajax/Config")] + [Route("Assets/AssetCategory/Ajax/GetConfig")] + public IActionResult Ajax_AssetCategoryConfig(Model_AssetCategory model) + { + AjaxResponse_AssetCategoryConfig responseData = new AjaxResponse_AssetCategoryConfig(model); + String messageTitle = Localiser["caption.asset.categories"]; + + // Validate session and referrer. + if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); + if (!ValidReferer) return Forbid(); + RefreshModel(model); + + // Populate configuration data. + PopulateAssetCategoryConfig(model, responseData); + + // Complete response. + responseData.Success = true; + return Json(responseData); + } + private void PopulateAssetCategoryConfig(Model_AssetCategory model, AjaxResponse_AssetCategoryConfig responseData) + { + // Configuration. + model.PopulateListConfig(responseData.Config); + model.PopulateItemConfig(responseData.ConfigItemNew, null, Sbm.AssetType.Unknown); + + // Reference data - select lists. + foreach (TypeCodeDesc assetType in GetCodesOfType(Sbm.SystemCode.AssetType)) + responseData.AssetTypes.Add(assetType.Code, assetType.Desc); + foreach (TypeCodeDesc incomeType in GetCodesOfType(Sbm.SystemCode.AssetIncomeType)) + responseData.IncomeTypes.Add(incomeType.Code, incomeType.Desc); + + // Reference data - statuses. + foreach (SaStatus status in SbmAssetCategory.ValidStatuses) + { + responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); + if (status != SaStatus.Deleted) + responseData.StatusesCreate.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); + } + responseData.StatusCodeDefault = SacsSystem.GetStatusCode(SbmAssetCategory.DefaultStatus); + } + + //------------------------------------------------------------------- + // Asset Category List. + //------------------------------------------------------------------- + private class AjaxResponse_AssetCategoryList : AjaxResponse_AssetCategoryConfig + { + // Construction. + public AjaxResponse_AssetCategoryList(SbmModel_Portal model) : base(model) { } + // View mode. + public class ModeData + { + public bool? Search { get; set; } + public bool? Maintain { get; set; } + } + public ModeData Mode { get; set; } + // AssetCategory list. + public List AssetCategories { get; } = new List(); + } //------------------------------------------------------------------- [HttpPost] [Route("Assets/AssetCategory/Ajax/GetList")] @@ -77,19 +162,21 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); - // Reference data - statuses. - foreach (SaStatus status in SbmAssetCategory.ValidStatuses) - { - responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); - if (status != SaStatus.Deleted) - responseData.StatusesCreate.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); - } - responseData.StatusCodeDefault = SacsSystem.GetStatusCode(SbmAssetCategory.DefaultStatus); + // Populate configuration data. + PopulateAssetCategoryConfig(model, responseData); + + // View mode. + responseData.Mode = new AjaxResponse_AssetCategoryList.ModeData(); + Model_AssetCategory.ViewMode viewMode = model.GetFilterMode(); + if (viewMode == Model_AssetCategory.ViewMode.Maintain) + responseData.Mode.Maintain = true; + else + responseData.Mode.Search = true; // Item filter. SbmAssetCategory.Params prmAssetCategory = new SbmAssetCategory.Params(); prmAssetCategory.Search = model.Filter.Search; - prmAssetCategory.StatusCat = model.Filter.GetStatusCat(); + prmAssetCategory.StatusCat = model.GetFilterStatusCat(); model.Paging.ItemTotal = (ulong)AssetMgr.GetAssetCategoryCount(prmAssetCategory); model.PopulatePagingTo(prmAssetCategory.ResultsPaging); @@ -99,11 +186,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets ColumnDfn colCode = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.Code); ColumnDfn colDescBrief = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.DescBrief); ColumnDfn colAssetCount = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.AssetCount); + ColumnDfn colNotes = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.Notes); ColumnDfn colStatus = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.Status); List columns = new List() { colId, colType, colCode, colDescBrief, - colAssetCount, colStatus + colAssetCount, colNotes, colStatus }; // Query items. @@ -116,15 +204,21 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets AssetCategoryListData assetCategoryData = new AssetCategoryListData() { Id = values.GetLong(colId.DataName).ToString(), - TypeDesc = Localiser.GetAssetTypeCaption(assetType), Code = values.GetString(colCode.DataName), - DescBrief = values.GetString(colDescBrief.DataName), + Caption = values.GetString(colDescBrief.DataName), + TypeDesc = Localiser.GetAssetTypeCaption(assetType), StatusCode = values.GetString(colStatus.DataName), - StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)) }; + assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Type}", Internals.AssetTypeCodes.GetDescForType(assetType)); + assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Code}", assetCategoryData.Code); + assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Caption}", assetCategoryData.Caption); + assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Notes}", AssetMgr.GetAssetCategoryDataValue(colNotes, values).ToString()); + assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Status}", SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))); long assetCount = values.GetLong(colAssetCount.DataName); if (assetCount > 0) assetCategoryData.AssetCount = assetCount; + // Cleanse item values. + assetCategoryData.Field.Value.RemoveAll(item => StringUtil.IsBlank(item.Value)); responseData.AssetCategories.Add(assetCategoryData); } } @@ -144,7 +238,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets { // Construction. public AjaxResponse_AssetCategory(SbmModel_Portal model) : base(model) { } - // AssetCategory details. + // Configuration. + public Model_AssetCategory.ItemConfigData Config { get; } = new Model_AssetCategory.ItemConfigData(); + // Asset Category details. public AssetCategoryItemData assetCategory { get; } = new AssetCategoryItemData(); } //------------------------------------------------------------------- @@ -180,6 +276,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets } // Construct response. + model.PopulateItemConfig(responseData.Config, assetCategory); PopulateAssetCategoryResponseItemData(model, responseData.assetCategory, assetCategory); responseData.Success = true; } @@ -243,15 +340,16 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } assetCategory = AssetMgr.CreateAssetCategory(model.AssetCategory.AssetType); + disposables.Add(assetCategory); } // Populate item properties. if (model.AssetCategory.Code != null) assetCategory.Code = model.AssetCategory.Code; - if (model.AssetCategory.DescBrief != null) - assetCategory.DescBrief = model.AssetCategory.DescBrief; + if (model.AssetCategory.Caption != null) + assetCategory.DescBrief = model.AssetCategory.Caption; if (model.AssetCategory.StatusCode != null) - assetCategory.Status = model.AssetCategory.GetStatus(); + assetCategory.Status = model.GetAssetCategoryStatus(); if (model.AssetCategory.Notes != null) assetCategory.Notes = model.AssetCategory.Notes; @@ -274,6 +372,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets } // Construct response. + model.PopulateItemConfig(responseData.Config, assetCategory); PopulateAssetCategoryResponseItemData(model, responseData.assetCategory, assetCategory); responseData.Success = true; } diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/AssetCategoryController.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/AssetCategoryController.cs index 91c04af..4293af1 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/AssetCategoryController.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/AssetCategoryController.cs @@ -26,7 +26,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets //------------------------------------------------------------------- [Route("Assets/AssetCategory")] - public IActionResult Index() + public IActionResult Index(Model_AssetCategory model) { if (!ValidUserSession) AutoLoginUser(); @@ -38,8 +38,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets return RedirectToAction("", "Security"); } - // AssetCategory page. - Model_AssetCategory model = new Model_AssetCategory(Localiser); + // Asset Category page. + RefreshModel(model); + model.PopulateListConfig(); + model.Paging.PageNo = SessionData_Portal.Profile.Commodity.Filter.PageNo; + model.Paging.PageLength = SessionData_Portal.Profile.Commodity.Filter.PageLength; return View("Views/Assets/AssetCategory/Index.cshtml", model); } diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController-Ajax.cs index c1986a5..ec6c943 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Commodities/CommodityController-Ajax.cs @@ -108,7 +108,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities public AjaxResponse_CommodityConfig(SbmModel_Portal model) : base(model) { } // Configuration. public Model_Commodity.ListConfigData Config { get; } = new Model_Commodity.ListConfigData(); - public Model_Commodity.ItemConfigData ConfigCmd { get; } = new Model_Commodity.ItemConfigData(); + public Model_Commodity.ItemConfigData ConfigItemNew { get; } = new Model_Commodity.ItemConfigData(); // Reference data. public List CommodityTypes { get; } = new List(); public List Statuses { get; } = new List(); @@ -139,7 +139,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities { // Configuration. model.PopulateListConfig(responseData.Config); - model.PopulateItemConfig(responseData.ConfigCmd, null, Sbm.CommodityType.Unknown); + model.PopulateItemConfig(responseData.ConfigItemNew, null, Sbm.CommodityType.Unknown); // Reference data - commodity types. foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType)) @@ -189,12 +189,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities // View mode. responseData.Mode = new AjaxResponse_CommodityList.ModeData(); - Model_Commodity.CommodityViewMode viewMode = model.GetFilterMode(); - if (viewMode == Model_Commodity.CommodityViewMode.Maintain) + Model_Commodity.ViewMode viewMode = model.GetFilterMode(); + if (viewMode == Model_Commodity.ViewMode.Maintain) responseData.Mode.Maintain = true; - else if (viewMode == Model_Commodity.CommodityViewMode.StockControl) + else if (viewMode == Model_Commodity.ViewMode.StockControl) responseData.Mode.StockControl = true; - else if (viewMode == Model_Commodity.CommodityViewMode.StockTake) + else if (viewMode == Model_Commodity.ViewMode.StockTake) responseData.Mode.StockTake = true; else responseData.Mode.Search = true; @@ -303,26 +303,29 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities if (!ValidReferer) return Forbid(); RefreshModel(model); - // Identify item. - SysId commodityId = SysId.ToSysId(model.Commodity.Id); - if (!SysId.IsValid(commodityId)) - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); - - // Retrieve item. - SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId); - if (commodity == null) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) { - SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve commodity for Id: '{model.Commodity.Id}'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + + // Identify item. + SysId commodityId = SysId.ToSysId(model.Commodity.Id); + if (!SysId.IsValid(commodityId)) + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); + + // Retrieve item. + SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId); + disposables.Add(commodity); + if (commodity == null) + { + SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve commodity for Id: '{model.Commodity.Id}'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + } + + // Construct response. + model.PopulateItemConfig(responseData.Config, commodity); + PopulateCommodityResponseItemData(commodity, responseData.commodity); + responseData.Success = true; } - - // Construct response. - model.PopulateItemConfig(responseData.Config, commodity); - PopulateCommodityResponseItemData(commodity, responseData.commodity); - - // Complete response. - responseData.Success = true; - return Json(responseData); } @@ -361,63 +364,65 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); } - // Retrieve existing item. - SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId); - if (commodity == null && SysId.IsValid(commodityId)) + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) { - SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve commodity for Id: '{model.Commodity.Id}'"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); - } - // Create new item if required. - if (commodity == null) - { - commodity = CommodityMgr.CreateCommodity(model.GetCommodityType(), model.Commodity.Code); + // Retrieve existing item. + SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId); + disposables.Add(commodity); + if (commodity == null && SysId.IsValid(commodityId)) + { + SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve commodity for Id: '{model.Commodity.Id}'"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); + } + + // Create new item if required. + if (commodity == null) + { + commodity = CommodityMgr.CreateCommodity(model.GetCommodityType(), model.Commodity.Code); + disposables.Add(commodity); + } + + // Populate item properties. + if (model.Commodity.Type != null) + commodity.CommodityType = model.GetCommodityType(); if (model.Commodity.Code != null) commodity.Code = model.Commodity.Code; - } + if (model.Commodity.DescBrief != null) + commodity.DescBrief = model.Commodity.DescBrief; + // Common properties. + if (model.Commodity.Notes != null) + commodity.Notes = model.Commodity.Notes; + if (model.Commodity.StatusCode != null) + commodity.Status = model.GetCommodityStatus(); - // Populate item properties. - if (model.Commodity.Type != null) - commodity.CommodityType = model.GetCommodityType(); - if (model.Commodity.Code != null) - commodity.Code = model.Commodity.Code; - if (model.Commodity.DescBrief != null) - commodity.DescBrief = model.Commodity.DescBrief; - // Common properties. - if (model.Commodity.Notes != null) - commodity.Notes = model.Commodity.Notes; - if (model.Commodity.StatusCode != null) - commodity.Status = model.GetCommodityStatus(); - - // Store item. - if (!SysId.IsValid(commodity.Id)) - { - if (!CommodityMgr.InsertCommodity(commodity, DbUpdateInfo)) + // Store item. + if (!SysId.IsValid(commodity.Id)) { - SaLogger.Warn($"{SysUtil.Fn} Failed to insert commodity: {CommodityMgr.ErrorStateMessage}"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"])); + if (!CommodityMgr.InsertCommodity(commodity, DbUpdateInfo)) + { + SaLogger.Warn($"{SysUtil.Fn} Failed to insert commodity: {CommodityMgr.ErrorStateMessage}"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"])); + } + responseData.SetNotification(messageTitle, Localiser["msg.item.created"]); } - responseData.SetNotification(messageTitle, Localiser["msg.item.created"]); - } - else - { - if (!CommodityMgr.UpdateCommodity(commodity, DbUpdateInfo)) + else { - SaLogger.Warn($"{SysUtil.Fn} Failed to update commodity [Id:{SysId.ToLong(commodity.Id)}]: {CommodityMgr.ErrorStateMessage}"); - return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"])); + if (!CommodityMgr.UpdateCommodity(commodity, DbUpdateInfo)) + { + SaLogger.Warn($"{SysUtil.Fn} Failed to update commodity [Id:{SysId.ToLong(commodity.Id)}]: {CommodityMgr.ErrorStateMessage}"); + return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"])); + } + responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]); } - responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]); + UpdateAssociatedData(commodity); + + // Construct response. + model.PopulateItemConfig(responseData.Config, commodity); + PopulateCommodityResponseItemData(commodity, responseData.commodity); + responseData.Success = true; } - UpdateAssociatedData(commodity); - - // Construct response. - model.PopulateItemConfig(responseData.Config, commodity); - PopulateCommodityResponseItemData(commodity, responseData.commodity); - - // Complete response. - responseData.Success = true; - return Json(responseData); } diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/AssociationController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/AssociationController-Ajax.cs index 76506da..a7ab6d5 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/AssociationController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/AssociationController-Ajax.cs @@ -199,12 +199,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts // View mode. responseData.Mode = new AjaxResponse_AssociationList.ModeData(); - Model_Association.AssociationViewMode viewMode = model.GetFilterMode(); - if (viewMode == Model_Association.AssociationViewMode.Maintain) + Model_Association.ViewMode viewMode = model.GetFilterMode(); + if (viewMode == Model_Association.ViewMode.Maintain) responseData.Mode.Maintain = true; - else if (viewMode == Model_Association.AssociationViewMode.Relationships) + else if (viewMode == Model_Association.ViewMode.Relationships) responseData.Mode.Relationships = true; - else if (viewMode == Model_Association.AssociationViewMode.PriceSet) + else if (viewMode == Model_Association.ViewMode.PriceSet) responseData.Mode.PriceSet = true; else responseData.Mode.Search = true; diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/ContactController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/ContactController-Ajax.cs index 54cd499..d05380a 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/ContactController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Contacts/ContactController-Ajax.cs @@ -205,8 +205,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts // View mode. responseData.Mode = new AjaxResponse_ContactList.ModeData(); - Model_Contact.ContactViewMode viewMode = model.GetFilterMode(); - if (viewMode == Model_Contact.ContactViewMode.Maintain) + Model_Contact.ViewMode viewMode = model.GetFilterMode(); + if (viewMode == Model_Contact.ViewMode.Maintain) responseData.Mode.Maintain = true; else responseData.Mode.Search = true; @@ -215,7 +215,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); prmAffiliate.Search = model.Filter.Search; prmAffiliate.AffiliateType = model.GetFilterContactType(); - if (prmAffiliate.AffiliateType == Sbm.AffiliateType.Any && viewMode == Model_Contact.ContactViewMode.Search) + if (prmAffiliate.AffiliateType == Sbm.AffiliateType.Any && viewMode == Model_Contact.ViewMode.Search) prmAffiliate.AffiliateType = Sbm.AffiliateType.AnyContact; prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted; prmAffiliate.SortColumns.Add(AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Name)); diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/SbmController_Portal.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/SbmController_Portal.cs index eb72d55..059c142 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/SbmController_Portal.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/SbmController_Portal.cs @@ -28,6 +28,16 @@ using DocumentFormat.OpenXml.EMMA; using DocumentFormat.OpenXml.Wordprocessing; using Sarand.BusinessMgr.Net.Core.Web.Models; using Sarand.BusinessMgr.Web.Portal.Models; +using Sarand.BusinessMgr.Net.Standard.Base.Consoles; +using Sarand.Net.Standard.Base.CodeTypes; +using Sarand.Net.Standard.Base.Diary; +using Sarand.Net.Standard.Base.Email; +using Sarand.Net.Standard.Base.Interfaces; +using Sarand.Net.Standard.Base.ItemData; +using Sarand.Net.Standard.Base.ItemDocs; +using Sarand.Net.Standard.Base.ItemOptions; +using Sarand.Net.Standard.Base.ReferenceData; +using Sarand.Net.Standard.Base.UpdateLog; namespace Sarand.BusinessMgr.Web.Portal.Controllers { @@ -38,6 +48,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers { //------------------------------------------------------------------- // Data members. + private SbmInternals internals; private SbmSysParamCache sysParamCache = null; //------------------------------------------------------------------- @@ -49,12 +60,44 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers { if (disposing) { - if (sysParamCache != null) sysParamCache.Dispose(); - sysParamCache = null; + if (internals != null) internals.Dispose(); internals = null; + if (sysParamCache != null) sysParamCache.Dispose(); sysParamCache = null; } base.Dispose(disposing); } + //------------------------------------------------------------------- + // Properties. + public SbmInternals Internals { get { if (internals == null && UserContext_Core != null) { internals = new SbmInternals(UserContext_Core); } return internals; } } + // Managers. + public SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } } + public SbmAssetMgr AssetMgr { get { return Internals.AssetMgr; } } + public SbmCommodityMgr CommodityMgr { get { return Internals.CommodityMgr; } } + public SbmPriceMgr PriceMgr { get { return Internals.PriceMgr; } } + public SbmTransactionMgr TransactionMgr { get { return Internals.TransactionMgr; } } + public SbmStockMgr StockMgr { get { return Internals.StockMgr; } } + public SbmProcessMgr ProcessMgr { get { return Internals.ProcessMgr; } } + public SbmDataItemMgr DataItemMgr { get { return Internals.DataItemMgr; } } + // Consoles. + public SbmSessionConsole SessionConsole { get { return Internals.SessionConsole; } } + public SaDiaryConsole DiaryConsole { get { return Internals.DiaryConsole; } } + public SaSecurityConsole SecurityConsole { get { return Internals.SecurityConsole; } } + public SaCodeTypeConsole CodeTypeConsole { get { return Internals.CodeTypeConsole; } } + public SaReferenceDataConsole ReferenceDataConsole { get { return Internals.ReferenceDataConsole; } } + public SaUpdateLogConsole UpdateLogConsole { get { return Internals.UpdateLogConsole; } } + public SaInterfaceConsole InterfaceConsole { get { return Internals.InterfaceConsole; } } + public SaItemDocConsole ItemDocConsole { get { return Internals.ItemDocConsole; } } + public SaItemOptionConsole ItemOptionConsole { get { return Internals.ItemOptionConsole; } } + public SaItemDataConsole ItemDataConsole { get { return Internals.ItemDataConsole; } } + // Configurations. + public SbmStockControlConfig StockControlConfig { get { return Internals.StockControlConfig; } } + public SbmRequirementCostingConfig RequirementCostingConfig { get { return Internals.RequirementCostingConfig; } } + // System codes. + public List GetCodesOfType(Sbm.SystemCode systemCode) { return Internals.GetSystemCodes(systemCode); } + // Email. + public SaEmailConfig EmailConfig { get { return Internals.EmailConfig; } } + public SbmEmailConsole EmailConsole { get { return Internals.EmailConsole; } } + //------------------------------------------------------------------- // Session data. @@ -84,24 +127,26 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers /// - Open user session - store details against Sesion Data. /// - Set 'Keep logged in' cookie if required. ///
- protected bool SignUserIn(SbmInternals internalsForUser, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage) + protected bool SignUserIn(SbmSessionData_Portal sessionDataForUser, SbmInternals internalsForUser, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage) { + string errorPrefix = $"Unable to sign account in"; + string errorSuffix = $"Context: {sessionDataForUser.RepositoryContext}. Email: {sessionDataForUser.UserEmailAddress}."; // Validate Security Item and Affiliate, just in case - should have been done before arriving here! if (securityItemUser == null) { - SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - null security item."); + SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - null security item. {errorSuffix}"); errorMessage = Localiser["security.msg.signin.invalid"]; return false; } if (affiliateUser == null) { - SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - null affiliate."); + SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - null affiliate. {errorSuffix}"); errorMessage = Localiser["security.msg.signin.invalid"]; return false; } if (!affiliateUser.IsStatusCurrent) { - SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - affiliate is not active. Email: {securityItemUser.EmailAddress}"); + SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - affiliate is not active. {errorSuffix}"); errorMessage = Localiser["security.msg.signin.invalid"]; return false; } @@ -109,54 +154,64 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers // Organisation. if (associationOrganisation == null) { - SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - null organisation association."); + SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - null organisation association. {errorSuffix}"); errorMessage = Localiser["security.msg.signin.invalid"]; return false; } if (associationOrganisation.AssociationType != Sbm.AssociationType.Internal) { - SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - organisation association is not type 'Internal'."); + SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - organisation association is not type 'Internal'. {errorSuffix}"); errorMessage = Localiser["security.msg.signin.invalid"]; return false; } if (affiliateOrganisation == null) { - SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - null organisation affiliate."); + SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - null organisation affiliate. {errorSuffix}"); errorMessage = Localiser["security.msg.signin.invalid"]; return false; } + // Verify Organisation is supervised by User. + if (!internalsForUser.AccountMgr.IsAffiliateSupervisedBy(affiliateOrganisation.Id, affiliateUser.Id)) + { + SaLogger.Warn($"{SysUtil.Fn} {errorPrefix} - Organisation is not supervised by user. {errorSuffix}"); + errorMessage = Localiser["security.msg.signin.invalid"]; + return false; + } + + // Configure security profile. + sessionDataForUser.SecurityProfile_Core.RefreshProfile(internalsForUser.SessionConsole, internalsForUser.SecurityConsole, securityItemUser.Id, internalsForUser.SecurityConsole.GetRegisteredRights()); + // 'Keep logged in' can be switched off by the application configuration. keepLoggedIn = App.AppConfig.Security.SignIn.KeepLoggedIn.Allowed && keepLoggedIn; - using (DisposableCollection disposables = new DisposableCollection()) + // Log user in. + securityItemUser.LastLogin = DateTime.Now; + securityItemUser.InvalidLoginCount = 0; + securityItemUser.LastInvalidLoginAt = DateTime.MinValue; + if (!internalsForUser.SecurityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo)) { - // Log user in. - securityItemUser.LastLogin = DateTime.Now; - securityItemUser.InvalidLoginCount = 0; - securityItemUser.LastInvalidLoginAt = DateTime.MinValue; - if (!internalsForUser.SecurityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo)) - { - SaLogger.Warn($"{SysUtil.Fn} Failed to update security item for {securityItemUser.EmailAddress}: {internalsForUser.SecurityConsole.ErrorStateMessage}"); - errorMessage = Localiser["security.msg.signin.invalid"]; - return false; - } + SaLogger.Warn($"{SysUtil.Fn} Failed to update security item for {securityItemUser.EmailAddress}: {internalsForUser.SecurityConsole.ErrorStateMessage}"); + errorMessage = Localiser["security.msg.signin.invalid"]; + return false; + } - // Update affiliate. - affiliateUser.KeepLoggedIn_Portal = keepLoggedIn; - if (!internalsForUser.AccountMgr.UpdateAffiliate(affiliateUser, DbUpdateInfo)) - { - SaLogger.Warn($"{SysUtil.Fn} Failed to update affiliate for {securityItemUser.EmailAddress}: {internalsForUser.AccountMgr.ErrorStateMessage}"); - errorMessage = Localiser["security.msg.signin.invalid"]; - return false; - } - SaLogger.Info($"{SysUtil.Fn} User session opened for {securityItemUser.EmailAddress}", true); + // Update affiliate. + affiliateUser.KeepLoggedIn_Portal = keepLoggedIn; + if (!internalsForUser.AccountMgr.UpdateAffiliate(affiliateUser, DbUpdateInfo)) + { + SaLogger.Warn($"{SysUtil.Fn} Failed to update affiliate for {securityItemUser.EmailAddress}: {internalsForUser.AccountMgr.ErrorStateMessage}"); + errorMessage = Localiser["security.msg.signin.invalid"]; + return false; + } + SaLogger.Info($"{SysUtil.Fn} User session opened for {securityItemUser.EmailAddress}", true); - // Create session. - OpenUserSession(internalsForUser.SessionContext, repositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation); - - // Configure security profile. - SessionData_Portal.SecurityProfile_Core.RefreshProfile(SessionConsole, internalsForUser.SecurityConsole, securityItemUser.Id, internalsForUser.SecurityConsole.GetRegisteredRights()); + // Create session. + if (!OpenUserSession(sessionDataForUser)) + { + SaLogger.Warn($"{SysUtil.Fn} Failed to open user session. Repository context: {sessionDataForUser.RepositoryContext}. Email: {securityItemUser.EmailAddress}."); + errorMessage = Localiser["security.msg.signin.invalid"]; + return false; } // Send the 'Keep Logged In' cookie if requested. @@ -168,7 +223,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers //------------------------------------------------------------------- /// Populate the user's profile contact details to the session. - protected bool RefreshSessionProfileContact(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) + protected bool RefreshSessionData(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) { SbmSessionData_Portal sessionData = SessionData_Portal; SysId affiliateIdUser = sessionData?.User?.AffiliateId ?? null; @@ -177,24 +232,30 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers if (!affiliateIdUser.Equals(affiliateUser.Id)) return false; if (!SysId.IsValid(affiliateOrganisation?.Id ?? null)) return false; - sessionData.RefreshUser(securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation); + sessionData.Refresh(securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation); return true; } //------------------------------------------------------------------- /// Start a new user session on sign-in. - protected bool OpenUserSession(SbmSessionContext sessionContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) + protected bool OpenUserSession(SbmSessionData_Portal sessionDataForUser) { // Validate user properties. - if (!SysId.IsValid(affiliateUser.Id)) return false; - if (StringUtil.IsEmpty(securityItemUser.EmailAddress)) return false; + if (!SysId.IsValid(sessionDataForUser.UserAffiliateId)) + { + return false; + } + if (StringUtil.IsBlank(sessionDataForUser.UserEmailAddress)) + { + return false; + } // Close previous session. CloseUserSession(); // Open session. - return SetSessionData(new SbmSessionData_Portal(sessionContext, repositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation)); + return SetSessionData(sessionDataForUser); } protected void CloseUserSession() { @@ -267,8 +328,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers if (sessionContext != null) { // Consoles and Managers must be associated with the specific context. - SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext); - using (SbmInternals internalsForUser = new SbmInternals(userContext)) + SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContext, keepLoggedInParams.RepositoryContext, null, null, null, null); + using (SbmInternals internalsForUser = new SbmInternals(sessionDataForUser)) { using (SaSecurityItem securityItemUser = internalsForUser.SecurityConsole.GetUserByEmail(keepLoggedInParams.EmailAddress)) using (SbmAffiliate affiliateUser = internalsForUser.AccountMgr.GetAffiliateById(keepLoggedInParams.AffiliateIdUser)) @@ -281,10 +342,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers { if (affiliateUser.IsStatusCurrent) { - List supervisedOrganisations = internalsForUser.AccountMgr.GetAffiliatesSupervisedBy(affiliateUser.Id); + // Bring the Session Data up to date with the session properties. + sessionDataForUser.Refresh(securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation); String errorMessage = ""; - if (SignUserIn(internalsForUser, keepLoggedInParams.RepositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage)) + if (SignUserIn(sessionDataForUser, internalsForUser, securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation, true, ref errorMessage)) { + // User auto-login successful. SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix); return true; } diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController-Ajax.cs index 240068c..d55c3fb 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController-Ajax.cs @@ -93,24 +93,24 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security { if (sessionContext == null) return false; - SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext); + SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContext, model.RepositoryContext, null, null, null, null); ISacsDatabase busMgrDatabase = App.GetBusMgrDatabase(sessionContext); if (busMgrDatabase == null) return false; using (DisposableCollection disposables = new DisposableCollection()) { - SbmInternals internalsForUser = new SbmInternals(userContext); + SbmInternals internalsForUser = new SbmInternals(sessionDataForUser); disposables.Add(internalsForUser); // User's security item. - SaSecurityItem securityItemUser = GetSecurityItemForSignin(userContext, internalsForUser.SecurityConsole, model); + SaSecurityItem securityItemUser = GetSecurityItemForSignin(sessionDataForUser, internalsForUser.SecurityConsole, model); disposables.Add(securityItemUser); if (securityItemUser == null) { SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve Security Item. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}."); return false; } - if (!internalsForUser.SecurityConsole.PasswordMatches(securityItemUser, model.Password, userContext.DbUpdateInfo)) + if (!internalsForUser.SecurityConsole.PasswordMatches(securityItemUser, model.Password, sessionDataForUser.DbUpdateInfo)) { SaLogger.Warn($"{SysUtil.Fn} Supplied password doesn't match Security Item. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}."); return false; @@ -125,17 +125,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security return false; } - // User's supervised organisations. - List supervisedOrganisations = internalsForUser.AccountMgr.GetAffiliatesSupervisedBy(affiliateUser.Id); - if (supervisedOrganisations.IsEmpty()) - { - SaLogger.Warn($"{SysUtil.Fn} User has no supervised organisations. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}."); - return false; - } - userContext.RefreshUser(securityItemUser, affiliateUser, supervisedOrganisations); - // User's organisation association. - SbmAssociation associationOrganisation = GetOrganisationAssociationForSignIn(internalsForUser.AccountMgr, model, userContext); + SbmAssociation associationOrganisation = GetOrganisationAssociationForSignIn(internalsForUser.AccountMgr, model, sessionDataForUser); disposables.Add(associationOrganisation); if (associationOrganisation == null) { @@ -152,15 +143,18 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security return false; } + // Populate User properties to the Session Data. + sessionDataForUser.Refresh(securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation); + // Initialise user session. - if (SignUserIn(internalsForUser, model.RepositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage)) + if (SignUserIn(sessionDataForUser, internalsForUser, securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage)) return true; } return false; } //------------------------------------------------------------------- - private SaSecurityItem GetSecurityItemForSignin(SbmUserContext_Web userContext, SaSecurityConsole securityConsoleForUser, Model_Security model) + private SaSecurityItem GetSecurityItemForSignin(ISbmUserContext userContext, SaSecurityConsole securityConsoleForUser, Model_Security model) { // Retrieve security item by email address. SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress); @@ -216,13 +210,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security /// /// Identify the organisation for the user to login to - either last selected (via SysParam) or first in list. /// - private SbmAssociation GetOrganisationAssociationForSignIn(SbmAccountMgr accountMgrForUser, Model_Security model, SbmUserContext userContext) + private SbmAssociation GetOrganisationAssociationForSignIn(SbmAccountMgr accountMgrForUser, Model_Security model, ISbmUserOrganisationContext userContext) { // Previously selected organisation is stored in user params (SysParam table). SbmSysParamCache sysParamCache = new SbmSysParamCache(userContext, userContext.UserAffiliateId); SysId affiliateIdOrganisation = SysId.ToSysId(sysParamCache.GetUserParamValue(SbmSysParamCache.ParamName_SelectedCompany)); SbmAssociation associationOrganisation = null; - foreach (SysIdString supervisedOrganisation in userContext.SupervisedOrganisations) + List supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(userContext.UserAffiliateId); + foreach (SysIdString supervisedOrganisation in supervisedOrganisations) { SbmAssociation associationOrganisationCandidate = accountMgrForUser.GetAssociationByOwnerTypeTarget(supervisedOrganisation.Id, Sbm.AssociationType.Internal, supervisedOrganisation.Id); if (associationOrganisationCandidate == null) @@ -374,10 +369,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security // Validate referrer. if (!ValidReferer) return Forbid(); - // If user is logged in, session Consoles and Managers can be used. - // If 'Request Password' parameters are specified, Consoles and Managers must be associated with the specific database for the user. - SbmSessionContext sessionContextForUser = null; - SbmUserContext_Web userContextForUser = null; + // If user is logged in, session Internals can be used. + // If 'Request Password' parameters are specified, Internals must be associated with the specific context for the user. + SbmInternals internalsForUser = null; // If 'Request Password' encrypted params (from email link) are present, // Session is not required and password can be set directly against the user. @@ -389,29 +383,27 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security if (storePasswordParams.IsValid()) { // Instance Repository configured on Control database identified by Context. - SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(storePasswordParams.RepositoryContext); - if (sessionContext != null) + SbmSessionContext sessionContextForUser = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(storePasswordParams.RepositoryContext); + if (sessionContextForUser != null) { - // Consoles and Managers must be associated with the specific context. - SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext); - using (SbmInternals internalsForUser = new SbmInternals(userContext)) + // Consoles and Managers must be associated with the specific context for the User storing the password. + SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContextForUser, storePasswordParams.RepositoryContext, null, null, null, null); + internalsForUser = new SbmInternals(sessionDataForUser); + // Retrieve user details and validate email address. + securityItemUser = internalsForUser.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, storePasswordParams.SecurityItemId); + affiliateUser = internalsForUser.AccountMgr.GetAffiliateById(storePasswordParams.AffiliateId); + if (storePasswordParams.IsValid(securityItemUser, affiliateUser)) { - // Retrieve user details and validate email address. - securityItemUser = internalsForUser.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, storePasswordParams.SecurityItemId); - affiliateUser = internalsForUser.AccountMgr.GetAffiliateById(storePasswordParams.AffiliateId); - if (storePasswordParams.IsValid(securityItemUser, affiliateUser)) - { - sessionContextForUser = sessionContext; - userContextForUser = userContext; - validRequestPasswordParams = true; - validSessionRequired = false; - } - else - { - SaLogger.Warn($"{SysUtil.Fn} 'Request Password' parameters supplied but invalid. Email: {storePasswordParams.EmailAddress}. SecurityItemId: {SysId.ToString(storePasswordParams.SecurityItemId)}. AffiliateId: {SysId.ToString(storePasswordParams.AffiliateId)}."); - if (securityItemUser != null) securityItemUser.Dispose(); securityItemUser = null; - if (affiliateUser != null) affiliateUser.Dispose(); affiliateUser = null; - } + sessionDataForUser.Refresh(securityItemUser, affiliateUser, null, null); + validRequestPasswordParams = true; + validSessionRequired = false; + } + else + { + SaLogger.Warn($"{SysUtil.Fn} 'Request Password' parameters supplied but invalid. Email: {storePasswordParams.EmailAddress}. SecurityItemId: {SysId.ToString(storePasswordParams.SecurityItemId)}. AffiliateId: {SysId.ToString(storePasswordParams.AffiliateId)}."); + if (securityItemUser != null) securityItemUser.Dispose(); securityItemUser = null; + if (affiliateUser != null) affiliateUser.Dispose(); affiliateUser = null; + if (internalsForUser != null) internalsForUser.Dispose(); internalsForUser = null; } } } @@ -420,20 +412,24 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security if (validSessionRequired && (securityItemUser == null || affiliateUser == null) && !ValidUserSession) return Json(responseData.SetSessionExpired(messageTitle, Localiser["security.msg.warn.sessionExpired"])); - // User specific Consoles and Managers if User Context specified. - using (SaSecurityConsole securityConsoleForUser = userContextForUser != null ? App.CreateSecurityConsole(userContextForUser) : null) - using (SbmAccountMgr accountMgrForUser = userContextForUser != null ? App.System.CreateAccountMgr(userContextForUser) : null) + // User specific Internals if Request Password params supplied, otherwise use Session Internals for current User Session. + SbmInternals internalsForStorePassword = internalsForUser ?? Internals; + + using (DisposableCollection disposables = new DisposableCollection()) { - SaSecurityConsole securityConsole = (securityConsoleForUser ?? SecurityConsole); - SbmAccountMgr accountMgr = (accountMgrForUser ?? AccountMgr); + disposables.Add(internalsForUser); + disposables.Add(securityItemUser); + disposables.Add(affiliateUser); // Retrieve user details if not previously populated. if (securityItemUser == null && SessionData_Portal != null) - securityItemUser = (securityConsole.GetSecurityItemById(SaSecurity.ItemType.User, SessionData_Portal.User.SecurityItemId)); + securityItemUser = internalsForStorePassword.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, SessionData_Portal.User.SecurityItemId); + disposables.Add(securityItemUser); if (securityItemUser == null) return Json(responseData.SetControlError(nameof(model.Password), "System error - failed to retrieve security item details.")); if (affiliateUser == null && SessionData_Portal != null) - affiliateUser = accountMgr.GetAffiliateById(SessionData_Portal.User.AffiliateId); + affiliateUser = internalsForStorePassword.AccountMgr.GetAffiliateById(SessionData_Portal.User.AffiliateId); + disposables.Add(affiliateUser); if (affiliateUser == null) return Json(responseData.SetControlError(nameof(model.Password), "System error - failed to retrieve affiliate details.")); @@ -447,7 +443,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security // Store password. // NB Do not use Microsoft.AspNetCore.Identity.PasswordHasher.HashPassword() while legacy (C++) desktop application still in use. - securityConsole.SetPassword(securityItemUser, model.Password); + internalsForStorePassword.SecurityConsole.SetPassword(securityItemUser, model.Password); securityItemUser.PasswordChangedAt = DateTime.Now; // Remove new password from history if present. for (int passwordHistoryIdx = 0; passwordHistoryIdx < securityItemUser.PasswordHistory.Count; passwordHistoryIdx++) @@ -465,21 +461,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security securityItemUser.PasswordHistory.Add(oldPasswordHashed); while (securityItemUser.PasswordHistory.Count > 10) securityItemUser.PasswordHistory.RemoveAt(securityItemUser.PasswordHistory.Count - 1); - if (!securityConsole.UpdateSecurityItem(securityItemUser, userContextForUser?.DbUpdateInfo ?? DbUpdateInfo)) + if (!internalsForStorePassword.SecurityConsole.UpdateSecurityItem(securityItemUser, internalsForStorePassword.DbUpdateInfo)) { - SaLogger.Warn($"{SysUtil.Fn} Failed to change password for {securityItemUser.EmailAddress}: {securityConsole.ErrorStateMessage}"); + SaLogger.Warn($"{SysUtil.Fn} Failed to change password for {securityItemUser.EmailAddress}: {internalsForStorePassword.SecurityConsole.ErrorStateMessage}"); return Json(responseData.SetControlError(nameof(model.Password), Localiser["security.msg.change.password.failed"])); } SaLogger.Info($"{SysUtil.Fn} Password changed for {securityItemUser.EmailAddress}.", true); } - // Cleanup. NB The Security Item and/or Affiliate aren't disposed when the method - // returns above but these objects shouldn't be carrying any disposable resources. - if (securityItemUser != null) securityItemUser.Dispose(); securityItemUser = null; - if (affiliateUser != null) affiliateUser.Dispose(); affiliateUser = null; - sessionContextForUser = null; - userContextForUser = null; - // Construct response. responseData.Success = true; if (validRequestPasswordParams) @@ -517,10 +506,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(model.RepositoryContext); if (sessionContext != null) { - SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext); + SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContext, model.RepositoryContext, null, null, null, null); // Get user security item and affiliate. - using (SbmInternals internalsForUser = new SbmInternals(userContext)) + using (SbmInternals internalsForUser = new SbmInternals(sessionDataForUser)) using (SaSecurityItem securityItemUser = internalsForUser.SecurityConsole.GetUserByEmail(model.EmailAddress)) { if (securityItemUser != null) @@ -529,16 +518,17 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security { if (affiliateUser != null) { + sessionDataForUser.Refresh(securityItemUser, affiliateUser, null, null); if (affiliateUser.Status == SaStatus.Current || affiliateUser.IsStatusActive) { - SbmEmailConsole emailConsole = App.CreateEmailConsole(userContext); + SbmEmailConsole emailConsole = internalsForUser.EmailConsole; // Send password request email. SaEmailData emailData = new SaEmailData(); emailData.Config = App.EmailConfig; emailData.AddressesTo.Add(model.EmailAddress); emailData.Subject = Localiser["security.caption.request.password"]; - PopulateRequestPasswordEmailBody(emailConsole, userContext, emailData, securityItemUser, affiliateUser); + PopulateRequestPasswordEmailBody(emailConsole, sessionDataForUser, emailData, securityItemUser, affiliateUser); if (emailConsole.SendEmail(emailData)) SaLogger.Info($"{SysUtil.Fn} Password request email sent to {model.EmailAddress}.", true); else SaLogger.Warn($"{SysUtil.Fn} Failed to send password request email to {model.EmailAddress}."); diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController.cs index 4601364..e687a63 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Security/SecurityController.cs @@ -17,6 +17,7 @@ using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Sarand.BusinessMgr.Web.Portal.Helpers; +using Sarand.BusinessMgr.Web.Portal.App; namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security { @@ -81,12 +82,13 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security if (sessionContext != null) { // Consoles and Managers must be associated with the specific context. - SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext); - using (SbmInternals internalsForUser = new SbmInternals(userContext)) + SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContext, changePasswordParams.RepositoryContext, null, null, null, null); + using (SbmInternals internalsForUser = new SbmInternals(sessionDataForUser)) { using (SaSecurityItem securityItemUser = internalsForUser.SecurityConsole.GetUserByEmail(changePasswordParams.EmailAddress)) using (SbmAffiliate affiliateUser = internalsForUser.AccountMgr.GetAffiliateById(changePasswordParams.AffiliateId)) { + sessionDataForUser.Refresh(securityItemUser, affiliateUser, null, null); if (securityItemUser != null && affiliateUser != null) { if (securityItemUser.Id.Equals(changePasswordParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id)) diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Transactions/TransactionController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Transactions/TransactionController-Ajax.cs index 8e0a69c..9e3875f 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Transactions/TransactionController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Transactions/TransactionController-Ajax.cs @@ -96,7 +96,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions public AjaxResponse_TransactionConfig(SbmModel_Portal model) : base(model) { } // Configuration. public Model_Transaction.ListConfigData Config { get; } = new Model_Transaction.ListConfigData(); - public Model_Transaction.ItemConfigData ConfigCmd { get; } = new Model_Transaction.ItemConfigData(); + public Model_Transaction.ItemConfigData ConfigItemNew { get; } = new Model_Transaction.ItemConfigData(); // Reference data. public List TransactionTypes { get; } = new List(); public List Statuses { get; } = new List(); @@ -127,7 +127,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions { // Configuration. model.PopulateListConfig(responseData.Config); - model.PopulateItemConfig(responseData.ConfigCmd, null, Sbm.TransactionType.Unknown); + model.PopulateItemConfig(responseData.ConfigItemNew, null, Sbm.TransactionType.Unknown); // Reference data - transaction types. foreach (TypeCodeDesc transactionType in GetCodesOfType(Sbm.SystemCode.TransactionType)) diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/VehicleClassController-Ajax.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Vehicles/VehicleClassController-Ajax.cs similarity index 95% rename from SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/VehicleClassController-Ajax.cs rename to SaBusinessMgrCoreWebPortal/Portal/Controllers/Vehicles/VehicleClassController-Ajax.cs index bb3a94a..0c5c17a 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/VehicleClassController-Ajax.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Vehicles/VehicleClassController-Ajax.cs @@ -3,7 +3,7 @@ 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.Web.Portal.Models; -using Sarand.BusinessMgr.Web.Portal.Models.Assets; +using Sarand.BusinessMgr.Web.Portal.Models.Vehicles; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; @@ -13,7 +13,7 @@ using System; using System.Collections.Generic; using System.Linq; -namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets +namespace Sarand.BusinessMgr.Web.Portal.Controllers.Vehicles { //======================================================================= partial class VehicleClassController @@ -71,9 +71,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets } //------------------------------------------------------------------- [HttpPost] - [Route("Assets/VehicleClass/Ajax/GetList")] - [Route("Assets/VehicleClass/Ajax/GetVehicleClasses")] - [Route("Assets/VehicleClass/Ajax/GetVehicleClassList")] + [Route("Vehicles/VehicleClass/Ajax/GetList")] + [Route("Vehicles/VehicleClass/Ajax/GetVehicleClasses")] + [Route("Vehicles/VehicleClass/Ajax/GetVehicleClassList")] public IActionResult Ajax_GetVehicleClassList(Model_VehicleClass model) { String messageTitle = Localiser["caption.vehicle.classes"]; @@ -96,7 +96,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets // Item filter. SbmVehicleClass.Params prmVehicleClass = new SbmVehicleClass.Params(); prmVehicleClass.Search = model.Filter.Search; - prmVehicleClass.StatusCat = model.Filter.GetStatusCat(); + prmVehicleClass.StatusCat = model.GetFilterStatusCat(); model.Paging.ItemTotal = (ulong)AssetMgr.GetVehicleClassCount(prmVehicleClass); model.PopulatePagingTo(prmVehicleClass.ResultsPaging); @@ -157,8 +157,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets } //------------------------------------------------------------------- [HttpPost] - [Route("Assets/VehicleClass/Ajax/GetItem")] - [Route("Assets/VehicleClass/Ajax/GetVehicleClass")] + [Route("Vehicles/VehicleClass/Ajax/GetItem")] + [Route("Vehicles/VehicleClass/Ajax/GetVehicleClass")] public IActionResult Ajax_GetVehicleClass(Model_VehicleClass model) { String messageTitle = Localiser["caption.vehicle.class"]; @@ -198,8 +198,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets // Store VehicleClass ajax request. //------------------------------------------------------------------- [HttpPost] - [Route("Assets/VehicleClass/Ajax/StoreItem")] - [Route("Assets/VehicleClass/Ajax/StoreVehicleClass")] + [Route("Vehicles/VehicleClass/Ajax/StoreItem")] + [Route("Vehicles/VehicleClass/Ajax/StoreVehicleClass")] public IActionResult Ajax_StoreVehicleClass(Model_VehicleClass model) { String messageTitle = Localiser["caption.vehicle.class"]; diff --git a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/VehicleClassController.cs b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Vehicles/VehicleClassController.cs similarity index 87% rename from SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/VehicleClassController.cs rename to SaBusinessMgrCoreWebPortal/Portal/Controllers/Vehicles/VehicleClassController.cs index 07362eb..e328d24 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Controllers/Assets/VehicleClassController.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Controllers/Vehicles/VehicleClassController.cs @@ -2,14 +2,14 @@ using Microsoft.Extensions.Logging; using Sarand.BusinessMgr.Net.Core.Web.App; using Sarand.BusinessMgr.Web.Portal.Models; -using Sarand.BusinessMgr.Web.Portal.Models.Assets; +using Sarand.BusinessMgr.Web.Portal.Models.Vehicles; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets +namespace Sarand.BusinessMgr.Web.Portal.Controllers.Vehicles { //====================================================================== public partial class VehicleClassController : SbmController_Portal @@ -25,7 +25,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets } //------------------------------------------------------------------- - [Route("Assets/VehicleClass")] + [Route("Vehicles/VehicleClass")] public IActionResult Index() { if (!ValidUserSession) @@ -40,7 +40,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets // VehicleClass page. Model_VehicleClass model = new Model_VehicleClass(Localiser); - return View("Views/Assets/VehicleClass/Index.cshtml", model); + return View("Views/Vehicles/VehicleClass/Index.cshtml", model); } //------------------------------------------------------------------- diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_Asset.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_Asset.cs index c16c8ce..143a357 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_Asset.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_Asset.cs @@ -15,7 +15,7 @@ using System; namespace Sarand.BusinessMgr.Web.Portal.Models.Assets { //======================================================================= - public class Model_Asset : SbmModel_Portal + public partial class Model_Asset : SbmModel_Portal { //------------------------------------------------------------------- // Construction. diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_AssetCategory-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_AssetCategory-Config.cs new file mode 100644 index 0000000..eb3aa09 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_AssetCategory-Config.cs @@ -0,0 +1,258 @@ +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Bus; +using System; +using System.Collections.Generic; +using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm; + +namespace Sarand.BusinessMgr.Web.Portal.Models.Assets +{ + //======================================================================= + // Asset Category model - Configuration. + //======================================================================= + partial class Model_AssetCategory + { + //------------------------------------------------------------------- + + /// Prefix for field names. + public const String FieldNamePrefix = "AssetCat"; + + /// Item fields. + public enum ItemField + { + // AssetCategory properties. + Id, + // Identity. + Type, + Code, + Caption, + // Defaults. + IncomeType, + // Purchase. + TaxCodePurchase, + PaymentTerms, + // Sale. + TaxCodeSale, + TaxCodeProfit, + // Associated properties. + AssetCount, + // Common. + Notes, + Status, + CreatedOn, + UpdatedOn, + Actions, + } + + /// + /// Identifier used by form fields to show control specific messages generated by model validation etc. + /// - Both page and model should use this method to consistently generate the field name. + /// + public static String GetFieldName(ItemField field) + { + return $"{FieldNamePrefix}{field}"; + } + + // List configuration. + public class ListConfigData + { + // Actions. + public class ActionData + { + public class AllowData + { + public bool? Create { get; set; } + public bool? Update { get; set; } + } + public AllowData Allow { get; } = new AllowData(); + } + public ActionData Action { get; } = new ActionData(); + // List columns. + public class ColumnData + { + // Column name prefix. + public String Prefix { get; } = Model_AssetCategory.FieldNamePrefix; + // Hide column. + public HashSet Hide { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Column labels. + public Dictionary Label { get; } = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + } + public ColumnData Column { get; } = new ColumnData(); + } + public ListConfigData ListConfig { get; private set; } + + //------------------------------------------------------------------- + /// + /// Populate AssetCategory list configuration data - only required on initial page construction. + /// + public void PopulateListConfig() + { + ListConfig = new ListConfigData(); + PopulateListConfig(ListConfig); + } + public void PopulateListConfig(ListConfigData config) + { + ViewMode pageMode = GetFilterMode(); + bool modeIsSearch = pageMode == ViewMode.Search; + bool modeIsMaintain = pageMode == ViewMode.Maintain; + bool userCanCreateAssetCategories = SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(Sbm.ItemType.AssetCategory); + bool userCanUpdateAssetCategories = SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(Sbm.ItemType.AssetCategory); + + // Actions. + + if (userCanCreateAssetCategories) + config.Action.Allow.Create = true; + if (userCanUpdateAssetCategories) + config.Action.Allow.Update = true; + + // List columns. + + if (GetFilterAssetType() <= 0) + config.Column.Hide.Add($"{ItemField.Type}"); + + // Asset Category Assets. + if (!modeIsMaintain || !SessionConsole.AllowOption(Sbm.ConfigOption.Assets)) + config.Column.Hide.Add($"{ItemField.AssetCount}"); + + // Actions. + if (!modeIsMaintain) + config.Column.Hide.Add($"{ItemField.Actions}"); + } + + //------------------------------------------------------------------- + // Item configuration. + //------------------------------------------------------------------- + // Legacy AssetCategory dialog tabs and panels. + // Dialog: + // - Asset type, code, caption. + // Tab 1 'Properties': + // Defaults - Income type. + // Purchase - Purcahse tax code, payment terms. + // Sale - Sell tax code, profit tax code. + // Notes. + // Tab 2 'Processes'. + //------------------------------------------------------------------- + + public class ItemConfigData + { + // Update dialog title. + public String Title { get; set; } + // Pre-select AssetCategory type. + public class TypeData + { + public TypeData(string code, String desc) + { + Code = code; + Desc = desc; + } + public String Code { get; set; } + public String Desc { get; set; } + } + public TypeData Type { get; set; } + // Field name prefix. + public String Prefix { get; } = Model_AssetCategory.FieldNamePrefix; + // Control flags. + public bool? ManagedByAccounts { get; set; } + public bool? LocalPricing { get; set; } + // Allowed actions. + public class AllowData + { + public bool? UpdateCode { get; set; } + } + public AllowData Allow { get; } = new AllowData(); + // Item fields. + public class FieldData + { + // Field name prefix. + public String Prefix { get; } = Model_AssetCategory.FieldNamePrefix; + // Hide field. + public HashSet Hide { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Read-only field. + public HashSet Readonly { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Field labels. + public Dictionary Label { get; } = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + } + public FieldData Field { get; } = new FieldData(); + } + /// + /// Populate item configuration for existing vehicle. + /// + public void PopulateItemConfig(ItemConfigData config, SbmAssetCategory assetCategory) + { + PopulateItemConfig(config, assetCategory.GetItemId(), assetCategory.AssetType); + } + /// + /// Populate item configuration for new or existing vehicle. + /// + public void PopulateItemConfig(ItemConfigData config, ItemId assetCategoryId, Sbm.AssetType assetType) + { + // Session configuration. + bool userCanCreateAssetCategories = SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(Sbm.ItemType.AssetCategory); + bool userCanUpdateAssetCategories = SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(Sbm.ItemType.AssetCategory); + + // Update dialog title. + config.Title = Localiser["caption.vehicle.update"]; + + //--------------------------------------------------------------- + // Identity. + + // Asset type. + // ToDo - Asset type readonly if any associated assets. + if (!userCanUpdateAssetCategories || (ItemId.IsValid(assetCategoryId) && AssetMgr.AssetCategoryHasAssets(assetCategoryId.Id))) + config.Field.Readonly.Add($"{ItemField.Type}"); + + // Code. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.Code}"); + + // Caption. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.Caption}"); + + //--------------------------------------------------------------- + // Defaults. + + // Income type. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.IncomeType}"); + + //--------------------------------------------------------------- + // Purchase. + + // Tax code - purchase. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.TaxCodePurchase}"); + + // Payment terms. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.PaymentTerms}"); + + //--------------------------------------------------------------- + // Sale. + + // Tax code - sell. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.TaxCodeSale}"); + + // Tax code - profit. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.TaxCodeProfit}"); + + //--------------------------------------------------------------- + // Common properties. + + // Status. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.Status}"); + + // Notes. + if (!userCanUpdateAssetCategories) + config.Field.Readonly.Add($"{ItemField.Notes}"); + + //--------------------------------------------------------------- + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_AssetCategory.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_AssetCategory.cs index f2e4248..fe57cb1 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_AssetCategory.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_AssetCategory.cs @@ -1,4 +1,5 @@ using DocumentFormat.OpenXml.Spreadsheet; +using Microsoft.AspNetCore.Http; using Sarand.BusinessMgr.Net.Core.Web.App; using Sarand.BusinessMgr.Net.Core.Web.Controllers; using Sarand.BusinessMgr.Net.Standard.Base.App; @@ -15,8 +16,15 @@ using System; namespace Sarand.BusinessMgr.Web.Portal.Models.Assets { //======================================================================= - public class Model_AssetCategory : SbmModel_Portal + public partial class Model_AssetCategory : SbmModel_Portal { + //------------------------------------------------------------------- + // Definitions. + public enum ViewMode + { + Search, Maintain + } + //------------------------------------------------------------------- // Construction. public Model_AssetCategory(SbmLocaliser localiser) : @@ -28,14 +36,24 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets // Filter properties. public class FilterData { + public String Mode { get; set; } + public String AssetType { get; set; } public String Search { get; set; } public String StatusCat { get; set; } - public SbmAssetCategory.StatusCat GetStatusCat() - { - return EnumUtil.ParseEnum(StatusCat, SbmAssetCategory.StatusCat.NotDeleted); - } } public FilterData Filter { get; } = new FilterData(); + public ViewMode GetFilterMode() + { + return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search); + } + public Sbm.AssetType GetFilterAssetType() + { + return EnumUtil.ParseEnum(Filter.AssetType, Sbm.AssetType.Unknown); + } + public SbmAssetCategory.StatusCat GetFilterStatusCat() + { + return EnumUtil.ParseEnum(Filter.StatusCat, SbmAssetCategory.StatusCat.NotDeleted); + } //------------------------------------------------------------------- // Item properties. @@ -46,12 +64,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets public String TypeCode { get; set; } public Sbm.AssetType AssetType { get; set; } public String Code { get; set; } - public String DescBrief { get; set; } + public String Caption { get; set; } public String Notes { get; set; } public String StatusCode { get; set; } - public SaStatus GetStatus() { return SacsSystem.GetStatusForCode(StatusCode); } } public AssetCategoryData AssetCategory { get; } = new AssetCategoryData(); + public SaStatus GetAssetCategoryStatus() { return SacsSystem.GetStatusForCode(AssetCategory.StatusCode); } //------------------------------------------------------------------- // Validation. @@ -66,7 +84,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets // AssetCategory type. if (AssetCategory.TypeCode != null) { - String controlName = "AssetCategoryType"; + String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Type); AssetCategory.AssetType = (Sbm.AssetType)Internals.AssetTypeCodes.GetTypeForCode(AssetCategory.TypeCode); responseData.SetControlValue(controlName, AssetCategory.TypeCode); if (StringUtil.IsBlank(AssetCategory.TypeCode)) @@ -78,7 +96,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets // AssetCategory Code. if (AssetCategory.Code != null) { - String controlName = "AssetCategoryCode"; + String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Code); AssetCategory.Code = AssetCategory.Code.ToUpper(); responseData.SetControlValue(controlName, AssetCategory.Code); if (StringUtil.IsBlank(AssetCategory.Code)) @@ -87,21 +105,21 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Code)]); } - // AssetCategory DescBrief. - if (AssetCategory.DescBrief != null) + // AssetCategory Caption. + if (AssetCategory.Caption != null) { - String controlName = "AssetCategoryDescription"; - responseData.SetControlValue(controlName, AssetCategory.DescBrief); - if (StringUtil.IsBlank(AssetCategory.DescBrief)) + String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Caption); + responseData.SetControlValue(controlName, AssetCategory.Caption); + if (StringUtil.IsBlank(AssetCategory.Caption)) responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); - else if (StringUtil.GetLength(AssetCategory.DescBrief) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief)) + else if (StringUtil.GetLength(AssetCategory.Caption) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief)) responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief)]); } // Notes. if (AssetCategory.Notes != null) { - String controlName = "AssetCategoryNotes"; + String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Notes); responseData.SetControlValue(controlName, AssetCategory.Notes); if (StringUtil.GetLength(AssetCategory.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes)) responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes)]); @@ -110,10 +128,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets // AssetCategory status. if (AssetCategory.StatusCode != null) { - String controlName = "AssetCategoryStatus"; + String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Status); if (StringUtil.IsBlank(AssetCategory.StatusCode)) responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); - else if (!SbmAssetCategory.ValidStatuses.Contains(AssetCategory.GetStatus())) + else if (!SbmAssetCategory.ValidStatuses.Contains(GetAssetCategoryStatus())) responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); } } diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_VehicleClass.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_VehicleClass.cs deleted file mode 100644 index 1f5317c..0000000 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Assets/Model_VehicleClass.cs +++ /dev/null @@ -1,130 +0,0 @@ -using DocumentFormat.OpenXml.Spreadsheet; -using Sarand.BusinessMgr.Net.Core.Web.App; -using Sarand.BusinessMgr.Net.Core.Web.Controllers; -using Sarand.BusinessMgr.Net.Standard.Base.App; -using Sarand.BusinessMgr.Net.Standard.Base.Bus; -using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; -using Sarand.Net.Standard.Base.App; -using Sarand.Net.Standard.Base.Bus; -using Sarand.Net.Standard.Base.Core; -using Sarand.Net.Standard.Base.Helpers; -using Sarand.Net.Standard.Base.Utils; -using System; - -namespace Sarand.BusinessMgr.Web.Portal.Models.Assets -{ - //======================================================================= - public class Model_VehicleClass : SbmModel_Portal - { - //------------------------------------------------------------------- - // Construction. - public Model_VehicleClass(SbmLocaliser localiser) : - base(localiser) - { - } - - //------------------------------------------------------------------- - // Filter properties. - public class FilterData - { - public string Search { get; set; } - public string StatusCat { get; set; } - public SbmVehicleClass.StatusCat GetStatusCat() - { - return EnumUtil.ParseEnum(StatusCat, SbmVehicleClass.StatusCat.NotDeleted); - } - } - public FilterData Filter { get; } = new FilterData(); - - //------------------------------------------------------------------- - // Item properties. - public class VehicleClassData - { - public string Exists { get; set; } - public string Id { get; set; } - public string MakeCode { get; set; } - public string Model { get; set; } - public string Derivative { get; set; } - public string DescBrief { get; set; } - public string VehicleTypeCode { get; set; } - public Sbm.VehicleType VehicleType { get; set; } = Sbm.VehicleType.Unknown; - public string VehicleCategoryCode { get; set; } - public string FuelTypeCode { get; set; } - public Sbm.VehicleFuelType FuelType { get; set; } = Sbm.VehicleFuelType.Unknown; - public string OdometerUnitsCode { get; set; } - public Sbm.VehicleOdometerUnits OdometerUnits { get; set; } = Sbm.VehicleOdometerUnits.Unknown; - public string Notes { get; set; } - public string StatusCode { get; set; } - public SaStatus GetStatus() { return SacsSystem.GetStatusForCode(StatusCode); } - } - public VehicleClassData VehicleClass { get; } = new VehicleClassData(); - - //------------------------------------------------------------------- - // Validation. - //------------------------------------------------------------------- - // VehicleClass. - public bool ValidateVehicleClassData(Sacs.Web.Components.SaController.AjaxResponse_Data responseData) - { - // Record disposable items as they are created so all can be disposed when needed. - using (DisposableCollection disposables = new DisposableCollection()) - { - - // Make. - if (VehicleClass.MakeCode != null) - { - string controlName = "VehicleClassMake"; - responseData.SetControlValue(controlName, VehicleClass.MakeCode); - if (VehicleClass.MakeCode.IsBlank()) - responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); - } - - // Model. - if (VehicleClass.Model != null) - { - string controlName = "VehicleClassModel"; - VehicleClass.Model = VehicleClass.Model.ToUpper(); - responseData.SetControlValue(controlName, VehicleClass.Model); - if (VehicleClass.Model.IsBlank()) - responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); - else if (StringUtil.GetLength(VehicleClass.Model) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Model)) - responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Model)]); - } - - // VehicleClass DescBrief. - if (VehicleClass.DescBrief != null) - { - string controlName = "VehicleClassDescription"; - responseData.SetControlValue(controlName, VehicleClass.DescBrief); - if (VehicleClass.DescBrief.IsBlank()) - responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); - else if (StringUtil.GetLength(VehicleClass.DescBrief) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_DescBrief)) - responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_DescBrief)]); - } - - // Notes. - if (VehicleClass.Notes != null) - { - string controlName = "VehicleClassNotes"; - responseData.SetControlValue(controlName, VehicleClass.Notes); - if (StringUtil.GetLength(VehicleClass.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Notes)) - responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Notes)]); - } - - // VehicleClass status. - if (VehicleClass.StatusCode != null) - { - string controlName = "VehicleClassStatus"; - if (VehicleClass.StatusCode.IsBlank()) - responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); - else if (!SbmVehicleClass.ValidStatuses.Contains(VehicleClass.GetStatus())) - responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); - } - } - - return !responseData.HasControlErrors(); - } - - //------------------------------------------------------------------- - } - //======================================================================= -} diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity-Config.cs index 6e99a16..489cc42 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity-Config.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity-Config.cs @@ -219,11 +219,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities public void PopulateListConfig(ListConfigData config) { // View properties. - CommodityViewMode viewMode = GetFilterMode(); - bool modeIsMaintain = viewMode == CommodityViewMode.Maintain; - bool modeIsSearch = viewMode == CommodityViewMode.Search; - bool modeIsStockControl = viewMode == CommodityViewMode.StockControl; - bool modeIsStockTake = viewMode == CommodityViewMode.StockTake; + ViewMode viewMode = GetFilterMode(); + bool modeIsMaintain = viewMode == ViewMode.Maintain; + bool modeIsSearch = viewMode == ViewMode.Search; + bool modeIsStockControl = viewMode == ViewMode.StockControl; + bool modeIsStockTake = viewMode == ViewMode.StockTake; Sbm.CommodityType commodityType = GetFilterCommodityType(); @@ -260,7 +260,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities config.Column.Hide.Add($"{ItemField.SalesPrice}"); // Pack qty. - if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_PackQtySale)) + if (modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_PackQtySale)) config.Column.Label.Add($"{ItemField.PackQtySale}", Localiser["label.pack.quantity"]); else config.Column.Hide.Add($"{ItemField.PackQtySale}"); @@ -288,7 +288,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities // Specification. // Weight. - if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_Weight)) + if (modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_Weight)) config.Column.Label.Add($"{ItemField.Weight}", Localiser["label.weight"]); else config.Column.Hide.Add($"{ItemField.Weight}"); @@ -297,7 +297,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities // Defaults. // Catalog Reference. - if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_CatalogRef)) + if (modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_CatalogRef)) config.Column.Label.Add($"{ItemField.CatalogRef}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_CatalogRef, Localiser["label.catalog.ref"])); else config.Column.Hide.Add($"{ItemField.CatalogRef}"); @@ -306,19 +306,19 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities // Stock. // Stock - allocated. - if ((modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAllocated)) && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_QtyAllocated)) + if ((modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAllocated)) && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_QtyAllocated)) config.Column.Label.Add($"{ItemField.QtyAllocated}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_QtyAllocated, Localiser["label.allocated"])); else config.Column.Hide.Add($"{ItemField.QtyAllocated}"); // Stock - available. - if (!modeIsStockControl && SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAvailable)) + if (!modeIsStockControl && SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAvailable)) config.Column.Label.Add($"{ItemField.StockAvailable}", Localiser["label.available"]); else config.Column.Hide.Add($"{ItemField.StockAvailable}"); // Current Level. - if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockLevelSales)) + if (modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockLevelSales)) config.Column.Label.Add($"{ItemField.CurrentLevel}", Localiser["label.current.level"]); else config.Column.Hide.Add($"{ItemField.CurrentLevel}"); diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity.cs index 37fa1b0..b8bc7fe 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Commodities/Model_Commodity.cs @@ -28,7 +28,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities { //------------------------------------------------------------------- // Definitions. - public enum CommodityViewMode + public enum ViewMode { Search, Maintain, StockControl, StockTake } @@ -49,9 +49,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities public String Search { get; set; } } public FilterData Filter { get; } = new FilterData(); - public CommodityViewMode GetFilterMode() + public ViewMode GetFilterMode() { - return EnumUtil.ParseEnum(Filter.Mode, CommodityViewMode.Search); + return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search); } public Sbm.CommodityType GetFilterCommodityType() { diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association-Config.cs index 5ee5a9a..1c8860f 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association-Config.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association-Config.cs @@ -134,9 +134,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts } public void PopulateListConfig(ListConfigData config) { - AssociationViewMode pageMode = GetFilterMode(); - bool modeIsRelationships = pageMode == AssociationViewMode.Relationships; - bool modeIsMaintain = pageMode == AssociationViewMode.Maintain; + ViewMode pageMode = GetFilterMode(); + bool modeIsRelationships = pageMode == ViewMode.Relationships; + bool modeIsMaintain = pageMode == ViewMode.Maintain; Sbm.AssociationType associationType = GetFilterAssociationType(); bool typeIsCustomer = associationType == Sbm.AssociationType.Customer; bool typeIsSupplier = associationType == Sbm.AssociationType.Supplier; @@ -177,15 +177,15 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts config.Column.Hide.Add($"{ItemField.Address}"); // Customer financials. - if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Open)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Open)) config.Column.Hide.Add($"{ItemField.TransSalesValueOpen}"); - if (!modeIsMaintain || !typeIsCustomer || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_LastSaleRaised)) + if (!modeIsMaintain || !typeIsCustomer || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_LastSaleRaised)) config.Column.Hide.Add($"{ItemField.TransLastSaleRaised}"); - if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_AnnualSalesTarget)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_AnnualSalesTarget)) config.Column.Hide.Add($"{ItemField.AnnualSalesTarget}"); - if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Cytd)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Cytd)) config.Column.Hide.Add($"{ItemField.TransSalesValueCytd}"); - if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Lcy)) + if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Lcy)) config.Column.Hide.Add($"{ItemField.TransSalesValueLcy}"); // Customer commodities. if (!modeIsMaintain || !typeIsCustomer || !CommodityMgr.CanManageCommodityCustomers()) @@ -196,7 +196,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.AllowOption(Sbm.ConfigOption.CustomerPriceSet) && PriceMgr.PriceDatabaseIsValid) config.Column.Hide.Add($"{ItemField.PriceSet}"); // Association group. - if (!modeIsMaintain || !typeIsCustomer || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Group)) + if (!modeIsMaintain || !typeIsCustomer || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Group)) config.Column.Hide.Add($"{ItemField.Group}"); // Customer codes. if (!modeIsMaintain || !typeIsCustomer || !CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.AccountManager))) @@ -331,7 +331,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts config.Type = new ItemConfigData.TypeData(associationTypes.GetCodeForType(Sbm.AssociationType.Member), Localiser.GetAssociationTypeCaption(Sbm.AssociationType.Member)); // Allow actions. - if (SessionData_Portal.GetOwnerOption_AllowOption(Sbm.OrgOption_AllowOption.UpdateAssociationCode)) + if (SessionConsole.GetOwnerOption_AllowOption(Sbm.OrgOption_AllowOption.UpdateAssociationCode)) config.Allow.UpdateCode = true; // Item Fields. diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association.cs index ed0d010..b21dcb0 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Association.cs @@ -27,7 +27,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts { //------------------------------------------------------------------- // Definitions. - public enum AssociationViewMode + public enum ViewMode { Search, Maintain, Relationships, PriceSet, } @@ -39,9 +39,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts { } - //------------------------------------------------------------------- - // Properties. - //------------------------------------------------------------------- // Filter. public class FilterData @@ -53,9 +50,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts public string Search { get; set; } } public FilterData Filter { get; } = new FilterData(); - public AssociationViewMode GetFilterMode() + public ViewMode GetFilterMode() { - return EnumUtil.ParseEnum(Filter.Mode, AssociationViewMode.Search); + return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search); } public Sbm.AssociationType GetFilterAssociationType() { diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact-Config.cs index 1108184..940b8d3 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact-Config.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact-Config.cs @@ -114,9 +114,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts public void PopulateListConfig(ListConfigData config) { - ContactViewMode viewMode = GetFilterMode(); - bool modeIsMaintain= viewMode == ContactViewMode.Maintain; - bool modeIsSearch = viewMode == ContactViewMode.Search; + ViewMode viewMode = GetFilterMode(); + bool modeIsMaintain= viewMode == ViewMode.Maintain; + bool modeIsSearch = viewMode == ViewMode.Search; Sbm.AffiliateType affiliateType = GetFilterContactType(); bool contactGroupsOnly = affiliateType == Sbm.AffiliateType.ContactGroup; diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact.cs index f57e19e..5243848 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Contacts/Model_Contact.cs @@ -27,7 +27,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts { //------------------------------------------------------------------- // Definitions. - public enum ContactViewMode + public enum ViewMode { Search, Maintain, } @@ -49,9 +49,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts public String Email { get; set; } } public FilterData Filter { get; } = new FilterData(); - public ContactViewMode GetFilterMode() + public ViewMode GetFilterMode() { - return EnumUtil.ParseEnum(Filter.Mode, ContactViewMode.Search); + return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search); } public Sbm.AffiliateType GetFilterContactType() { diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/SbmModel_Portal.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/SbmModel_Portal.cs index ef6113b..02a9341 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/SbmModel_Portal.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/SbmModel_Portal.cs @@ -106,6 +106,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Models Menu.Items.Add(referenceItem); } + //------------------------------------------------------------------- + // View reference data. + //------------------------------------------------------------------- + //------------------------------------------------------------------- // View reference data - Contacts. @@ -113,7 +117,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models /// List of Affiliate Types for filter dropdown. /// - Contact model cannot define this as contact list/dialog may be included in other views with their own model, eg. Association page. ///
- public IEnumerable GetAffiliateTypeCodesForFilterSelect() + public IEnumerable GetAffiliateTypeCodesForFilterDropdown() { List affiliateTypes = GetCodesOfType(Sbm.SystemCode.AffiliateType); if (!affiliateTypes.Any(item => item.Type == (int)Sbm.AffiliateType.AnyOrganisation)) @@ -125,7 +129,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models /// List of Association Types for filter dropdown. /// - Association model cannot define this as association list/dialog may be included in other views with their own model, eg. Commodity page. ///
- public IEnumerable GetAssociationTypeCodesForFilterSelect() + public IEnumerable GetAssociationTypeCodesForFilterDropdown() { List associationTypes = GetCodesOfType(Sbm.SystemCode.AssociationType); associationTypes.RemoveAll(item => item.Type == (short)Sbm.AssociationType.Internal); @@ -137,13 +141,72 @@ namespace Sarand.BusinessMgr.Web.Portal.Models return new SelectList(associationTypes, "Code", "Desc"); } + //------------------------------------------------------------------- + // View reference data - Commodities. + + /// + /// List of Commodity Types for filter dropdown. + /// + public IEnumerable GetCommodityTypeCodesForFilterDropdown() + { + List commodityTypes = new List(); + commodityTypes.Add(Sbm.CommodityType.Any, "", Localiser["label.any"]); + foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType)) + { + if (commodityType.Type == (int)Sbm.CommodityType.Asset && !SessionConsole.AllowOption(ConfigOption.Assets)) continue; + commodityTypes.Add(commodityType); + } + return new SelectList(commodityTypes, "Code", "Desc"); + } + + /// + /// List of Commodity Types for form dropdown. + /// + public IEnumerable GetCommodityTypeCodesForDropdown() + { + List commodityTypes = new List(); + foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType)) + { + if (commodityType.Type == (int)Sbm.CommodityType.Asset && !SessionConsole.AllowOption(ConfigOption.Assets)) continue; + commodityTypes.Add(commodityType); + } + return new SelectList(commodityTypes, "Code", "Desc"); + } + + /// + /// List of Asset Types for filter dropdown. + /// + public IEnumerable GetAssetTypeCodesForFilterDropdown() + { + List assetTypes = new List(); + assetTypes.Add(Sbm.AssetType.Any, "", Localiser["label.any"]); + foreach (TypeCodeDesc assetType in GetCodesOfType(Sbm.SystemCode.AssetType)) + { + assetTypes.Add(assetType); + } + return new SelectList(assetTypes, "Code", "Desc"); + } + + /// + /// List of Asset Types for form dropdown. + /// + public IEnumerable GetAssetTypeCodesForDropdown() + { + List assetTypes = new List(); + foreach (TypeCodeDesc assetType in GetCodesOfType(Sbm.SystemCode.AssetType)) + { + assetTypes.Add(assetType); + } + return new SelectList(assetTypes, "Code", "Desc"); + } + //------------------------------------------------------------------- // View reference data - Transactions. /// /// List of Transaction Types for filter dropdown. /// - public IEnumerable GetTransactionTypeCodesForFilterSelect() + public IEnumerable GetTransactionTypeCodesForFilterDropdown() { List transactionTypes = new List(); transactionTypes.Add(Sbm.TransactionType.Any, "", Localiser["label.any"]); @@ -171,44 +234,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Models return new SelectList(transactionTypes, "Code", "Desc"); } - //------------------------------------------------------------------- - // View reference data - Commodities. - - /// - /// List of Commodity Types for filter dropdown. - /// - public IEnumerable GetCommodityTypeCodesForFilterSelect() - { - List commodityTypes = new List(); - commodityTypes.Add(Sbm.CommodityType.Any, "", Localiser["label.any"]); - foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType)) - { - if (commodityType.Type == (int)Sbm.CommodityType.Asset && !SessionConsole.AllowOption(ConfigOption.Assets)) continue; - commodityTypes.Add(commodityType); - } - return new SelectList(commodityTypes, "Code", "Desc"); - } - - /// - /// List of Commodity Types for form dropdown. - /// - public IEnumerable GetCommodityTypeCodesForDropdown() - { - List commodityTypes = new List(); - foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType)) - { - if (commodityType.Type == (int)Sbm.CommodityType.Asset && !SessionConsole.AllowOption(ConfigOption.Assets)) continue; - commodityTypes.Add(commodityType); - } - return new SelectList(commodityTypes, "Code", "Desc"); - } - // ToDo - Organisation Option - Show Column: // case Sbm.SystemCode.OrgOption_ShowColumn: // if (code.Type == (int) Sbm.OrgOption_ShowColumn.Transaction_ContactArea) // Desc = "Transaction: " + sessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Association_ContactAreaCode, "Contact area"); - //------------------------------------------------------------------- } //======================================================================= diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Transactions/Model_Transaction-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Transactions/Model_Transaction-Config.cs index 43649fd..154ab1d 100644 --- a/SaBusinessMgrCoreWebPortal/Portal/Models/Transactions/Model_Transaction-Config.cs +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Transactions/Model_Transaction-Config.cs @@ -394,7 +394,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions // Contact Area. if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.ContactArea)) && - SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Transaction_ContactArea) && + SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Transaction_ContactArea) && (modeIsDeliveryPlanning || isSalesOrder)) { config.Column.Label.Add($"{ItemField.ContactArea}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_ContactAreaCode, Localiser["label.contact.area"])); diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_Vehicle-Config.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_Vehicle-Config.cs new file mode 100644 index 0000000..92d1b87 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_Vehicle-Config.cs @@ -0,0 +1,305 @@ +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Bus; +using System; +using System.Collections.Generic; + +namespace Sarand.BusinessMgr.Web.Portal.Models.Vehicles +{ + //======================================================================= + // Vehicle model - Configuration. + //======================================================================= + partial class Model_Vehicle + { + //------------------------------------------------------------------- + + /// Prefix for field names. + public const String FieldNamePrefix = "Vehicle"; + + /// Item fields. + public enum ItemField + { + // Vehicle properties. + Id, + // Identity. + Registration, + Vin, + // Model. + Make, + Model, + Class, + // Defaults. + CapCode, + KeyNumber, + KeyLocation, + Weight, + // Spec. + BuildOn, + PurchaseOdo, + RegisterOn, + FirstRegisterOn, + EngineNumber, + RegistrationPrevious, + LatestOdo, + LatestOdoOn, + // Associated properties. + AssetCount, + // Common. + Notes, + Status, + CreatedOn, + UpdatedOn, + Actions, + } + + /// + /// Identifier used by form fields to show control specific messages generated by model validation etc. + /// - Both page and model should use this method to consistently generate the field name. + /// + public static String GetFieldName(ItemField field) + { + return $"{FieldNamePrefix}{field}"; + } + + // List configuration. + public class ListConfigData + { + // Actions. + public class ActionData + { + public class AllowData + { + public bool? Create { get; set; } + public bool? Update { get; set; } + } + public AllowData Allow { get; } = new AllowData(); + } + public ActionData Action { get; } = new ActionData(); + // List columns. + public class ColumnData + { + // Column name prefix. + public String Prefix { get; } = Model_Vehicle.FieldNamePrefix; + // Hide column. + public HashSet Hide { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Column labels. + public Dictionary Label { get; } = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + } + public ColumnData Column { get; } = new ColumnData(); + } + public ListConfigData ListConfig { get; private set; } + + //------------------------------------------------------------------- + /// + /// Populate Vehicle list configuration data - only required on initial page construction. + /// + public void PopulateListConfig() + { + ListConfig = new ListConfigData(); + PopulateListConfig(ListConfig); + } + public void PopulateListConfig(ListConfigData config) + { + ViewMode pageMode = GetFilterMode(); + bool modeIsSearch = pageMode == ViewMode.Search; + bool modeIsMaintain = pageMode == ViewMode.Maintain; + bool userCanCreateVehicles = SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(Sbm.ItemType.Vehicle); + bool userCanUpdateVehicles = SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(Sbm.ItemType.Vehicle); + + // Actions. + + if (userCanCreateVehicles) + config.Action.Allow.Create = true; + if (userCanUpdateVehicles) + config.Action.Allow.Update = true; + + // List columns. + + if (SysId.IsValid(SysId.ToSysId(Filter.VehicleClassId))) + config.Column.Hide.Add($"{ItemField.Class}"); + + // Vehicle Assets. + if (!modeIsMaintain || !SessionConsole.AllowOption(Sbm.ConfigOption.Assets)) + config.Column.Hide.Add($"{ItemField.AssetCount}"); + + // Actions. + if (!modeIsMaintain) + config.Column.Hide.Add($"{ItemField.Actions}"); + } + + //------------------------------------------------------------------- + // Item configuration. + //------------------------------------------------------------------- + // Legacy Vehicle dialog tabs and panels. + // Tab 1 'Properties': + // Model + // Defaults + // Spec + // HPI + // Service + // Notes + // Tab 2 'Features': + // Features + //------------------------------------------------------------------- + + public class ItemConfigData + { + // Update dialog title. + public String Title { get; set; } + // Pre-select Vehicle type. + public class TypeData + { + public TypeData(string code, String desc) + { + Code = code; + Desc = desc; + } + public String Code { get; set; } + public String Desc { get; set; } + } + public TypeData Type { get; set; } + // Field name prefix. + public String Prefix { get; } = Model_Vehicle.FieldNamePrefix; + // Control flags. + public bool? ManagedByAccounts { get; set; } + public bool? LocalPricing { get; set; } + // Allowed actions. + public class AllowData + { + public bool? UpdateCode { get; set; } + } + public AllowData Allow { get; } = new AllowData(); + // Item fields. + public class FieldData + { + // Field name prefix. + public String Prefix { get; } = Model_Vehicle.FieldNamePrefix; + // Hide field. + public HashSet Hide { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Read-only field. + public HashSet Readonly { get; } = new HashSet(StringComparer.InvariantCultureIgnoreCase); + // Field labels. + public Dictionary Label { get; } = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + } + public FieldData Field { get; } = new FieldData(); + } + /// + /// Populate item configuration for existing vehicle. + /// + public void PopulateItemConfig(ItemConfigData config, SbmVehicle vehicle) + { + PopulateItemConfig(config, vehicle.GetItemId()); + } + /// + /// Populate item configuration for new or existing vehicle. + /// + public void PopulateItemConfig(ItemConfigData config, ItemId vehicleItemId) + { + // Session configuration. + bool userCanCreateVehicles = SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(Sbm.ItemType.Vehicle); + bool userCanUpdateVehicles = SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(Sbm.ItemType.Vehicle); + + // Update dialog title. + config.Title = Localiser["caption.vehicle.update"]; + + //--------------------------------------------------------------- + // Identity. + + // Registration. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.Registration}"); + + // VIN. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.Vin}"); + + //--------------------------------------------------------------- + // Model. + + // Make. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.Make}"); + + // Model. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.Model}"); + + // Class. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.Class}"); + + //--------------------------------------------------------------- + // Defaults. + + // CAP code. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.CapCode}"); + + // Key Number. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.KeyNumber}"); + + // Key Location. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.KeyLocation}"); + + // Weight. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.Weight}"); + + //--------------------------------------------------------------- + // Spec. + + // Build On. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.BuildOn}"); + + // Purchase Odomoeter. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.PurchaseOdo}"); + + // Register On. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.RegisterOn}"); + + // First Register On. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.FirstRegisterOn}"); + + // Engine Number. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.EngineNumber}"); + + // Previous Registration. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.RegistrationPrevious}"); + + // Latest Odomoeter. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.LatestOdo}"); + + // Latest Odomoeter. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.LatestOdoOn}"); + + //--------------------------------------------------------------- + // Service. + + //--------------------------------------------------------------- + // Common properties. + + // Status. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.Status}"); + + // Notes. + if (!userCanUpdateVehicles) + config.Field.Readonly.Add($"{ItemField.Notes}"); + + //--------------------------------------------------------------- + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_Vehicle.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_Vehicle.cs new file mode 100644 index 0000000..7583f17 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_Vehicle.cs @@ -0,0 +1,144 @@ +using DocumentFormat.OpenXml.Spreadsheet; +using Sarand.BusinessMgr.Net.Core.Web.App; +using Sarand.BusinessMgr.Net.Core.Web.Controllers; +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.Web.Portal.Models; +using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Helpers; +using Sarand.Net.Standard.Base.Utils; +using System; + +namespace Sarand.BusinessMgr.Web.Portal.Models.Vehicles +{ + //======================================================================= + public partial class Model_Vehicle : SbmModel_Portal + { + //------------------------------------------------------------------- + // Definitions. + public enum ViewMode + { + Search, Maintain + } + + //------------------------------------------------------------------- + // Construction. + public Model_Vehicle(SbmLocaliser localiser) : + base(localiser) + { + } + + //------------------------------------------------------------------- + // Filter properties. + public class FilterData + { + public String Mode { get; set; } + public String VehicleClassId { get; set; } + public String Search { get; set; } + public String StatusCat { get; set; } + } + public FilterData Filter { get; } = new FilterData(); + public ViewMode GetFilterMode() + { + return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search); + } + public SbmVehicle.StatusCat GetFilterStatusCat() + { + return EnumUtil.ParseEnum(Filter.StatusCat, SbmVehicle.StatusCat.NotDeleted); + } + + //------------------------------------------------------------------- + // Item properties. + public class VehicleData + { + public String Exists { get; set; } + public String Id { get; set; } + public String ClassId { get; set; } + public String Registration { get; set; } + public String Vin { get; set; } + public String CapCode { get; set; } + public String KeyNumber { get; set; } + public String KeyLocation { get; set; } + public String EngineNumber { get; set; } + public String EngineCapacity { get; set; } + public String Seats { get; set; } + public String Weight { get; set; } + public String ManufactureYear { get; set; } + public String Notes { get; set; } + public String StatusCode { get; set; } + public SaStatus GetStatus() { return SacsSystem.GetStatusForCode(StatusCode); } + } + public VehicleData Vehicle { get; } = new VehicleData(); + + //------------------------------------------------------------------- + // Validation. + //------------------------------------------------------------------- + // Vehicle. + public bool ValidateVehicleData(SbmController_Base.AjaxResponse_Data responseData) + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + + // Vehicle Class. + if (Vehicle.ClassId != null) + { + String controlName = "VehicleClass"; + if (StringUtil.IsBlank(Vehicle.ClassId)) + responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); + else if (!AssetMgr.VehicleClassExistsById(SysId.ToSysId(Vehicle.ClassId))) + responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); + } + + // Registration. + if (Vehicle.Registration != null) + { + String controlName = "VehicleRegistration"; + Vehicle.Registration = Vehicle.Registration.ToUpper(); + responseData.SetControlValue(controlName, Vehicle.Registration); + if (StringUtil.IsBlank(Vehicle.Registration)) + responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); + else if (StringUtil.GetLength(Vehicle.Registration) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_RegNumber)) + responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_RegNumber)]); + } + + // Vin. + if (Vehicle.Vin != null) + { + String controlName = "VehicleVin"; + Vehicle.Vin = Vehicle.Vin.ToUpper(); + responseData.SetControlValue(controlName, Vehicle.Vin); + if (StringUtil.GetLength(Vehicle.Vin) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_VIN)) + responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_VIN)]); + } + + // Notes. + if (Vehicle.Notes != null) + { + String controlName = "VehicleNotes"; + responseData.SetControlValue(controlName, Vehicle.Notes); + if (StringUtil.GetLength(Vehicle.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_Notes)) + responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_Notes)]); + } + + // Vehicle status. + if (Vehicle.StatusCode != null) + { + String controlName = "VehicleStatus"; + if (StringUtil.IsBlank(Vehicle.StatusCode)) + responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); + else if (!SbmVehicle.ValidStatuses.Contains(Vehicle.GetStatus())) + responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); + } + } + + return !responseData.HasControlErrors(); + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_VehicleClass.cs b/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_VehicleClass.cs new file mode 100644 index 0000000..26d6643 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Portal/Models/Vehicles/Model_VehicleClass.cs @@ -0,0 +1,135 @@ +using DocumentFormat.OpenXml.Spreadsheet; +using Sarand.BusinessMgr.Net.Core.Web.App; +using Sarand.BusinessMgr.Net.Core.Web.Controllers; +using Sarand.BusinessMgr.Net.Standard.Base.App; +using Sarand.BusinessMgr.Net.Standard.Base.Bus; +using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; +using Sarand.Net.Standard.Base.App; +using Sarand.Net.Standard.Base.Bus; +using Sarand.Net.Standard.Base.Core; +using Sarand.Net.Standard.Base.Helpers; +using Sarand.Net.Standard.Base.Utils; +using System; + +namespace Sarand.BusinessMgr.Web.Portal.Models.Vehicles +{ + //======================================================================= + public partial class Model_VehicleClass : SbmModel_Portal + { + //------------------------------------------------------------------- + // Construction. + public Model_VehicleClass(SbmLocaliser localiser) : + base(localiser) + { + } + + //------------------------------------------------------------------- + // Filter properties. + public class FilterData + { + public string VehicleType { get; set; } + public string Search { get; set; } + public string StatusCat { get; set; } + } + public FilterData Filter { get; } = new FilterData(); + public Sbm.VehicleType GetFilterVehicleType() + { + return (Sbm.VehicleType)Internals.VehicleTypeCodes.GetTypeForCode(Filter.VehicleType); + } + public SbmVehicleClass.StatusCat GetFilterStatusCat() + { + return EnumUtil.ParseEnum(Filter.StatusCat, SbmVehicleClass.StatusCat.NotDeleted); + } + + //------------------------------------------------------------------- + // Item properties. + public class VehicleClassData + { + public string Exists { get; set; } + public string Id { get; set; } + public string MakeCode { get; set; } + public string Model { get; set; } + public string Derivative { get; set; } + public string DescBrief { get; set; } + public string VehicleTypeCode { get; set; } + public Sbm.VehicleType VehicleType { get; set; } = Sbm.VehicleType.Unknown; + public string VehicleCategoryCode { get; set; } + public string FuelTypeCode { get; set; } + public Sbm.VehicleFuelType FuelType { get; set; } = Sbm.VehicleFuelType.Unknown; + public string OdometerUnitsCode { get; set; } + public Sbm.VehicleOdometerUnits OdometerUnits { get; set; } = Sbm.VehicleOdometerUnits.Unknown; + public string Notes { get; set; } + public string StatusCode { get; set; } + public SaStatus GetStatus() { return SacsSystem.GetStatusForCode(StatusCode); } + } + public VehicleClassData VehicleClass { get; } = new VehicleClassData(); + + //------------------------------------------------------------------- + // Validation. + //------------------------------------------------------------------- + // VehicleClass. + public bool ValidateVehicleClassData(Sacs.Web.Components.SaController.AjaxResponse_Data responseData) + { + // Record disposable items as they are created so all can be disposed when needed. + using (DisposableCollection disposables = new DisposableCollection()) + { + + // Make. + if (VehicleClass.MakeCode != null) + { + string controlName = "VehicleClassMake"; + responseData.SetControlValue(controlName, VehicleClass.MakeCode); + if (VehicleClass.MakeCode.IsBlank()) + responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); + } + + // Model. + if (VehicleClass.Model != null) + { + string controlName = "VehicleClassModel"; + VehicleClass.Model = VehicleClass.Model.ToUpper(); + responseData.SetControlValue(controlName, VehicleClass.Model); + if (VehicleClass.Model.IsBlank()) + responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); + else if (StringUtil.GetLength(VehicleClass.Model) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Model)) + responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Model)]); + } + + // VehicleClass DescBrief. + if (VehicleClass.DescBrief != null) + { + string controlName = "VehicleClassDescription"; + responseData.SetControlValue(controlName, VehicleClass.DescBrief); + if (VehicleClass.DescBrief.IsBlank()) + responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); + else if (StringUtil.GetLength(VehicleClass.DescBrief) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_DescBrief)) + responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_DescBrief)]); + } + + // Notes. + if (VehicleClass.Notes != null) + { + string controlName = "VehicleClassNotes"; + responseData.SetControlValue(controlName, VehicleClass.Notes); + if (StringUtil.GetLength(VehicleClass.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Notes)) + responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Notes)]); + } + + // VehicleClass status. + if (VehicleClass.StatusCode != null) + { + string controlName = "VehicleClassStatus"; + if (VehicleClass.StatusCode.IsBlank()) + responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); + else if (!SbmVehicleClass.ValidStatuses.Contains(VehicleClass.GetStatus())) + responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); + } + } + + return !responseData.HasControlErrors(); + } + + //------------------------------------------------------------------- + } + //======================================================================= +} diff --git a/SaBusinessMgrCoreWebPortal/SaBusinessMgrCoreWebPortal.csproj b/SaBusinessMgrCoreWebPortal/SaBusinessMgrCoreWebPortal.csproj index 8123112..1f566c7 100644 --- a/SaBusinessMgrCoreWebPortal/SaBusinessMgrCoreWebPortal.csproj +++ b/SaBusinessMgrCoreWebPortal/SaBusinessMgrCoreWebPortal.csproj @@ -52,7 +52,6 @@ - diff --git a/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Index.cshtml b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Index.cshtml index b07333a..4905d2c 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Index.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Index.cshtml @@ -2,207 +2,8 @@ @model Model_AssetCategory @inject SbmLocaliser Localiser @{ + /* Asset Category view. */ ViewData["Title"] = "Asset Categories"; - Model.AdditionalFiles_JS.Add("js/sbm-asset-cat.js"); } -
- - - -
- - @* Filter form - wrap header to include paging controls. *@ - @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryFilter", @class = "sbm-form", @onSubmit = "return false;" })) - { - - @* Header - Page caption, paging controls, actions. *@ -
-
-
- -
-
@Localiser["caption.asset.categories"]
-
- @* Burger menu *@ - -
-
-
- - @* Filter Panel *@ -
-
-
@Localiser["label.search"]
-
- @Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" }) -
-
-
- - } - - @* Item list *@ -
- - - - - - - - - - - - -
@Localiser["label.type"]@Localiser["label.code"]@Localiser["label.description"]@Localiser["label.status"]
-
- - @* Element templates *@ -
- - @* Filter Burger option template - ul is ignored *@ -
    -
  • XXX
  • -
- - @* AssetCategory row template - table is ignored. *@ - - - - - - - - -
-
- @* Burger menu *@ - -
-
- - @* Item Burger option template - ul is ignored *@ -
    -
  • XXX
  • -
- -
- - @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryId", @onSubmit = "return false;" })) - { - @Html.HiddenFor(model => model.AssetCategory.Id, new { @id = "", @class = "AssetCategoryId" }) - } -
-
- @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategory", @class = "sbm-form", @onSubmit = "return false;" })) - { - @Html.HiddenFor(model => model.AssetCategory.Exists, new { @id = "", @class = "AssetCategoryExists" }) - @Html.HiddenFor(model => model.AssetCategory.Id, new { @id = "", @class = "AssetCategoryId" }) - - @* Type *@ -
-
-
-
- -
-
-
-
- @Html.DropDownListFor(model => model.AssetCategory.TypeCode, Model.GetAssetTypeCodesForSelect(), Localiser["label.select"], new { @id = "ifAssetCategoryType", @class = "AssetCategoryType sbm-select" }) -
-
-
-
-
- - @* Contact Code *@ -
-
-
-
- -
-
-
-
- @Html.TextBoxFor(model => model.AssetCategory.Code, new { @id = "ifAssetCategoryCode", @class = "AssetCategoryCode sbm-input upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Code) }) -
-
-
-
-
- - @* Description *@ -
-
-
-
- -
-
-
-
- @Html.TextBoxFor(model => model.AssetCategory.DescBrief, new { @id = "ifAssetCategoryDescription", @class = "AssetCategoryDescription sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief) }) -
-
-
-
-
- - @* Status *@ -
-
-
-
- -
-
-
-
- -
-
-
-
-
- - @* Notes *@ -
-
-
-
- -
-
-
-
- @Html.TextAreaFor(model => model.AssetCategory.Notes, new { @id = "ifAssetCategoryNotes", @class = "AssetCategoryNotes sbm-textarea", @rows = 3, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes) }) -
-
-
-
-
- - } -
-
- -
- -
+ diff --git a/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryDialog.cshtml b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryDialog.cshtml new file mode 100644 index 0000000..3296fa1 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryDialog.cshtml @@ -0,0 +1,108 @@ +@* View is decoupled from Asset Category model as it may be included in other views, eg. Assets. *@ +@model SbmModel_Portal +@inject SbmLocaliser Localiser +@{ + /* Asset Category - Dialog panel */ + // Ensure view is only included once in page. + if (!Model.RegisterView("Views/Assets/AssetCategory/Panel-AssetCategoryDialog")) return; +} + +@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryId", @onSubmit = "return false;" })) +{ + @Html.Hidden("AssetCategory.Id", "", new { @id = "", @class = "AssetCategoryId" }) +} +
+
+ @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategory", @class = "sbm-form", @onSubmit = "return false;" })) + { + @Html.Hidden("AssetCategory.Exists", "", new { @id = "", @class = "AssetCategoryExists sbm-input" }) + @Html.Hidden("AssetCategory.Id", "", new { @id = "", @class = "AssetCategoryId sbm-input" }) + + @* Type *@ +
+
+
+
+ +
+
+
+
+ @Html.DropDownList("AssetCategory.TypeCode", Model.GetAssetTypeCodesForDropdown(), Localiser["label.select"], new { @id = "ifAssetCategoryType", @class = "AssetCategoryType sbm-select sbm-auto-val" }) +
+
+
+
+
+ + @* Contact Code *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("AssetCategory.Code", "", new { @id = "ifAssetCategoryCode", @class = "AssetCategoryCode sbm-input sbm-auto-val upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Code) }) +
+
+
+
+
+ + @* Caption *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBox("AssetCategory.Caption", "", new { @id = "ifAssetCategoryCaption", @class = "AssetCategoryDescription sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief) }) +
+
+
+
+
+ + @* Status *@ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ + @* Notes *@ +
+
+
+
+ +
+
+
+
+ @Html.TextArea("AssetCategory.Notes", "", new { @id = "ifAssetCategoryNotes", @class = "AssetCategoryNotes sbm-textarea sbm-auto-val", @rows = 3, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes) }) +
+
+
+
+
+ + } +
+
diff --git a/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryList.cshtml b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryList.cshtml new file mode 100644 index 0000000..5e4d64d --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryList.cshtml @@ -0,0 +1,62 @@ +@* View is decoupled from Asset Category model as it may be included in other views, eg. Assets. *@ +@model SbmModel_Portal +@inject SbmLocaliser Localiser +@{ + /* Asset Category - List panel */ + /* NB Can potentially appear more than once on a page. */ +} + +@* Item list *@ +
+ + + + + + + + + + + + + +
@Localiser["label.type"]@Localiser["label.code"]@Localiser["label.description"]@Localiser["label.notes"]@Localiser["label.status"]
+
+ +@* Element templates *@ +
+ + @* Filter Burger option template - ul is ignored *@ +
    +
  • XXX
  • +
+ + @* AssetCategory row template - table is ignored. *@ + + + + + + + + + +
+
+ @* Burger menu *@ + +
+
+ + @* Item Burger option template - ul is ignored *@ +
    +
  • XXX
  • +
+ +
diff --git a/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryMaintain.cshtml b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryMaintain.cshtml new file mode 100644 index 0000000..8212b00 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategoryMaintain.cshtml @@ -0,0 +1,61 @@ +@* View is decoupled from Asset Category model as it may be included in other views, eg. Assets. *@ +@model SbmModel_Portal +@inject SbmLocaliser Localiser +@{ + /* Asset Category - Maintain panel */ + // Ensure view is only included once in page. + if (!Model.RegisterView("Views/Assets/AssetCategory/Panel-AssetCategoryMaintain")) return; + Model.AdditionalFiles_JS.Add("js/sbm-asset-cat.js"); +} + +
+ + + +
+ + @* Filter form - wrap header to include paging controls. *@ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryFilter", @class = "sbm-form", @onSubmit = "return false;" })) + { + @Html.Hidden("Filter.Mode", Model_AssetCategory.ViewMode.Maintain, new { @id = "" }) + + @* Header - Page caption, paging controls, actions. *@ +
+
+
+ +
+
@Localiser["caption.asset.categories"]
+
+ @* Burger menu *@ + +
+
+
+ + @* Filter Panel *@ +
+
+
@Localiser["label.search"]
+
+ @Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch", @maxlength = "32" }) +
+
+
+ + } + + + +
+
+ + diff --git a/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategorySelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategorySelect.cshtml new file mode 100644 index 0000000..7a43e6b --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Assets/AssetCategory/Panel-AssetCategorySelect.cshtml @@ -0,0 +1,43 @@ +@* View is decoupled from Asset Category model as it may be included in other views, eg. Assets. *@ +@model SbmModel_Portal +@inject SbmLocaliser Localiser +@{ + /* Asset Category - Select panel */ + // Ensure view is only included once in page. + if (!Model.RegisterView("Views/Assets/AssetCategory/Panel-AssetCategorySelect")) return; + Model.AdditionalFiles_JS.Add("js/sbm-asset-cat.js"); +} + + + +
+ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmAssetCategoryFilter sbm-form", @onSubmit = "return false;" })) + { + @Html.Hidden("Filter.Mode", Model_AssetCategory.ViewMode.Search, new { @id = "" }) + + @* Filter Panel *@ +
+
+
+ @* AssetCategory type *@ +
@Localiser["label.type"]
+
+ @Html.DropDownList("Filter.AssetCategoryType", Model.GetAssetTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterAssetCategoryType sbm-select" }) +
+
+
+ @* AssetCategory filter - name etc. *@ +
@Localiser["label.search"]
+
+ @Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" }) +
+
+
+
+ } + + + +
diff --git a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml index 554ee9b..aec12e8 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationMaintain.cshtml @@ -20,7 +20,7 @@ @* Filter form - wrap header to include paging controls. *@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmAssociationFilter sbm-form", @onSubmit = "return false;" })) { - @Html.Hidden("Filter.Mode", Model_Association.AssociationViewMode.Maintain, new { @id = "" }) + @Html.Hidden("Filter.Mode", Model_Association.ViewMode.Maintain, new { @id = "" }) @* Header - Page caption, paging controls, actions. *@
@@ -48,7 +48,7 @@ @* Association Category *@
@Localiser["label.type"]
- @Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterSelect(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" }) + @Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterDropdown(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml index a21a553..40c883e 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Association/Panel-AssociationSelect.cshtml @@ -15,7 +15,7 @@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmAssociationFilter sbm-form", @onSubmit = "return false;" })) { - @Html.Hidden("Filter.Mode", Model_Association.AssociationViewMode.Search, new { @id = "" }) + @Html.Hidden("Filter.Mode", Model_Association.ViewMode.Search, new { @id = "" }) @Html.Hidden("Filter.OwnerId", "", new { @id = "", @class = "FilterOwnerId" }) @Html.Hidden("Filter.TargetId", "", new { @id = "", @class = "FilterTargetId" }) @@ -26,7 +26,7 @@ @* Association type *@
@Localiser["label.type"]
- @Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterSelect(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" }) + @Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterDropdown(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityDialog.cshtml b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityDialog.cshtml index 6d3f87c..9dbfcd5 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityDialog.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityDialog.cshtml @@ -2,7 +2,7 @@ @model SbmModel_Portal @inject SbmLocaliser Localiser @{ - /* Commodity dialog panel */ + /* Commodity - Dialog panel */ // Ensure view is only included once in page. if (!Model.RegisterView("Views/Commodity/Panel-CommodityDialog")) return; } @@ -35,7 +35,7 @@
- @Html.DropDownList("Commodity.Type", Model.GetCommodityTypeCodesForSelect(), Localiser["label.select"], new { @id = "cbCommodityType", @class = "CommodityType sbm-select" }) + @Html.DropDownList("Commodity.Type", Model.GetCommodityTypeCodesForDropdown(), Localiser["label.select"], new { @id = "cbCommodityType", @class = "CommodityType sbm-select" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityList.cshtml b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityList.cshtml index c0cc6da..2e4e880 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityList.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityList.cshtml @@ -2,7 +2,7 @@ @model SbmModel_Portal @inject SbmLocaliser Localiser @{ - /* Commodity list panel */ + /* Commodity - List panel */ /* NB Can potentially appear more than once on a page. */ } diff --git a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityMaintain.cshtml b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityMaintain.cshtml index a901584..7dd5ed5 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityMaintain.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommodityMaintain.cshtml @@ -2,7 +2,7 @@ @model SbmModel_Portal @inject SbmLocaliser Localiser @{ - /* Commodity maintain panel */ + /* Commodity - Maintain panel */ // Ensure view is only included once in page. if (!Model.RegisterView("Views/Commodity/Panel-CommodityMaintain")) return; Model.AdditionalFiles_JS.Add("js/sbm-commodity.js"); @@ -18,7 +18,7 @@ @* Filter form - wrap header to include paging controls. *@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodityFilter", @class = "sbm-form", @onSubmit = "return false;" })) { - @Html.Hidden("Filter.Mode", Model_Commodity.CommodityViewMode.Maintain, new { @id = "" }) + @Html.Hidden("Filter.Mode", Model_Commodity.ViewMode.Maintain, new { @id = "" }) @* Header - Page caption, paging controls, actions. *@
@@ -44,7 +44,7 @@ @* Commodity Category *@
@Localiser["label.type"]
- @Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" }) + @Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommoditySelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommoditySelect.cshtml index 87c1fde..ce0cb24 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommoditySelect.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Commodity/Panel-CommoditySelect.cshtml @@ -2,7 +2,7 @@ @model SbmModel_Portal @inject SbmLocaliser Localiser @{ - /* Commodity select panel */ + /* Commodity - Select panel */ // Ensure view is only included once in page. if (!Model.RegisterView("Views/Commodity/Panel-CommoditySelect")) return; Model.AdditionalFiles_JS.Add("js/sbm-commodity.js"); @@ -15,7 +15,7 @@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmCommodityFilter sbm-form", @onSubmit = "return false;" })) { - @Html.Hidden("Filter.Mode", Model_Commodity.CommodityViewMode.Search, new { @id = "" }) + @Html.Hidden("Filter.Mode", Model_Commodity.ViewMode.Search, new { @id = "" }) @* Filter Panel *@
@@ -24,7 +24,7 @@ @* Commodity type *@
@Localiser["label.type"]
- @Html.DropDownList("Filter.CommodityType", Model.GetAffiliateTypeCodesForFilterSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" }) + @Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactMaintain.cshtml b/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactMaintain.cshtml index 7bccd68..e1eb2b3 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactMaintain.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactMaintain.cshtml @@ -21,7 +21,7 @@ @* Filter form - wrap header to include paging controls. *@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmContactFilter sbm-form", @onSubmit = "return false;" })) { - @Html.Hidden("Filter.Mode", Model_Contact.ContactViewMode.Maintain, new { @id = "" }) + @Html.Hidden("Filter.Mode", Model_Contact.ViewMode.Maintain, new { @id = "" }) @* Header - Page caption, paging controls, actions. *@
@@ -47,7 +47,7 @@ @* Contact type *@
@Localiser["label.type"]
- @Html.DropDownList("Filter.ContactType", Model.GetAffiliateTypeCodesForFilterSelect(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" }) + @Html.DropDownList("Filter.ContactType", Model.GetAffiliateTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactSelect.cshtml b/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactSelect.cshtml index cd07f9f..7bf9674 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactSelect.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Contact/Panel-ContactSelect.cshtml @@ -15,7 +15,7 @@ @using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmContactFilter sbm-form", @onSubmit = "return false;" })) { - @Html.Hidden("Filter.Mode", Model_Contact.ContactViewMode.Search, new { @id = "" }) + @Html.Hidden("Filter.Mode", Model_Contact.ViewMode.Search, new { @id = "" }) @* Filter Panel *@
@@ -24,7 +24,7 @@ @* Contact type *@
@Localiser["label.type"]
- @Html.DropDownList("Filter.ContactType", Model.GetAffiliateTypeCodesForFilterSelect(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" }) + @Html.DropDownList("Filter.ContactType", Model.GetAffiliateTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" })
diff --git a/SaBusinessMgrCoreWebPortal/Views/Shared/_Layout.cshtml b/SaBusinessMgrCoreWebPortal/Views/Shared/_Layout.cshtml index 9ebcc00..8b8d285 100644 --- a/SaBusinessMgrCoreWebPortal/Views/Shared/_Layout.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/Shared/_Layout.cshtml @@ -45,6 +45,7 @@ integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" /> + diff --git a/SaBusinessMgrCoreWebPortal/Views/Vehicles/Vehicle/Index.cshtml b/SaBusinessMgrCoreWebPortal/Views/Vehicles/Vehicle/Index.cshtml new file mode 100644 index 0000000..4d87466 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/Views/Vehicles/Vehicle/Index.cshtml @@ -0,0 +1,215 @@ +@* Assets - Asset *@ +@model Model_Asset +@inject SbmLocaliser Localiser +@{ + ViewData["Title"] = "Assets"; + Model.AdditionalFiles_JS.Add("js/sbm-asset.js"); +} + +
+ + + +
+ + @* Filter form - wrap header to include paging controls. *@ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetFilter", @class = "sbm-form", @onSubmit = "return false;" })) + { + +
+
+
+ +
+
@Localiser["label.assets"]
+
+ @* Burger menu *@ + +
+
+
+ + @* Filter Panel *@ +
+
+
@Localiser["label.search"]
+
+ @Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" }) +
+
+
+ + } + +
+ + + + + + + + + + + + +
@Localiser["label.category"]@Localiser["label.serial"]@Localiser["label.description"]@Localiser["label.status"]
+
+ + @* Element templates *@ +
+ @* Filter Burger option template - ul is ignored *@ +
    +
  • XXX
  • +
+ @* Asset row template - table is ignored. *@ + + + + + + + + +
+
+ @* Burger menu *@ + +
+
+ @* Item Burger option template - ul is ignored *@ +
    +
  • XXX
  • +
+
+ + @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetId", @onSubmit = "return false;" })) + { + @Html.HiddenFor(model => model.Asset.Id, new { @id = "", @class = "AssetId" }) + } + @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCategories", @onSubmit = "return false;" })) + { + } +
+
+ @using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAsset", @class = "sbm-form", @onSubmit = "return false;" })) + { + @Html.HiddenFor(model => model.Asset.Exists, new { @id = "", @class = "AssetExists" }) + @Html.HiddenFor(model => model.Asset.Id, new { @id = "", @class = "AssetId" }) + + @* Type *@ +
+
+
+
+ +
+
+
+
+
+ @Html.HiddenFor(model => model.Asset.CategoryId, new { @id = "", @class = "AssetCategoryId" }) + +
+
+
+
+
+
+
+
+
+ + @* Serial Number*@ +
+
+
+
+ +
+
+
+
+ @Html.TextBoxFor(model => model.Asset.SerialNumber, new { @id = "ifAssetSerialNumber", @class = "AssetSerialNumber sbm-input upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAsset_SerialNumber) }) +
+
+
+
+
+ + @* Description *@ +
+
+
+
+ +
+
+
+
+ @Html.TextBoxFor(model => model.Asset.DescBrief, new { @id = "ifAssetDescription", @class = "AssetDescription sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAsset_DescBrief) }) +
+
+
+
+
+ + @* Status *@ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ + @* Notes *@ +
+
+
+
+ +
+
+
+
+ @Html.TextAreaFor(model => model.Asset.Notes, new { @id = "ifAssetNotes", @class = "AssetNotes sbm-textarea", @rows = 3, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAsset_Notes) }) +
+
+
+
+
+ + } +
+
+ + @* Select Item dialog and script *@ + + +
+ +
diff --git a/SaBusinessMgrCoreWebPortal/Views/Assets/VehicleClass/Index.cshtml b/SaBusinessMgrCoreWebPortal/Views/Vehicles/VehicleClass/Index.cshtml similarity index 100% rename from SaBusinessMgrCoreWebPortal/Views/Assets/VehicleClass/Index.cshtml rename to SaBusinessMgrCoreWebPortal/Views/Vehicles/VehicleClass/Index.cshtml diff --git a/SaBusinessMgrCoreWebPortal/Views/_ViewImports.cshtml b/SaBusinessMgrCoreWebPortal/Views/_ViewImports.cshtml index 70853ed..9e8daf9 100644 --- a/SaBusinessMgrCoreWebPortal/Views/_ViewImports.cshtml +++ b/SaBusinessMgrCoreWebPortal/Views/_ViewImports.cshtml @@ -4,6 +4,7 @@ @using Sarand.BusinessMgr.Web.Portal.Models.Contacts @using Sarand.BusinessMgr.Web.Portal.Models.Commodities @using Sarand.BusinessMgr.Web.Portal.Models.Assets +@using Sarand.BusinessMgr.Web.Portal.Models.Vehicles @using Sarand.BusinessMgr.Web.Portal.Models.Codes @using Sarand.Net.Standard.Base.CodeTypes @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-base.css b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-base.css index 759ec6e..a14cd4b 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-base.css +++ b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-base.css @@ -2,25 +2,6 @@ BusMgr Portal - Base stylesheet. */ -:root -{ - --color-OldGold: #d4af37; - --color-MintGreen: #98fb98; - --color-LimeGreen: #32cd32; - --color-KellyGreen: #4cbb17; - --color-OliveGreen: #808000; - --color-ForestGreen: #228b22; - --color-CornflowerBlue: #6495ed; - --color-RoyalBlue: #4169e1; - --color-NavyBlue: #000080; - --color-DarkBlue: #00008B; - --color-Indigo: #4b0082; - --color-Iris: #5d3fd3; - --color-Burgundy: #800020; - --color-BrightPurple: #bf40bf; - --color-DarkPink: #aa336a; -} - body { margin: 0; diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-cols.css b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-cols.css new file mode 100644 index 0000000..3198154 --- /dev/null +++ b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-cols.css @@ -0,0 +1,96 @@ +/* + BusMgr Portal - Colours stylesheet. +*/ + +:root +{ + --color-primary: #4b0082; + --color-light: #9b71b9; + --color-pale: #ebe2f1; + --color-OldGold: #d4af37; + --color-MintGreen: #98fb98; + --color-LimeGreen: #32cd32; + --color-KellyGreen: #4cbb17; + --color-OliveGreen: #808000; + --color-ForestGreen: #228b22; + --color-CornflowerBlue: #6495ed; + --color-RoyalBlue: #4169e1; + --color-NavyBlue: #000080; + --color-DarkBlue: #00008B; + --color-Indigo: #4b0082; + --color-Iris: #5d3fd3; + --color-Burgundy: #800020; + --color-BrightPurple: #bf40bf; + --color-DarkPink: #aa336a; +} + +/* Data panel */ + +:root +{ + --color-panel-data: var(--color-OliveGreen); +} + +.Contacts .sbm-panel-data +{ + --color-panel-data: var(--color-ForestGreen); +} + +.Associations .sbm-panel-data +{ + --color-panel-data: var(--color-Iris); +} + +.Commodities .sbm-panel-data +{ + --color-panel-data: var(--color-Burgundy); +} + +.AssetCategories .sbm-panel-data, .Assets .sbm-panel-data +{ + --color-panel-data: var(--color-BrightPurple); +} + +.VehicleClasses .sbm-panel-data, .Vehicles .sbm-panel-data +{ + --color-panel-data: var(--color-Iris); +} + +/* Dialogs */ + +:root +{ + --color-dialog: var(--color-OldGold); +} + +.ui-dialog.sbm-dark-blue +{ + --color-dialog: var(--color-DarkBlue); +} + +.ui-dialog.sbm-Contact +{ + --color-dialog: var(--color-ForestGreen); +} + +.ui-dialog.sbm-Association +{ + --color-dialog: var(--color-Iris); +} + +.ui-dialog.sbm-Commodity +{ + --color-dialog: var(--color-Burgundy); +} + +.ui-dialog.sbm-AssetCategory, .ui-dialog.sbm-Asset +{ + --color-dialog: var(--color-BrightPurple); +} + +.ui-dialog.sbm-VehicleClass, .ui-dialog.sbm-Vehicle +{ + --color-dialog: var(--color-Iris); +} + +/* The End */ diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-data.css b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-data.css index 1bfe5d0..837105f 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-data.css +++ b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-data.css @@ -4,26 +4,6 @@ /* Data panel */ -:root -{ - --color-panel-data: var(--color-OliveGreen); -} - -.Contacts .sbm-panel-data -{ - --color-panel-data: var(--color-ForestGreen); -} - -.Associations .sbm-panel-data -{ - --color-panel-data: var(--color-Iris); -} - -.Commodities .sbm-panel-data -{ - --color-panel-data: var(--color-Burgundy); -} - .sbm-panel-data { margin: 0 auto; diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-main.css b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-main.css index 1a272fd..fb7a111 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-main.css +++ b/SaBusinessMgrCoreWebPortal/wwwroot/css/sbm-main.css @@ -2,17 +2,6 @@ BusMgr Portal - Main stylesheet. */ -/* Global variables */ - -:root -{ - /* Colour analysis: https://www.colorhexa.com/ */ - /* #4b0082 - Indigo. Ref. https://www.crispedge.com/color/4b0082 */ - --color-primary: #4b0082; - --color-light: #9b71b9; - --color-pale: #ebe2f1; -} - /* Document */ html @@ -332,31 +321,6 @@ a:focus /* Dialogs */ -:root -{ - --color-dialog: var(--color-OldGold); -} - -.ui-dialog.sbm-dark-blue -{ - --color-dialog: var(--color-DarkBlue); -} - -.ui-dialog.sbm-Contact -{ - --color-dialog: var(--color-ForestGreen); -} - -.ui-dialog.sbm-Association -{ - --color-dialog: var(--color-Iris); -} - -.ui-dialog.sbm-Commodity -{ - --color-dialog: var(--color-Burgundy); -} - .sbm-dialog { display: none; diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset-cat.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset-cat.js index 46a14c1..dc2fcb1 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset-cat.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset-cat.js @@ -6,99 +6,125 @@ (function (win, doc, undef) { "use strict"; - let ac = sbm.AssetCat = { data: {}, ajax: {} }; - let $pnl = ac.$pnl = {}, $frm = ac.$frm = {}, $dlg = ac.$dlg = {}; + let ac = sbm.AssetCats = { env: {} }; //-------------------------------------------------------------- - ac.refreshResults = function (delay) + ac.refreshConfig = function (env, delay) + { + env.ajax.refreshConfig = env.ajax.refreshConfig || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/Config', formSel: env.$frm.filter, callbackFn: function (response) { ac.doRefreshConfig(env, response); } }; + sbm.doAjaxRequest(env.ajax.refreshConfig, delay || 50); + } + ac.doRefreshConfig = function (env, response) + { + //sbm.debug('doRefreshConfig', env, response); + if (!response.success) return; + // Config. + env.mode = response.mode; + env.config = response.config; + env.configItemNew = response.configItemNew; + env.data.assetTypes = response.assetTypes; + env.data.statuses = response.statuses; + env.data.statusesCreate = response.statusesCreate; + env.data.statusCodeDefault = response.statusCodeDefault; + } + + //-------------------------------------------------------------- + ac.refreshResults = function (env, delay) { if (!ac.awaitingRefreshResponse) { - $pnl.bgr.invisible(); - $pnl.table.find('tbody tr').remove(); - $pnl.msgs.hide().empty().append($('
' + sbm.msg.dataQuerying + '
')).fadeIn(200); + env.$pnl.bgr.invisible(); + env.$pnl.table.find('tbody tr').remove(); + env.$pnl.msgs.hide().empty().append($('
' + sbm.msg.dataQuerying + '
')).fadeIn(200); } - ac.ajax.assetCategories = ac.ajax.assetCategories || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/GetAssetCategories', formId: $frm.filter.prop('id'), callbackFn: ac.handleAssetCategories }; - sbm.doAjaxRequest(ac.ajax.assetCategories, delay || 50); + env.ajax.assetCategories = env.ajax.assetCategories || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/GetAssetCategories', formSel: env.$frm.filter, callbackFn: function (response) { ac.doRefreshResults(env, response); } }; + sbm.doAjaxRequest(env.ajax.assetCategories, delay || 50); ac.awaitingRefreshResponse = true; } - ac.handleAssetCategories = function (response) + ac.doRefreshResults = function (env, response) { - //sbm.debug('handleAssetCategories', response); + //sbm.debug('doRefreshResults', response); delete ac.awaitingRefreshResponse; - let $table = $('table', $pnl.table).find('tbody tr').remove().end(); - $pnl.msgs.hide().empty(); - sbm.refreshPaging(response, '#frmAssetCategoryFilter', ac.refreshResults); + env.$pnl.msgs.hide().empty(); + let $table = $('table', env.$pnl.table).find('tbody tr').remove().end(); + sbm.refreshPaging(response, env.$frm.filter, function () { ac.refreshResults(env); }); if (!response.success) return; - - // Reference data. - if (response.statuses) sbm.data.statuses = response.statuses; - if (response.statusesCreate) sbm.data.statusesCreate = response.statusesCreate; - if (response.statusCodeDefault) sbm.data.statusCodeDefault = response.statusCodeDefault; + ac.doRefreshConfig(env, response); // Menu. - $pnl.bgr.invisible(); - $pnl.mnu.empty(); - $pnl.mnu.append(ac.getFilterMenuOption(sbm.lbl.refresh, function () { ac.refreshResults(); }, 'sbm-refresh')); - $pnl.mnu.append(ac.getFilterMenuOption(sbm.lbl.create, function () { ac.createItem(); }, 'sbm-add')); - $pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', $pnl.mnu).length); + if (env.$pnl.bgr.length) + { + env.$pnl.bgr.invisible(); + env.$pnl.mnu.empty(); + env.$pnl.mnu.append(ac.getFilterMenuOption(env, sbm.lbl.refresh, function () { ac.refreshResults(env); }, 'sbm-refresh')); + env.$pnl.mnu.append(ac.getFilterMenuOption(env, sbm.lbl.create, function () { ac.createItem(env, env.configItemNew); }, 'sbm-add')); + env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length); + } // Items. var items = response.assetCategories || []; if (!items.length) - return $pnl.msgs.append($('
' + sbm.msg.dataNoneFound + '
')).fadeIn(500); - for (let itemIdx = 0; itemIdx < items.length; itemIdx++) - $table.append(ac.populateItem(ac.getItemTemplate(), items[itemIdx])); + return env.$pnl.msgs.append($('
' + sbm.msg.dataNoneFound + '
')).fadeIn(500); + for (const item of items) + $table.append(env, ac.populateItem(env, ac.getItemTemplate(env), item)); } - ac.populateItem = function ($item, item) + ac.populateItem = function (env, $item, item) { + //sbm.debug('populateItem', env, $item, item) if (!item) return $item; - $pnl.msgs.hide().empty(); $item.prop('id', ac.getItemId(item)); - $('.AssetCategoryType', $item).text(item.typeDesc); - $('.AssetCategoryCode', $item).text(item.code); - $('.AssetCategoryDescription', $item).text(item.descBrief); - $('.AssetCategoryStatusDesc', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase()); - // Actions. - let fnUpd = function () { ac.updateItem($item, item) }; - var $bgr = $('.sbm-burger', $item).invisible(); - let $mnu = $('ul.sbm-dropdown-menu', $bgr).empty(); - if (!item.deleted) + let cfg = env.config; + 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) { - $mnu.append(ac.getItemMenuOption(sbm.lbl.edit, fnUpd, 'sbm-edit')); - $('.AssetCategoryCode', $item).off('click').on('click', fnUpd).addClass('sbm-action-text'); - $item.off('dblclick').on('dblclick', fnUpd); + // Actions. + let fnUpd = function () { ac.updateItem(env, item.id) }; + var $bgr = $('.sbm-burger', $item).invisible(); + let $mnu = $('ul.sbm-dropdown-menu', $bgr).empty(); + if (!item.deleted) + { + $mnu.append(ac.getItemMenuOption(env, sbm.lbl.edit, fnUpd, 'sbm-edit')); + $('.' + prefix + 'Code', $item).off('click').on('click', fnUpd).addClass('sbm-action-text'); + $item.off('dblclick').on('dblclick', fnUpd); + } + $bgr.toggleVisibility(!!$('.sbm-dropdown-item', $mnu).length); + } + else + { + $item.off('click').on('click', function () { ac.selectItemRow(env, $item, item); }); + $item.off('dblclick').on('dblclick', function () { ac.selectItem(env); }); } - $bgr.toggleVisibility(!!$('.sbm-dropdown-item', $mnu).length); return $item; } ac.getItemId = function (item) { - return 'Itm_' + (item || {}).id; + return 'Act_' + (item || {}).id; } //-------------------------------------------------------------- - ac.getFilterDropdownTemplate = function () + ac.getFilterDropdownTemplate = function (env) { - return $('.sbm-dropdown-menu.AssetCategoryFilter li.sbm-dropdown-item', $pnl.tmpls).clone(); + return $('.sbm-dropdown-menu.AssetCategoryFilter li.sbm-dropdown-item', env.$pnl.tmpls).clone(); } - ac.getItemTemplate = function () + ac.getItemTemplate = function (env) { - return $('table tr.sbm-row-item.AssetCategory', $pnl.tmpls).clone(); + return $('table tr.sbm-row-item.AssetCategory', env.$pnl.tmpls).clone(); } - ac.getItemDropdownTemplate = function () + ac.getItemDropdownTemplate = function (env) { - return $('.sbm-dropdown-menu.AssetCategory li.sbm-dropdown-item', $pnl.tmpls).clone(); + return $('.sbm-dropdown-menu.AssetCategory li.sbm-dropdown-item', env.$pnl.tmpls).clone(); } //-------------------------------------------------------------- - ac.getFilterMenuOption = function (lbl, fn, cls) + ac.getFilterMenuOption = function (env, lbl, fn, cls) { - return ac.getMenuOption(ac.getFilterDropdownTemplate(), lbl, fn, cls); + return ac.getMenuOption(ac.getFilterDropdownTemplate(env), lbl, fn, cls); } - ac.getItemMenuOption = function (lbl, fn, cls) + ac.getItemMenuOption = function (env, lbl, fn, cls) { - return ac.getMenuOption(ac.getItemDropdownTemplate(), lbl, fn, cls); + return ac.getMenuOption(ac.getItemDropdownTemplate(env), lbl, fn, cls); } ac.getMenuOption = function ($opt, lbl, fn, cls) { @@ -106,101 +132,169 @@ } //-------------------------------------------------------------- - ac.createItem = function () + ac.createItem = function (env, cfg) { - ac.clearItem(); - sbm.populateSelectCodeDesc('#cbAssetCategoryStatus', sbm.data.statusesCreate); - $('#cbAssetCategoryStatus').val(sbm.data.statusCodeDefault).prop('readonly', false); - $dlg.item.dialog('option', 'title', sbm.dlg.title.createItem); - ac.openAssetCategoryDlg(); + sbm.debug('createItem', env, cfg); + ac.clearItem(env, cfg); + let $frm = env.$frm.item; + sbm.populateSelectCodeDesc('#cbAssetCategoryStatus', env.data.statusesCreate); + $('#cbAssetCategoryStatus').val(env.data.statusCodeDefault).prop('readonly', false); + ac.openItemDlg(env, cfg, sbm.dlg.title.createItem); } - ac.openAssetCategoryDlg = function () + ac.clearItem = function (env, cfg) { - sbm.openDialog($dlg.item, 600, 600); + sbm.clearItemForm(env.$frm.item); + sbm.populateSelectCodeDesc('#cbAssetCategoryStatus', env.data.statuses); } - ac.clearItem = function () + ac.openItemDlg = function (env, cfg, title) { - let frm = $frm.item; - $('.AssetCategoryExists,.AssetCategoryId,input[type="text"],textarea,select', frm).val(''); - sbm.populateSelectCodeDesc('#cbAssetCategoryStatus', sbm.data.statuses); - $('.AssetCategoryType,.AssetCategoryStatus', frm).prop('disabled', false); - sbm.clearControlErrors(); + let $dlg = env.$dlg.item; + let $frm = env.$frm.item; + sbm.configureItemControls(cfg, $frm); + var btns = {}; + btns[sbm.lbl.ok] = function () { ac.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, 600, 600); } //-------------------------------------------------------------- - ac.updateItem = function ($item, item) + ac.updateItem = function (env, id) { - ac.clearItem(); - $('.AssetCategoryId', $frm.itemId).val(item.id); - sbm.ajax.updateItem = sbm.ajax.updateItem || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/GetItem', formId: $frm.itemId.prop('id'), callbackFn: ac.onUpdateItem }; - sbm.doAjaxRequest(sbm.ajax.updateItem, 50); + let $frm = env.$frm.itemId; + $('.AssetCategoryId', $frm).val(id); + env.ajax.updateItem = env.ajax.updateItem || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/GetItem', formSel: $frm, callbackFn: function (response) { ac.onUpdateItem(env, response); } }; + sbm.doAjaxRequest(env.ajax.updateItem, 50); } - ac.onUpdateItem = function (response) + ac.onUpdateItem = function (env, response) { //sbm.debug('onUpdateItem', response); - let frm = $frm.item; - ac.clearItem(); if (!response.success) return; + let cfg = response.config || {}; + ac.clearItem(env, cfg); let item = response.assetCategory; - $('.AssetCategoryExists', frm).val(1); - $('.AssetCategoryId', frm).val(item.id); - $('.AssetCategoryType', frm).val(item.typeCode).prop('disabled', true); - $('.AssetCategoryCode', frm).val(item.code); - $('.AssetCategoryDescription', frm).val(item.descBrief); - $('.AssetCategoryNotes', frm).val(item.notes); - $('.AssetCategoryStatus', frm).val(item.statusCode).prop('disabled', true); - sbm.clearControlErrors(); - $dlg.item.dialog('option', 'title', sbm.dlg.title.updateItem); - ac.openAssetCategoryDlg(); + let $frm = env.$frm.item; + sbm.populateFormValues(cfg, $frm, item.field.value); + let $ctrls = $('.sbm-input,.sbm-textarea,.sbm-select', $frm); + $ctrls.filter('.AssetCategoryId').val(item.id); + $ctrls.filter('.AssetCategoryExists').val(1); + sbm.selectOrAdd($ctrls.filter('.AssetCategoryType'), item.typeCode, item.typeDesc); + sbm.selectOrAdd($ctrls.filter('.AssetCategoryStatus'), item.statusCode, item.field.value.Status); + ac.openItemDlg(env, cfg, sbm.dlg.title.updateItem); } //-------------------------------------------------------------- - ac.storeItem = function () + ac.storeItem = function (env) { - sbm.ajax.storeItem = sbm.ajax.storeItem || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/StoreItem', formId: 'frmAssetCategory', callbackFn: ac.onStoreItem }; - sbm.doAjaxRequest(sbm.ajax.storeItem, 50); + env.ajax.storeItem = env.ajax.storeItem || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { ac.onStoreItem(env, response); } }; + sbm.doAjaxRequest(env.ajax.storeItem, 50); } - ac.onStoreItem = function (response) + ac.onStoreItem = function (env, response) { //sbm.debug('onStoreItem', response); sbm.refreshControlValues(response.controlValues); if (!response.success) return; - $dlg.item.dialog('close'); - + env.$dlg.item.dialog('close'); var item = response.assetCategory; - var $item = $('#' + ac.getItemId(item), $pnl.table); - if (!$item.length) + if (env.prmEdit) { - $item = ac.getItemTemplate(); - $('table tbody', $pnl.table).prepend($item).show(); + ac.onItemEdited(env, item); } - ac.populateItem($item, item); + else if (env.$pnl.table.length) + { + env.$pnl.msgs.hide().empty(); + var $item = $('#' + ac.getItemId(item), env.$pnl.table); + if (!$item.length) + { + $item = ac.getItemTemplate(); + $('table tbody', env.$pnl.table).prepend($item).show(); + } + } + ac.populateItem(env, $item, item); + } + + //-------------------------------------------------------------- + /* Params: type, search, fnSuccess. */ + sbm.fn.selectAssetCategory = function (prm) + { + //sbm.debug('selectAssetCategory', prm); + let env = ac.env.select; + env.prmSelect = prm; + env.$frm.filter.find('.FilterAssetCategoryType').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 () { ac.refreshResults(env); }, 250); + } + ac.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; + } + ac.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.editAssetCategory = function (prm) + { + //sbm.debug('editAssetCategory', prm); + let env = ac.env.select; + env.prmEdit = prm; + sbm.debug(env, prm); + ac.updateItem(env, prm.id); + } + ac.onItemEdited = function (env, item) + { + //sbm.debug('ac.onItemEdited', env, item); + env.prmEdit.fnSuccess(item); + delete env.prmEdit; + } + + //-------------------------------------------------------------- + ac.initEnv = function ($pnlItems) + { + let env = { data: {}, ajax: {}, $pnl: {}, $frm: {}, $ctrl: {}, $dlg: {} }; + + env.$pnl.items = $($pnlItems); + env.$pnl.header = env.$pnl.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 = env.$pnl.items.find('.sbm-panel-item-table'); + env.$pnl.msgs = env.$pnl.table.find('.sbm-panel-messages'); + env.$pnl.tmpls = env.$pnl.items.find('.sbm-panel-item-template'); + + env.$frm.filter = $('#frmAssetCategoryFilter').on('input', '.FilterSearch', function () { ac.refreshResults(250); }); + + env.$frm.itemId = $('#frmAssetCategoryId'); + var opt = sbm.dlgOpts(); + opt.dialogClass += " sbm-AssetCategory"; + env.$dlg.item = $('#dlgAssetCategory').dialog(opt); + env.$frm.item = $('#frmAssetCategory').on('input', '.sbm-input, .sbm-textarea', function () { sbm.clearControlError(this); }).on('change', '.sbm-select', function () { sbm.clearControlError(this); }); + + var opt = sbm.dlgOpts(); + opt.dialogClass += " sbm-AssetCategory"; + opt.buttons[sbm.lbl.ok] = function () { ac.selectItem(env); }; + opt.buttons[sbm.lbl.cancel] = function () { delete env.prmSelect; $(this).dialog('close'); }; + env.$dlg.select = $('#dlgAssetCategorySelect').dialog(opt); + + return env; } //-------------------------------------------------------------- $(function () { - $pnl.items = $('.sbm-panel.AssetCategories'); - $pnl.header = $('.sbm-panel-header', $pnl.items); - $pnl.bgr = $('.sbm-burger', $pnl.header); - $pnl.mnu = $('ul.sbm-dropdown-menu', $pnl.bgr); - $pnl.filter = $('.sbm-panel-filter', $pnl.items); - $pnl.table = $('.sbm-panel-item-table', $pnl.items); - $pnl.msgs = $('.sbm-panel-messages', $pnl.items); - $pnl.tmpls = $('.sbm-panel-item-template', $pnl.items); - - $frm.filter = $('#frmAssetCategoryFilter'); - $('.FilterSearch', $frm.filter).on('input', function () { ac.refreshResults(250); }); - - $frm.itemId = $('#frmAssetCategoryId'); - var opt = sbm.dlgOpts(); - opt.buttons[sbm.lbl.save] = function () { ac.storeItem(); }; - opt.buttons[sbm.lbl.cancel] = function () { $(this).dialog('close'); }; - $dlg.item = $('#dlgAssetCategory').dialog(opt); - $frm.item = $('#frmAssetCategory'); - $($frm.item).on('input', '.sbm-input, .sbm-textarea', function () { sbm.clearControlError(this); }).on('change', '.sbm-select', function () { sbm.clearControlError(this); }); - - setTimeout(ac.refreshResults, 250); + ac.env.maint = ac.initEnv('.sbm-panel.AssetCategories'); + if (ac.env.maint.$pnl.items.length) setTimeout(function () { ac.refreshResults(ac.env.maint); }, 250); + ac.env.select = ac.initEnv('#dlgAssetCategorySelect'); + if (ac.env.select.$pnl.items.length) setTimeout(function () { ac.refreshConfig(ac.env.select); }, 250); }); //-------------------------------------------------------------- diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset.js index 8612b28..aa893df 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-asset.js @@ -214,6 +214,7 @@ $frm.itemId = $('#frmAssetId'); $frm.categories = $('#frmCategories'); var opt = sbm.dlgOpts(); + opt.dialogClass += " sbm-Asset"; opt.buttons[sbm.lbl.save] = function () { ac.storeItem(); }; opt.buttons[sbm.lbl.cancel] = function () { $(this).dialog('close'); }; $dlg.item = $('#dlgAsset').dialog(opt); diff --git a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-commodity.js b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-commodity.js index 3ff4437..cdd4d7b 100644 --- a/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-commodity.js +++ b/SaBusinessMgrCoreWebPortal/wwwroot/js/sbm-commodity.js @@ -20,7 +20,7 @@ // Config. env.mode = response.mode; env.config = response.config; - env.configCmd = response.configCmd; + env.configItemNew = response.configItemNew; env.data.commodityTypes = response.commodityTypes; env.data.statuses = response.statuses; env.data.defaultStatusCode = response.defaultStatusCode; @@ -55,7 +55,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')); - env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.configCmd); }, 'sbm-add')); + env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.configItemNew); }, 'sbm-add')); env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length); } @@ -63,8 +63,8 @@ var items = response.commodities || []; 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)); } co.populateItem = function (env, $item, item) { @@ -72,10 +72,10 @@ $item.prop('id', co.getItemId(item)); let cfg = env.config; 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) { - let prefix = cfg.column.prefix; - $('.' + prefix + 'Status', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase()); // Actions. var $bgr = $('.sbm-burger', $item).hide(); let $mnu = $('ul.sbm-dropdown-menu', $bgr).empty(); @@ -182,9 +182,7 @@ //-------------------------------------------------------------- co.storeItem = function (env) { - env.ajax.storeItem = env.ajax.storeItem || { - url: sbm.url.base + 'Commodity/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { co.onStoreItem(env, response); } - }; + env.ajax.storeItem = env.ajax.storeItem || {url: sbm.url.base + 'Commodity/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { co.onStoreItem(env, response); }}; sbm.doAjaxRequest(env.ajax.storeItem, 50); } co.onStoreItem = function (env, response) @@ -256,7 +254,7 @@ } //-------------------------------------------------------------- - co.initCommodityEnv = function ($pnlItems) + co.initEnv = function ($pnlItems) { let env = { data: {}, ajax: {}, $pnl: {}, $frm: {}, $ctrl: {}, $dlg: {} }; @@ -288,12 +286,13 @@ //-------------------------------------------------------------- $(function () { - co.env.maint = co.initCommodityEnv('.sbm-panel.Commodities'); + co.env.maint = co.initEnv('.sbm-panel.Commodities'); if (co.env.maint.$pnl.items.length) setTimeout(function () { co.refreshResults(co.env.maint); }, 250); - co.env.select = co.initCommodityEnv('#dlgCommoditySelect'); + co.env.select = co.initEnv('#dlgCommoditySelect'); 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