Session data.

This commit is contained in:
Andy Howard
2025-01-22 08:01:51 +00:00
parent 61ecd59794
commit f375e0d175
121 changed files with 3743 additions and 2126 deletions
@@ -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)
@@ -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);
}
//-------------------------------------------------------------------
}
//=======================================================================
+10 -29
View File
@@ -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)
/// <summary>
/// Protected construction - for JSON deserialisation and non-session data (eg. prior to logon).
/// <para>- Session index persistent to record sequence in which Session Data objects created.</para>
/// <para>- Session index should be zero for non-session data, eg. background tasks.</para>
/// </summary>
protected SbmSessionData_Web(long sessionIdx, SbmSessionContext sessionContext) :
base(sessionIdx, sessionContext)
{
}
// Protected construction.
/// <summary>
/// Session Data constructor - prior to storage against session.
/// </summary>
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; }
//-------------------------------------------------------------------
}
//=======================================================================
+1 -1
View File
@@ -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.
@@ -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<SysIdString> supervisedOwners)
{
base.SetUserData(securityItemUser, affiliateUser, supervisedOwners);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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<TypeCodeDesc> 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.
@@ -271,44 +271,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Models
return new SelectList(codes, "Code", "Desc");
}
/// <summary>List of Address Types for dropdown.</summary>
public IEnumerable<SelectListItem> GetAddressTypeCodesForSelect()
{
return new SelectList(GetCodesOfType(Sbm.SystemCode.AddressType), "Code", "Desc");
}
/// <summary>List of Affiliate Types for dropdown.</summary>
public IEnumerable<SelectListItem> GetAffiliateTypeCodesForSelect()
{
return new SelectList(GetCodesOfType(Sbm.SystemCode.AffiliateType), "Code", "Desc");
}
/// <summary>List of Association Types for dropdown.</summary>
public IEnumerable<SelectListItem> GetAssociationTypeCodesForSelect()
{
List<TypeCodeDesc> associationTypes = GetCodesOfType(Sbm.SystemCode.AssociationType);
associationTypes.RemoveAll(item => item.Type == (short)Sbm.AssociationType.Internal);
foreach (Sbm.AssociationType associationType in EnumUtil.GetValues<Sbm.AssociationType>())
{
if (!SessionConsole.AllowAssociationType(associationType))
associationTypes.RemoveAll(item => item.Type == (short)associationType);
}
return new SelectList(associationTypes, "Code", "Desc");
}
/// <summary>List of Commodity Types for dropdown.</summary>
public IEnumerable<SelectListItem> GetCommodityTypeCodesForSelect()
{
return new SelectList(GetCodesOfType(Sbm.SystemCode.CommodityType), "Code", "Desc");
}
/// <summary>List of Asset Types for dropdown.</summary>
public IEnumerable<SelectListItem> GetAssetTypeCodesForSelect()
{
return new SelectList(GetCodesOfType(Sbm.SystemCode.AssetType), "Code", "Desc");
}
//-------------------------------------------------------------------
// Form properties.
/// <summary>
+3 -2
View File
@@ -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,
+18 -20
View File
@@ -8,12 +8,12 @@ using System;
namespace Sarand.BusinessMgr.Net.Standard.Base.App
{
//=======================================================================
/// <summary>
/// Application configuration:
/// <para>- Availability of UI components - menu options, views etc.</para>
/// </summary>
public static class SbmAppConfig
//=======================================================================
/// <summary>
/// Application configuration:
/// <para>- Availability of UI components - menu options, views etc.</para>
/// </summary>
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()}");
@@ -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);
//-------------------------------------------------------------------
}
//=======================================================================
+41 -17
View File
@@ -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.
/// <summary>
/// Internal User Context for read-only database access when this class is used outside of user specific sessions.
/// <para>- data caches etc.</para>
/// Internal core Session Data for Core database access when this
/// class is used outside of user specific core sessions, eg.
/// <para>- Pre-login.</para>
/// <para>- Data caches.</para>
/// <para>- Control application session interacting with a core database.</para>
/// </summary>
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.
/// <summary>
/// Sessionless construction - minimal context information.
/// </summary>
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<TypeCodeDesc> AssociationTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.AssociationType); } }
public List<TypeCodeDesc> CommodityTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.CommodityType); } }
public List<TypeCodeDesc> AssetTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.AssetType); } }
public List<TypeCodeDesc> VehicleTypeCodes { get { return GetSystemCodes(Sbm.SystemCode.VehicleType); } }
public List<TypeCodeDesc> 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;
}
}
@@ -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);
+60 -53
View File
@@ -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
/// <summary>
/// Basic user session data, shared by Portal and Control applications.
/// </summary>
public abstract class SbmSessionData : ISbmUserContext
{
//-------------------------------------------------------------------
private static long sessionIdxRoot = SacsRandomHelper.GetInt32(1000, 1999);
// Definitions.
//-------------------------------------------------------------------
// Construction.
/// <summary>Protected constructor for deserialisation only.</summary>
protected SbmSessionData(long sessionIdx, int itemIdx, SbmSessionContext sessionContext)
{
SessionIdx = sessionIdx;
ItemIdx = itemIdx;
SessionContext = sessionContext;
}
/// <summary>
/// Plain constructor.
/// <para>- SessionContext must be supplied.</para>
/// </summary>
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.
/// <summary>
/// Constructor to persist the Session index, eg. for deserialisation from Session.
/// <para>- Session index of zero indicates sessionless data, eg. background tasks.</para>
/// <para>- Session index less than zero will assign a new value.</para>
/// </summary>
protected SbmSessionData(long sessionIdx, SbmSessionContext sessionContext)
{
SessionIdx = sessionIdx >= 0 ? sessionIdx : sessionIdxNext++;
DataIdx = dataIdxNext++;
SessionContext = sessionContext;
}
/// <summary>
/// Main constructor.
/// <para>- SessionContext must be supplied.</para>
/// </summary>
protected SbmSessionData(SbmSessionContext sessionContext)
{
SessionIdx = sessionIdxNext++;
DataIdx = dataIdxNext++;
SessionContext = sessionContext;
}
//-------------------------------------------------------------------
// Properties.
/// <summary>
/// Session Index - assigned in sequence and persistent when data is serialised/deserialised.
/// </summary>
public long SessionIdx { get; }
/// <summary>
/// Data Index - assigned in sequence for each object constructed.
/// </summary>
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; }
//-------------------------------------------------------------------
}
//=======================================================================
@@ -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
//-------------------------------------------------------------------
@@ -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<SysIdString> supervisedOwners = new List<SysIdString>();
/// <summary>User Security Item Id.</summary>
public SysId SecurityItemId { get; protected set; } = new SysId();
/// <summary>User Affiliate Id.</summary>
public SysId AffiliateId { get; protected set; } = new SysId();
/// <summary>User first name.</summary>
public String FirstName { get; protected set; } = "";
/// <summary>User last name.</summary>
public String LastName { get; protected set; } = "";
/// <summary>User display name.</summary>
public String DisplayName { get; protected set; } = "";
/// <summary>User email address.</summary>
public String EmailAddress { get; protected set; } = "";
/// <summary>User managed associations - Id and display name.</summary>
public List<SysIdString> SupervisedOrganisations { get { return new List<SysIdString>(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<SysIdString> 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() { }
/// <summary>Organisation Affiliate Id.</summary>
public SysId AffiliateId { get; protected set; } = new SysId();
/// <summary>Organisation Affiliate Type.</summary>
public Sbm.AffiliateType AffiliateType { get; protected set; } = Sbm.AffiliateType.Unknown;
/// <summary>Organisation display name.</summary>
public String DisplayName { get; protected set; } = "";
/// <summary>Organisation Interface context - to qualify interfaces belonging to the organisation.</summary>
public String InterfaceContext { get; protected set; } = "";
/// <summary>Organisation 'Internal' Association Id.</summary>
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; } }
/// <summary>User Security Item Id.</summary>
public SysId UserSecurityItemId { get { return User?.SecurityItemId; } }
/// <summary>User Affiliate Id.</summary>
public SysId UserAffiliateId { get { return User?.AffiliateId; } }
/// <summary>User display name.</summary>
public String UserDisplayName { get { return userData?.DisplayName; } }
/// <summary>User email address.</summary>
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; } }
/// <summary>Organisation Affiliate Id.</summary>
public SysId OrganisationAffiliateId { get { return Organisation?.AffiliateId; } }
/// <summary>Organisation Affiliate Type.</summary>
public Sbm.AffiliateType OrganisationAffiliateType { get { return Organisation?.AffiliateType ?? Sbm.AffiliateType.Unknown; } }
/// <summary>Organisation 'Internal' Association Id.</summary>
public SysId OrganisationAssociationId { get { return Organisation?.AssociationId; } }
/// <summary>Organisation display name.</summary>
public String OrganisationDisplayName { get { return Organisation?.DisplayName; } }
/// <summary>Organisation Interface context - to qualify interfaces belonging to the organisation.</summary>
public String OrganisationInterfaceContext { get { return Organisation?.InterfaceContext; } }
public List<SysIdString> SupervisedOrganisations { get { return new List<SysIdString>(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<SysIdString> 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;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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<CodeDesc>();
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)
@@ -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
@@ -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(); }
@@ -249,6 +249,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
//-------------------------------------------------------------------
// Utilities.
public ItemId GetItemId()
{
return new ItemId((short)Sbm.ItemType.AssetCategory, Id);
}
//-------------------------------------------------------------------
// Properties.
@@ -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
@@ -1862,7 +1862,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
{
SbmAccountMgr accountMgr = null;
List<StringPair> lValue = new List<StringPair>();
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());
@@ -794,7 +794,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
//-------------------------------------------------------------------
// Status Categories.
public static List<TypeCodeDesc> GetTransactionStatusCats(ISbmUserOrganisationContext userContext, Sbm.TransactionType transactionType)
public static List<TypeCodeDesc> GetTransactionStatusCats(Sbm.TransactionType transactionType)
{
List<TypeCodeDesc> statusCats = new List<TypeCodeDesc>();
List<TypeCodeDesc> 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;
+7 -1
View File
@@ -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
}
/// <summary>
/// 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; }
/// <summary>Vehicle status.</summary>
public StatusCat StatusCat { get; set; } = StatusCat.Any;
// Utilities.
@@ -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;
@@ -222,6 +222,10 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
//-------------------------------------------------------------------
// Utilities.
public ItemId GetItemId()
{
return new ItemId((short)Sbm.ItemType.VehicleEvent, Id);
}
//-------------------------------------------------------------------
// Properties.
@@ -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:
@@ -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();
//-------------------------------------------------------------------
/// <summary>
@@ -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}.");
@@ -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
{
//=======================================================================
/// <summary>
/// Session data - Common User properties associated with either a Core or Control user session.
/// </summary>
public interface ISbmSessionData_Base : ISbmUserContext
{
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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
{
//=======================================================================
/// <summary>
/// Control Session data - User properties associated with a Control user session.
/// </summary>
public interface ISbmSessionData_Control : ISbmSessionData_Base, ISbmUserContext
{
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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
{
//=======================================================================
/// <summary>
/// Core Session data - User and Organisation properties associated with a Core user session.
/// </summary>
public interface ISbmSessionData_Core : ISbmUserOrganisationContext
{
//-------------------------------------------------------------------
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -367,11 +367,21 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
public abstract List<SbmAffiliate> GetAffiliateList(SbmAffiliate.Params prm);
public abstract DbResultSet ExecuteAffiliateQuery(List<ColumnDfn> columns, SbmAffiliate.Params prm);
public List<SysIdString> GetAffiliatesSupervisedBy(SysId affiliateIdUser)
public bool IsAffiliateSupervisedBy(SysId affiliateIdContact, SysId affiliateIdSupervisor)
{
List<SysIdString> affiliateIdNames = new List<SysIdString>();
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<SysIdString> GetAffiliatesSupervisedBy(SysId affiliateIdSupervisor)
{
List<SysIdString> affiliateIdNames = new List<SysIdString>();
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
prmAffiliate.AffiliateIdAssocTarget = affiliateIdSupervisor;
prmAffiliate.TargetSupervised = SbmAffiliate.Params.Supervised.Yes;
foreach (SbmAffiliate affiliate in GetAffiliateList(prmAffiliate))
{
@@ -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.
//-------------------------------------------------------------------
@@ -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))
{
@@ -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)
{
}
//-------------------------------------------------------------------
}
}
@@ -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
@@ -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; } }
//-------------------------------------------------------------------
}
@@ -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<TypeCodeDesc> GetTransactionStatusCats(Sbm.TransactionType eType)
{
List<TypeCodeDesc> transactionStatusCats = new List<TypeCodeDesc>();
List<TypeCodeDesc> 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
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -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.
@@ -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;
@@ -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;
@@ -493,13 +493,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
List<String> filter = new List<String>();
// 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;
@@ -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);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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<SbmSessionData_Control>(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);
}
}
}
//=======================================================================
}
@@ -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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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);
}
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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<IConfiguration> mockConfiguration = new Mock<IConfiguration>();
Mock<IWebHostEnvironment> mockEnvironment = new Mock<IWebHostEnvironment>();
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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
SbmcRepository repository = Internals_Control.ControlInstanceMgr.GetRepositoryByContext(instanceContext);
disposables.Add(repository);
return new SbmCoreInstanceConsole_Control(SessionData_Control, repository);
}
}
//-------------------------------------------------------------------
// Repositories.
/// <summary>
/// Retrieve an active repository, randomly selected.
/// </summary>
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();
}
/// <summary>
/// Retrieve an active repository by context.
/// </summary>
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();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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<SbmSessionData_Control>(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);
}
}
//=======================================================================
}
@@ -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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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<string, string> passwordHashes = new Dictionary<string, string>();
using (SbmSecurityConsole_Web securityConsole = new SbmSecurityConsole_Web(UserContext))
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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++)
@@ -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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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);
}
//-------------------------------------------------------------------
}
@@ -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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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<SysIdString> 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<SbmSessionData_Portal>(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);
}
}
}
//=======================================================================
}
@@ -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<IConfiguration> mockConfiguration = new Mock<IConfiguration>();
Mock<IWebHostEnvironment> mockEnvironment = new Mock<IWebHostEnvironment>();
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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
SbmcRepository repository = Internals_Control.ControlInstanceMgr.GetRepositoryByContext(instanceContext);
disposables.Add(repository);
return new SbmCoreInstanceConsole_Control(repository);
}
return AppPortal.GetControlSessionContextByRepositoryContext(instanceContext);
}
//-------------------------------------------------------------------
@@ -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<IConfiguration> mockConfiguration = new Mock<IConfiguration>();
Mock<IWebHostEnvironment> mockEnvironment = new Mock<IWebHostEnvironment>();
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;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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<SysIdString> 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<SbmSessionData_Portal>(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);
}
}
//=======================================================================
}
@@ -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);
}
//-------------------------------------------------------------------
@@ -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)
{ }
/// <summary>
/// SessionData construction.
@@ -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);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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
{
//=======================================================================
/// <summary>
/// Wrapper class to allow access to core internals from Control application.
/// </summary>
public class SbmUserContext_Control : ISbmUserOrganisationContext
{
//-------------------------------------------------------------------
public SbmUserContext_Control(SbmSessionData_Control sessionData)
{
SessionData = sessionData;
}
//-------------------------------------------------------------------
// Properties.
private SbmSessionData_Control SessionData { get; }
//-------------------------------------------------------------------
/// <summary>Session Context - Identifies database connections etc.</summary>
public SbmSessionContext SessionContext { get { return null; } }
//-------------------------------------------------------------------
// User properties.
/// <summary>User Security Item Id.</summary>
public SysId UserSecurityItemId { get { return null; } }
/// <summary>User Affiliate Id.</summary>
public SysId UserAffiliateId { get { return null; } }
/// <summary>User display name.</summary>
public String UserDisplayName { get { return SessionData.UserDisplayName; } }
/// <summary>User email address.</summary>
public String UserEmailAddress { get { return SessionData.UserEmailAddress; } }
/// <summary>Does the context represent a valid user account.</summary>
public bool ValidUser { get { return SessionData.ValidUser; } }
/// <summary>Database update info - user session specific properties for database inserts/updates.</summary>
public DbUpdateInfo DbUpdateInfo { get { return SessionData.DbUpdateInfo; } }
//-------------------------------------------------------------------
/// <summary>Security profile - what the user is allowed to do based on security roles and groups.</summary>
public ISbmSecurityProfile_Core SecurityProfile_Core { get; }
//-------------------------------------------------------------------
// Organisation properties.
/// <summary>Organisation Affiliate Id.</summary>
public SysId OrganisationAffiliateId { get; }
/// <summary>Organisation Affiliate Type.</summary>
public Sbm.AffiliateType OrganisationAffiliateType { get; }
/// <summary>Organisation 'Internal' Association Id.</summary>
public SysId OrganisationAssociationId { get; }
/// <summary>Organisation display name.</summary>
public String OrganisationDisplayName { get; }
/// <summary>Organisation Interface context - to qualify interfaces belonging to the organisation.</summary>
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; }
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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
}
/// <summary>Core internals for accessing core managers etc.</summary>
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);
}
/// <summary>
/// Create core security console.
/// </summary>
/// <returns></returns>
public override SaSecurityConsole CreateSecurityConsole()
{
return App.CreateSecurityConsole(internals.UserContext);
}
//-------------------------------------------------------------------
}
//=======================================================================
@@ -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.
@@ -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<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// 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.
@@ -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));
@@ -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<SbmController_Control> 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.
//-------------------------------------------------------------------
/// <summary>Control session data</summary>
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<SbmSessionData_Control>(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;
}
@@ -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)
{
@@ -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);
@@ -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<SelectListItem> GetInstanceContextsForSelect()
@@ -453,4 +453,10 @@
<data name="label.rows" xml:space="preserve">
<value>Rows</value>
</data>
<data name="caption.vehicle.update" xml:space="preserve">
<value>Update Vehicle</value>
</data>
<data name="caption.vehicle.create" xml:space="preserve">
<value>Create Vehicle</value>
</data>
</root>
@@ -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" })
<div class="spacer2"></div>
<div class="sbc-caption">@Localiser["label.instance"]</div>
@@ -55,6 +56,7 @@
<div class="spacer2"></div>
<div class="sbc-caption">@Localiser["label.organisation"]</div>
@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 @@
<div class="spacer2"></div>
<div class="sbc-caption">@Localiser["label.user"]</div>
@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 *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.UserFirstName)">
@@ -209,6 +212,7 @@
</div>
<div class="col-sm-9">
<div class="sbc-control">
@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 })
</div>
<div class="sbc-message"></div>
@@ -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) });
});
//--------------------------------------------------------------
@@ -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);
}
@@ -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);
}
/// <summary>
/// SessionData construction.
/// <para>SessionContext and UserAccount must be supplied.</para>
/// <para>Organisation is optional.</para>
/// Session Data construction for non-session data, eg. background tasks.
/// <para>.</para>
/// </summary>
public SbmSessionData_Portal(SbmSessionContext sessionContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> 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);
}
/// <summary>
/// Session Data construction.
/// <para>- Session Context must be supplied.</para>
/// <para>- Other parameters are optional and can be added later via Refresh().</para>
/// </summary>
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<SysIdString> 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<SysIdString>();
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; }
/// <summary>User managed associations - Id and display name.</summary>
public List<SysIdString> SupervisedOrganisations { get { return new List<SysIdString>(supervisedOrganisations); } }
protected List<SysIdString> supervisedOrganisations { get; } = new List<SysIdString>();
// Utilities.
public bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> 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
/// <summary>Portal User details.</summary>
public UserData_Portal User { get; private set; }
//-------------------------------------------------------------------
/// <summary>
/// Update the user's contact details against the session.
/// Update the User and Organisation details against the Session Data.
/// <para>- User identity must match that already against the session.</para>
/// </summary>
public bool RefreshUser(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> 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
//-------------------------------------------------------------------
/// <summary>
/// User Profile.
/// User Profile - persistent session properties relating to default population of views, forms etc.
/// <para>- Filter settings.</para>
/// </summary>
public class UserProfileData
@@ -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);
}
//-------------------------------------------------------------------
}
}
@@ -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<string, string> Value { get; } = new Dictionary<string, string>();
}
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<AssetCategoryListData> AssetCategories { get; } = new List<AssetCategoryListData>();
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<CodeDesc> AssetTypes { get; } = new List<CodeDesc>();
public List<CodeDesc> IncomeTypes { get; } = new List<CodeDesc>();
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
public List<CodeDesc> StatusesCreate { get; } = new List<CodeDesc>();
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<AssetCategoryListData> AssetCategories { get; } = new List<AssetCategoryListData>();
}
//-------------------------------------------------------------------
[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<ColumnDfn> columns = new List<ColumnDfn>()
{
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;
}
@@ -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);
}
@@ -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<CodeDesc> CommodityTypes { get; } = new List<CodeDesc>();
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
@@ -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<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
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<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
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);
}
@@ -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;
@@ -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));
@@ -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<TypeCodeDesc> 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
/// <para>- Open user session - store details against Sesion Data.</para>
/// <para>- Set 'Keep logged in' cookie if required.</para>
/// </summary>
protected bool SignUserIn(SbmInternals internalsForUser, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> 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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
// 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
//-------------------------------------------------------------------
/// <summary>Populate the user's profile contact details to the session.</summary>
protected bool RefreshSessionProfileContact(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> 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;
}
//-------------------------------------------------------------------
/// <summary>Start a new user session on sign-in.</summary>
protected bool OpenUserSession(SbmSessionContext sessionContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> 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<SysIdString> 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;
}
@@ -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<IDisposable> disposables = new DisposableCollection<IDisposable>())
{
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<SysIdString> 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
/// <summary>
/// Identify the organisation for the user to login to - either last selected (via SysParam) or first in list.
/// </summary>
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<SysIdString> 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<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
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}.");
@@ -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))
@@ -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<CodeDesc> TransactionTypes { get; } = new List<CodeDesc>();
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
@@ -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))
@@ -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"];
@@ -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);
}
//-------------------------------------------------------------------
@@ -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.
@@ -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
{
//-------------------------------------------------------------------
/// <summary>Prefix for field names.</summary>
public const String FieldNamePrefix = "AssetCat";
/// <summary>Item fields.</summary>
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,
}
/// <summary>
/// Identifier used by form fields to show control specific messages generated by model validation etc.
/// <para>- Both page and model should use this method to consistently generate the field name.</para>
/// </summary>
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<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Column labels.
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
}
public ColumnData Column { get; } = new ColumnData();
}
public ListConfigData ListConfig { get; private set; }
//-------------------------------------------------------------------
/// <summary>
/// Populate AssetCategory list configuration data - only required on initial page construction.
/// </summary>
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<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Read-only field.
public HashSet<string> Readonly { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Field labels.
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
}
public FieldData Field { get; } = new FieldData();
}
/// <summary>
/// Populate item configuration for existing vehicle.
/// </summary>
public void PopulateItemConfig(ItemConfigData config, SbmAssetCategory assetCategory)
{
PopulateItemConfig(config, assetCategory.GetItemId(), assetCategory.AssetType);
}
/// <summary>
/// Populate item configuration for new or existing vehicle.
/// </summary>
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}");
//---------------------------------------------------------------
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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"]);
}
}
@@ -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<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
// 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();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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}");
@@ -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()
{
@@ -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.
@@ -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()
{
@@ -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;
@@ -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()
{
@@ -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.
/// <para>- Contact model cannot define this as contact list/dialog may be included in other views with their own model, eg. Association page.</para>
/// </summary>
public IEnumerable<SelectListItem> GetAffiliateTypeCodesForFilterSelect()
public IEnumerable<SelectListItem> GetAffiliateTypeCodesForFilterDropdown()
{
List<TypeCodeDesc> 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.
/// <para>- Association model cannot define this as association list/dialog may be included in other views with their own model, eg. Commodity page.</para>
/// </summary>
public IEnumerable<SelectListItem> GetAssociationTypeCodesForFilterSelect()
public IEnumerable<SelectListItem> GetAssociationTypeCodesForFilterDropdown()
{
List<TypeCodeDesc> 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.
/// <summary>
/// List of Commodity Types for filter dropdown.
/// </summary>
public IEnumerable<SelectListItem> GetCommodityTypeCodesForFilterDropdown()
{
List<TypeCodeDesc> commodityTypes = new List<TypeCodeDesc>();
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");
}
/// <summary>
/// List of Commodity Types for form dropdown.
/// </summary>
public IEnumerable<SelectListItem> GetCommodityTypeCodesForDropdown()
{
List<TypeCodeDesc> commodityTypes = new List<TypeCodeDesc>();
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");
}
/// <summary>
/// List of Asset Types for filter dropdown.
/// </summary>
public IEnumerable<SelectListItem> GetAssetTypeCodesForFilterDropdown()
{
List<TypeCodeDesc> assetTypes = new List<TypeCodeDesc>();
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");
}
/// <summary>
/// List of Asset Types for form dropdown.
/// </summary>
public IEnumerable<SelectListItem> GetAssetTypeCodesForDropdown()
{
List<TypeCodeDesc> assetTypes = new List<TypeCodeDesc>();
foreach (TypeCodeDesc assetType in GetCodesOfType(Sbm.SystemCode.AssetType))
{
assetTypes.Add(assetType);
}
return new SelectList(assetTypes, "Code", "Desc");
}
//-------------------------------------------------------------------
// View reference data - Transactions.
/// <summary>
/// List of Transaction Types for filter dropdown.
/// </summary>
public IEnumerable<SelectListItem> GetTransactionTypeCodesForFilterSelect()
public IEnumerable<SelectListItem> GetTransactionTypeCodesForFilterDropdown()
{
List<TypeCodeDesc> transactionTypes = new List<TypeCodeDesc>();
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.
/// <summary>
/// List of Commodity Types for filter dropdown.
/// </summary>
public IEnumerable<SelectListItem> GetCommodityTypeCodesForFilterSelect()
{
List<TypeCodeDesc> commodityTypes = new List<TypeCodeDesc>();
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");
}
/// <summary>
/// List of Commodity Types for form dropdown.
/// </summary>
public IEnumerable<SelectListItem> GetCommodityTypeCodesForDropdown()
{
List<TypeCodeDesc> commodityTypes = new List<TypeCodeDesc>();
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");
//-------------------------------------------------------------------
}
//=======================================================================
@@ -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"]));
@@ -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
{
//-------------------------------------------------------------------
/// <summary>Prefix for field names.</summary>
public const String FieldNamePrefix = "Vehicle";
/// <summary>Item fields.</summary>
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,
}
/// <summary>
/// Identifier used by form fields to show control specific messages generated by model validation etc.
/// <para>- Both page and model should use this method to consistently generate the field name.</para>
/// </summary>
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<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Column labels.
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
}
public ColumnData Column { get; } = new ColumnData();
}
public ListConfigData ListConfig { get; private set; }
//-------------------------------------------------------------------
/// <summary>
/// Populate Vehicle list configuration data - only required on initial page construction.
/// </summary>
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<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Read-only field.
public HashSet<string> Readonly { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Field labels.
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
}
public FieldData Field { get; } = new FieldData();
}
/// <summary>
/// Populate item configuration for existing vehicle.
/// </summary>
public void PopulateItemConfig(ItemConfigData config, SbmVehicle vehicle)
{
PopulateItemConfig(config, vehicle.GetItemId());
}
/// <summary>
/// Populate item configuration for new or existing vehicle.
/// </summary>
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}");
//---------------------------------------------------------------
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
// 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();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -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<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
// 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();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -52,7 +52,6 @@
<ItemGroup>
<Folder Include="Views\Assets\Asset\" />
<Folder Include="Views\Assets\Vehicle\" />
<Folder Include="Views\Transaction\" />
</ItemGroup>
@@ -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");
}
<div class="sbm-panel AssetCategories fullheight">
<script type="text/javascript">
sbm.dlg.title.createItem = '@(Localiser.GetJavascriptText("caption.asset.category.create"))';
sbm.dlg.title.updateItem = '@(Localiser.GetJavascriptText("caption.asset.category.update"))';
</script>
<div class="sbm-panel-data sbm-flex">
@* 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. *@
<div class="sbm-panel-header">
<div class="row">
<div class="fixed">
<partial name="~/Views/Common/ResultsPaging.cshtml" />
</div>
<div class="col center"><div class="sbm-panel-caption">@Localiser["caption.asset.categories"]</div></div>
<div class="fixed">
@* Burger menu *@
<ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div>
</div>
</div>
@* Filter Panel *@
<div class="sbm-panel-filter">
<div class="row pb4">
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-sm-7">
@Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" })
</div>
</div>
</div>
}
@* Item list *@
<div class="sbm-panel-item-table sbm-flex">
<table class="sbm-item-list">
<thead>
<tr>
<th class="pl-2">@Localiser["label.type"]</th>
<th class="">@Localiser["label.code"]</th>
<th class="">@Localiser["label.description"]</th>
<th class="center">@Localiser["label.status"]</th>
<th class="right" style="width:2%;"></th>
</tr>
<tr><td colspan="6"><div class="sbm-panel-messages"></div></td></tr>
</thead>
<tbody></tbody>
</table>
</div>
@* Element templates *@
<div class="sbm-panel-item-template">
@* Filter Burger option template - ul is ignored *@
<ul class="sbm-dropdown-menu AssetCategoryFilter">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul>
@* AssetCategory row template - table is ignored. *@
<table class="">
<tr class="sbm-row-item AssetCategory">
<td><div class="AssetCategoryType pl-1"></div></td>
<td><div class="AssetCategoryCode"></div></td>
<td><div class="AssetCategoryDescription"></div></td>
<td><div class="AssetCategoryStatusDesc center"></div></td>
<td>
<div class="right">
@* Burger menu *@
<ul class="nav navbar-nav navbar-light navbar-right sbm-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div>
</td>
</tr>
</table>
@* Item Burger option template - ul is ignored *@
<ul class="sbm-dropdown-menu AssetCategory">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul>
</div>
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryId", @onSubmit = "return false;" }))
{
@Html.HiddenFor(model => model.AssetCategory.Id, new { @id = "", @class = "AssetCategoryId" })
}
<div id="dlgAssetCategory" class="sbm-dialog">
<div class="spacer2"></div>
@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 *@
<div class="sbm-form-control AssetCategoryType">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="ifAssetCategoryType"><span>@Localiser["label.type"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbm-control">
@Html.DropDownListFor(model => model.AssetCategory.TypeCode, Model.GetAssetTypeCodesForSelect(), Localiser["label.select"], new { @id = "ifAssetCategoryType", @class = "AssetCategoryType sbm-select" })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
@* Contact Code *@
<div class="sbm-form-control AssetCategoryCode">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="ifAssetCategoryCode"><span>@Localiser["label.code"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbm-control">
@Html.TextBoxFor(model => model.AssetCategory.Code, new { @id = "ifAssetCategoryCode", @class = "AssetCategoryCode sbm-input upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Code) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
@* Description *@
<div class="sbm-form-control AssetCategoryDescription">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="ifAssetCategoryDescription"><span>@Localiser["label.description"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbm-control">
@Html.TextBoxFor(model => model.AssetCategory.DescBrief, new { @id = "ifAssetCategoryDescription", @class = "AssetCategoryDescription sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
@* Status *@
<div class="sbm-form-control AssetCategoryStatus">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="cbAssetCategoryStatus"><span>@Localiser["label.status"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbm-control">
<select id="cbAssetCategoryStatus" class="sbm-select AssetCategoryStatus" name="AssetCategory.StatusCode"></select>
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
@* Notes *@
<div class="sbm-form-control AssetCategoryNotes">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="ifAssetCategoryNotes"><span>@Localiser["label.notes"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextAreaFor(model => model.AssetCategory.Notes, new { @id = "ifAssetCategoryNotes", @class = "AssetCategoryNotes sbm-textarea", @rows = 3, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
}
<div class="spacer2"></div>
</div>
</div>
</div>
<partial name="Panel-AssetCategoryMaintain.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" })
}
<div id="dlgAssetCategory" class="sbm-dialog">
<div class="spacer2"></div>
@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 *@
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Type)">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="ifAssetCategoryType"><span>@Localiser["label.type"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbm-control">
@Html.DropDownList("AssetCategory.TypeCode", Model.GetAssetTypeCodesForDropdown(), Localiser["label.select"], new { @id = "ifAssetCategoryType", @class = "AssetCategoryType sbm-select sbm-auto-val" })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
@* Contact Code *@
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Code)">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="ifAssetCategoryCode"><span>@Localiser["label.code"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbm-control">
@Html.TextBox("AssetCategory.Code", "", new { @id = "ifAssetCategoryCode", @class = "AssetCategoryCode sbm-input sbm-auto-val upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Code) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
@* Caption *@
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Caption)">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="ifAssetCategoryCaption"><span>@Localiser["label.description"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbm-control">
@Html.TextBox("AssetCategory.Caption", "", new { @id = "ifAssetCategoryCaption", @class = "AssetCategoryDescription sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
@* Status *@
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Status)">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="cbAssetCategoryStatus"><span>@Localiser["label.status"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbm-control">
<select id="cbAssetCategoryStatus" class="sbm-select AssetCategoryStatus sbm-auto-val" name="AssetCategory.StatusCode"></select>
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
@* Notes *@
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Notes)">
<div class="row">
<div class="col-sm-3">
<div class="sbm-label">
<label for="ifAssetCategoryNotes"><span>@Localiser["label.notes"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sbm-control">
@Html.TextArea("AssetCategory.Notes", "", new { @id = "ifAssetCategoryNotes", @class = "AssetCategoryNotes sbm-textarea sbm-auto-val", @rows = 3, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes) })
</div>
<div class="sbm-message"></div>
</div>
</div>
</div>
}
<div class="spacer2"></div>
</div>
@@ -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 *@
<div class="sbm-panel-item-table sbm-flex">
<table class="sbm-item-list">
<thead>
<tr>
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Type) width25pc pl-1">@Localiser["label.type"]</th>
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Code) width10pc">@Localiser["label.code"]</th>
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Caption) width25pc">@Localiser["label.description"]</th>
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Notes) width25pc d-none d-md-table-cell">@Localiser["label.notes"]</th>
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Status) width10pc center">@Localiser["label.status"]</th>
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Actions) width5pc"></th>
</tr>
<tr><td colspan="6"><div class="sbm-panel-messages"></div></td></tr>
</thead>
<tbody></tbody>
</table>
</div>
@* Element templates *@
<div class="sbm-panel-item-template">
@* Filter Burger option template - ul is ignored *@
<ul class="sbm-dropdown-menu AssetCategoryFilter">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul>
@* AssetCategory row template - table is ignored. *@
<table class="">
<tr class="sbm-row-item AssetCategory">
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Type) pl-1"></td>
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Code)"></td>
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Caption)"></td>
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Notes) d-none d-md-table-cell"></td>
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Status) center"></td>
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Actions)">
<div class="right">
@* Burger menu *@
<ul class="nav navbar-nav navbar-light navbar-right sbm-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div>
</td>
</tr>
</table>
@* Item Burger option template - ul is ignored *@
<ul class="sbm-dropdown-menu AssetCategory">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul>
</div>

Some files were not shown because too many files have changed in this diff Show More