Dynamic Portal menu
This commit is contained in:
@@ -99,7 +99,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
}
|
||||
public DatabaseConfig ControlDatabase { get; private set; }
|
||||
public DatabaseConfig TemplateDatabase { get; private set; }
|
||||
public List<DatabaseConfig> BusMgrDatabases { get; } = new List<DatabaseConfig>();
|
||||
// Documents.
|
||||
public class DocumentsConfig
|
||||
{
|
||||
@@ -211,18 +210,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
ExtractDatabaseConfig(TemplateDatabase, templateDatabaseSection);
|
||||
}
|
||||
|
||||
// BusinessMgr databases.
|
||||
IConfigurationSection busMgrDatabasesSection = configSection.GetSection("BusMgrDatabases");
|
||||
if (busMgrDatabasesSection.Exists())
|
||||
{
|
||||
foreach (IConfigurationSection busMgrDbSection in busMgrDatabasesSection.GetChildren())
|
||||
{
|
||||
SbmAppConfig.DatabaseConfig dbConfig = new SbmAppConfig.DatabaseConfig();
|
||||
ExtractDatabaseConfig(dbConfig, busMgrDbSection);
|
||||
BusMgrDatabases.Add(dbConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// Variants.
|
||||
foreach (ConfigurationSection variantSection in configSection.GetSection("Variants").GetChildren())
|
||||
{
|
||||
|
||||
@@ -71,8 +71,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
||||
applicationParams.Add("Configuration", SbmSystem.DebugMode ? "Debug" : "Release");
|
||||
applicationParams.Add("Environment", EnvironmentName);
|
||||
applicationParams.Add("Control database", AppConfig.ControlDatabase.Location);
|
||||
foreach (SbmAppConfig.DatabaseConfig dbConfig in AppConfig.BusMgrDatabases)
|
||||
applicationParams.Add("BusMgr database", (dbConfig.Identifiers.Any() ? $"[{String.Join(",", dbConfig.Identifiers)}] " : "") + dbConfig.Location);
|
||||
applicationParams.Add("Application root", SbmSystem.ApplicationFolder);
|
||||
if (!StringUtil.IsEmpty(AppConfig.Documents.RootFolder))
|
||||
applicationParams.Add("Documents root", AppConfig.Documents.RootFolder);
|
||||
|
||||
@@ -117,8 +117,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Model.
|
||||
//-------------------------------------------------------------------
|
||||
protected void RefreshModel(SbmModel_Base model)
|
||||
protected virtual void RefreshModel(SbmModel_Base model)
|
||||
{
|
||||
if (model == null) return;
|
||||
|
||||
|
||||
@@ -53,7 +53,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
|
||||
ProspectGroup,
|
||||
// Associated data.
|
||||
GroupMembers,
|
||||
Association_Count,
|
||||
AssociationOwner_Count,
|
||||
AssociationTarget_Count,
|
||||
// Common properties.
|
||||
Notes,
|
||||
Flag,
|
||||
|
||||
@@ -366,7 +366,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
private static readonly String aliasAffiliate_AddPrim = "Aff_AddPrim";
|
||||
private static readonly String prefixAffiliate_AddPrim = aliasAffiliate_AddPrim + "_";
|
||||
private static readonly String colNameAffiliate_GroupMembers = "GroupMembers";
|
||||
private static readonly String colNameAffiliate_AssociationCount = "AssocCount";
|
||||
private static readonly String colNameAffiliate_AssociationOwnerCount = "AssocOwnerCount";
|
||||
private static readonly String colNameAffiliate_AssociationTargetCount = "AssocTargetCount";
|
||||
|
||||
// Column definition population.
|
||||
private void SetAffiliateColDfn
|
||||
@@ -499,9 +500,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
SetAffiliateColDfn(columnDfn, "Members", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
||||
columnDfn.DataName = colNameAffiliate_GroupMembers;
|
||||
break;
|
||||
case SbmAffiliate.Column.Association_Count:
|
||||
SetAffiliateColDfn(columnDfn, "Associations", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
||||
columnDfn.DataName = colNameAffiliate_AssociationCount;
|
||||
case SbmAffiliate.Column.AssociationOwner_Count:
|
||||
SetAffiliateColDfn(columnDfn, "Owner Assocs", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
||||
columnDfn.DataName = colNameAffiliate_AssociationOwnerCount;
|
||||
break;
|
||||
case SbmAffiliate.Column.AssociationTarget_Count:
|
||||
SetAffiliateColDfn(columnDfn, "Target Assocs", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
||||
columnDfn.DataName = colNameAffiliate_AssociationTargetCount;
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
@@ -1042,16 +1047,32 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
if (columns.HasId(SbmAffiliate.Column.Association_Count))
|
||||
// Associations.
|
||||
|
||||
if (columns.HasId(SbmAffiliate.Column.AssociationOwner_Count))
|
||||
{
|
||||
// Count active associations.
|
||||
String aliasAffiliate_Associations = "AffAssocs";
|
||||
String aliasAffiliate_Associations_Owner = "AffAssOwner";
|
||||
DbQuery qryAssocs = new DbQuery(db.DbmsType);
|
||||
qryAssocs.Tables.Add((SbmDbDfn.TableIdx.Association).ToString(), aliasAffiliate_Associations);
|
||||
qryAssocs.Tables.Add((SbmDbDfn.TableIdx.Association).ToString(), aliasAffiliate_Associations_Owner);
|
||||
qryAssocs.Columns.Add("Count(*)");
|
||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdOwner, aliasAffiliate_Associations)}={SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAffiliate)}");
|
||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Status, aliasAffiliate_Associations)}='{StatusCurrent}'");
|
||||
query.Columns.Add("(" + qryAssocs.BuildQuery() + ")", colNameAffiliate_AssociationCount);
|
||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdOwner, aliasAffiliate_Associations_Owner)}={SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAffiliate)}");
|
||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Type, aliasAffiliate_Associations_Owner)}!={(int)Sbm.AssociationType.Internal}");
|
||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Status, aliasAffiliate_Associations_Owner)}='{StatusCurrent}'");
|
||||
query.Columns.Add("(" + qryAssocs.BuildQuery() + ")", colNameAffiliate_AssociationOwnerCount);
|
||||
}
|
||||
|
||||
if (columns.HasId(SbmAffiliate.Column.AssociationTarget_Count))
|
||||
{
|
||||
// Count active associations.
|
||||
String aliasAffiliate_Associations_Target = "AffAssTarget";
|
||||
DbQuery qryAssocs = new DbQuery(db.DbmsType);
|
||||
qryAssocs.Tables.Add((SbmDbDfn.TableIdx.Association).ToString(), aliasAffiliate_Associations_Target);
|
||||
qryAssocs.Columns.Add("Count(*)");
|
||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdTarget, aliasAffiliate_Associations_Target)}={SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAffiliate)}");
|
||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Type, aliasAffiliate_Associations_Target)}!={(int)Sbm.AssociationType.Internal}");
|
||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Status, aliasAffiliate_Associations_Target)}='{StatusCurrent}'");
|
||||
query.Columns.Add("(" + qryAssocs.BuildQuery() + ")", colNameAffiliate_AssociationTargetCount);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Consoles;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -19,12 +21,16 @@ namespace Sarand.BusinessMgr.Test.Web.Portal.App
|
||||
[TestMethod]
|
||||
public void Test_PasswordEncoding()
|
||||
{
|
||||
Assert.IsNotNull(BusMgrDatabase);
|
||||
StringAssert.Matches(BusMgrDatabase.EncodePassword_Hex(""), reHex);
|
||||
using (SbmSecurityConsole_Web securityConsole = new SbmSecurityConsole_Web(UserContext))
|
||||
{
|
||||
|
||||
// Iterate using random filename (8.3).
|
||||
for (int i = 0; i < 1000; i++)
|
||||
StringAssert.Matches(BusMgrDatabase.EncodePassword_Hex(Path.GetRandomFileName()), reHex);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -34,19 +40,23 @@ namespace Sarand.BusinessMgr.Test.Web.Portal.App
|
||||
Assert.IsNotNull(BusMgrDatabase);
|
||||
Dictionary<string, string> passwordHashes = new Dictionary<string, string>();
|
||||
|
||||
// Iterate using random filename (8.3).
|
||||
for (int i = 0; i < 200; i++)
|
||||
using (SbmSecurityConsole_Web securityConsole = new SbmSecurityConsole_Web(UserContext))
|
||||
{
|
||||
string password = Path.GetRandomFileName();
|
||||
string passwordHash = BusMgrDatabase.EncodePassword_Hex(password);
|
||||
StringAssert.Matches(passwordHash, reHex);
|
||||
passwordHashes.Add(password, passwordHash);
|
||||
}
|
||||
foreach (string password in passwordHashes.Keys)
|
||||
{
|
||||
string passwordHash = passwordHashes.GetValueOrDefault(password);
|
||||
StringAssert.Matches(passwordHash, reHex);
|
||||
Assert.IsTrue(BusMgrDatabase.ComparePassword_Hex(password, passwordHash));
|
||||
|
||||
// Iterate using random filename (8.3).
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
string password = Path.GetRandomFileName();
|
||||
string passwordHash = securityConsole.EncodePassword_Hex(password);
|
||||
StringAssert.Matches(passwordHash, reHex);
|
||||
passwordHashes.Add(password, passwordHash);
|
||||
}
|
||||
foreach (string password in passwordHashes.Keys)
|
||||
{
|
||||
string passwordHash = passwordHashes.GetValueOrDefault(password);
|
||||
StringAssert.Matches(passwordHash, reHex);
|
||||
Assert.IsTrue(securityConsole.ComparePassword_Hex(password, passwordHash));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,23 +55,6 @@ namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
public SysId ControlOwnerId { get; protected set; }
|
||||
public SysId ControlRepositoryId { get; protected set; }
|
||||
}
|
||||
private class SessionContextData_Core : SessionContextData
|
||||
{
|
||||
// Instance configuration for core database instance without Control configuration.
|
||||
public SessionContextData_Core(SbmSessionContext_Web sessionContext) : base(sessionContext)
|
||||
{
|
||||
}
|
||||
private SbmInstanceConfig instanceConfig = null;
|
||||
public override SbmInstanceConfig InstanceConfig
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instanceConfig == null)
|
||||
instanceConfig = new SbmInstanceConfig_Core(SessionContext);
|
||||
return instanceConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
private class SessionContextData_Control : SessionContextData
|
||||
{
|
||||
public SessionContextData_Control(SbmSessionContext_Web sessionContext, SysId controlOwnerId, SysId controlRepositoryId) : base(sessionContext)
|
||||
@@ -233,26 +216,6 @@ namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
controlDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
|
||||
if (controlDatabase.HasErrorState())
|
||||
SaLogger.Warn($"{SysUtil.Fn} Control Database initialisation error: " + controlDatabase.ErrorStateMessage);
|
||||
|
||||
// Configure BusMgr database connections.
|
||||
foreach (Net.Core.Web.App.SbmAppConfig.DatabaseConfig dbConfig in AppConfig.BusMgrDatabases)
|
||||
{
|
||||
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
|
||||
config.Location = dbConfig.Location;
|
||||
config.User = dbConfig.User;
|
||||
config.Password = dbConfig.Password;
|
||||
SacsDatabase coreDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config);
|
||||
if (!coreDatabase.HasErrorState())
|
||||
{
|
||||
// Session context.
|
||||
ushort sessionContextIdx = sessionContextIdx_Next++;
|
||||
SessionContextData sessionContextData = new SessionContextData_Core(new SbmSessionContext_Web(sessionContextIdx, Sbm.Application.WebPortal));
|
||||
sessionContextData.BusMgrDatabase = coreDatabase;
|
||||
sessionContextData.RepositoryContexts.UnionWith(dbConfig.Identifiers);
|
||||
sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData);
|
||||
}
|
||||
else SaLogger.Warn($"{SysUtil.Fn} Database: " + coreDatabase.DatabaseName + ". Initialisation error: " + coreDatabase.ErrorStateMessage);
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private SaUpdateLogConsole updateLogConsole;
|
||||
//private SaUpdateLogConsole updateLogConsole;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[HttpGet]
|
||||
[Route("Commodity")]
|
||||
[Route("Commodities")]
|
||||
public IActionResult Index(Model_Commodity model)
|
||||
{
|
||||
if (!ValidUserSession)
|
||||
|
||||
@@ -234,7 +234,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
||||
ColumnDfn colPhoneMobile = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneMobile);
|
||||
ColumnDfn colPhoneDirect = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneDirect);
|
||||
ColumnDfn colEmail = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Email);
|
||||
ColumnDfn colAssocCount = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Association_Count);
|
||||
ColumnDfn colAssocOwnerCount = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.AssociationOwner_Count);
|
||||
ColumnDfn colAssocTargetCount = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.AssociationTarget_Count);
|
||||
ColumnDfn colNotes = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Notes);
|
||||
ColumnDfn colStatus = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Status);
|
||||
ColumnDfn colCreatedOn = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.CreateOn_Date);
|
||||
@@ -242,7 +243,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||
{
|
||||
colId, colName, colAffiliateType,
|
||||
colAddress, colContact, colPhoneMain, colPhoneAlt, colPhoneMobile, colPhoneDirect, colEmail, colAssocCount,
|
||||
colAddress, colContact, colPhoneMain, colPhoneAlt, colPhoneMobile, colPhoneDirect, colEmail, colAssocOwnerCount, colAssocTargetCount,
|
||||
colNotes, colStatus, colCreatedOn, colUpdatedOn
|
||||
};
|
||||
if (responseData.Config.Column.Hide.Contains($"{Model_Contact.ItemField.Address}"))
|
||||
@@ -250,7 +251,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
||||
if (responseData.Config.Column.Hide.Contains($"{Model_Contact.ItemField.Email}"))
|
||||
columns.Remove(colEmail);
|
||||
if (responseData.Config.Column.Hide.Contains($"{Model_Contact.ItemField.Associations}"))
|
||||
columns.Remove(colAssocCount);
|
||||
columns.Remove(colAssocOwnerCount);
|
||||
|
||||
// Sort Columns.
|
||||
if (!prmAffiliate.SortColumns.Any())
|
||||
@@ -279,7 +280,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
||||
affiliateData.Field.Value.Add($"{Model_Contact.ItemField.Status}", SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)));
|
||||
affiliateData.Field.Value.Add($"{Model_Contact.ItemField.CreatedOn}", Localiser.FormatDate(values.GetDate(colCreatedOn.DataName)));
|
||||
affiliateData.Field.Value.Add($"{Model_Contact.ItemField.UpdatedOn}", Localiser.FormatDate(values.GetDate(colUpdatedOn.DataName)));
|
||||
long assocCount = values.GetLong(colAssocCount.DataName);
|
||||
long assocOwnerCount = values.GetLong(colAssocOwnerCount.DataName);
|
||||
long assocTargetCount = values.GetLong(colAssocTargetCount.DataName);
|
||||
long assocCount = assocOwnerCount + assocTargetCount;
|
||||
if (assocCount > 0)
|
||||
affiliateData.AssociationCount = assocCount;
|
||||
// Cleanse item values.
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[HttpGet]
|
||||
[Route("Contact")]
|
||||
[Route("Contacts")]
|
||||
public IActionResult Index(Model_Contact model)
|
||||
{
|
||||
if (!ValidUserSession)
|
||||
|
||||
@@ -24,6 +24,10 @@ using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Database;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||
using Sarand.BusinessMgr.Web.Portal.Helpers;
|
||||
using DocumentFormat.OpenXml.EMMA;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Models;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
{
|
||||
@@ -218,6 +222,26 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
base.OnActionExecuted(filterContext);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Model.
|
||||
/// <summary>
|
||||
/// Populate model wioth session data etc.
|
||||
/// <para>- Invoked from SbmController_Web.OnActionExecuting.</para>
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
protected override void RefreshModel(SbmModel_Base model)
|
||||
{
|
||||
if (model == null) return;
|
||||
base.RefreshModel(model);
|
||||
|
||||
SbmModel_Portal portalModel = model as SbmModel_Portal;
|
||||
if (portalModel != null)
|
||||
{
|
||||
// Populate menu options.
|
||||
portalModel.PopulateMenu();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Keep Logged In.
|
||||
//-------------------------------------------------------------------
|
||||
@@ -238,47 +262,41 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
String logSuffix = keepLoggedInParams.GetValidParams().Concat("", " ", ".");
|
||||
if (keepLoggedInParams.IsValid())
|
||||
{
|
||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(keepLoggedInParams.RepositoryContext, keepLoggedInParams.EmailAddress);
|
||||
if (sessionContexts.Any())
|
||||
// Instance Repository configured on Control database identified by Context.
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(keepLoggedInParams.RepositoryContext);
|
||||
if (sessionContext != null)
|
||||
{
|
||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||
using (SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(keepLoggedInParams.EmailAddress))
|
||||
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateById(keepLoggedInParams.AffiliateIdUser))
|
||||
using (SbmAssociation associationOrganisation = accountMgrForUser.GetAssociationById(keepLoggedInParams.AssociationIdOrganisation))
|
||||
using (SbmAffiliate affiliateOrganisation = accountMgrForUser.GetAffiliateById(associationOrganisation?.AffiliateIdOwner ?? null))
|
||||
{
|
||||
using (SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(keepLoggedInParams.EmailAddress))
|
||||
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateById(keepLoggedInParams.AffiliateIdUser))
|
||||
using (SbmAssociation associationOrganisation = accountMgrForUser.GetAssociationById(keepLoggedInParams.AssociationIdOrganisation))
|
||||
using (SbmAffiliate affiliateOrganisation = accountMgrForUser.GetAffiliateById(associationOrganisation?.AffiliateIdOwner ?? null))
|
||||
if (securityItemUser != null && affiliateUser != null && associationOrganisation != null && affiliateOrganisation != null)
|
||||
{
|
||||
if (securityItemUser != null && affiliateUser != null && associationOrganisation != null && affiliateOrganisation != null)
|
||||
if (securityItemUser.Id.Equals(keepLoggedInParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id))
|
||||
{
|
||||
if (securityItemUser.Id.Equals(keepLoggedInParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id))
|
||||
if (affiliateUser.IsStatusCurrent)
|
||||
{
|
||||
if (affiliateUser.IsStatusCurrent)
|
||||
List<SysIdString> supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
String errorMessage = "";
|
||||
if (SignUserIn(userContext, keepLoggedInParams.RepositoryContext, securityConsoleForUser, accountMgrForUser, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage))
|
||||
{
|
||||
List<SysIdString> supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
String errorMessage = "";
|
||||
if (SignUserIn(userContext, keepLoggedInParams.RepositoryContext, securityConsoleForUser, accountMgrForUser, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage))
|
||||
{
|
||||
SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix);
|
||||
return true;
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "failed to sign user in: " + errorMessage + "." + logSuffix);
|
||||
SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix);
|
||||
return true;
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Affiliate is not active." + logSuffix);
|
||||
else SaLogger.Warn(logPrefix + "failed to sign user in: " + errorMessage + "." + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are inconsistent. " + logSuffix);
|
||||
else SaLogger.Warn(logPrefix + "Affiliate is not active." + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + logSuffix);
|
||||
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are inconsistent. " + logSuffix);
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + logSuffix);
|
||||
}
|
||||
if (ValidUserSession)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else SaLogger.Warn($"{SysUtil.Fn} Keep Logged In cookie found but no matching session contexts found." + logSuffix);
|
||||
|
||||
@@ -69,30 +69,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
// Instance Repository configured on Control database.
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(model.RepositoryContext);
|
||||
String errorMessage = "";
|
||||
|
||||
if (!OpenUserSession(model, sessionContext, ref errorMessage))
|
||||
{
|
||||
if (!StringUtil.IsBlank(errorMessage))
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
if (!(SessionData_Portal?.ValidUser ?? false))
|
||||
{
|
||||
// Session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(model.RepositoryContext, model.EmailAddress);
|
||||
if (sessionContexts.IsEmpty())
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
||||
{
|
||||
String errorMessage = "";
|
||||
if (OpenUserSession(model, sessionContext, ref errorMessage)) break;
|
||||
|
||||
if (!StringUtil.IsBlank(errorMessage))
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!(SessionData_Portal?.ValidUser ?? false))
|
||||
@@ -125,14 +107,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
disposables.Add(accountMgrForUser);
|
||||
|
||||
// User's security item.
|
||||
SaSecurityItem securityItemUser = GetSecurityItemForSignin(securityConsoleForUser, model);
|
||||
SaSecurityItem securityItemUser = GetSecurityItemForSignin(userContext, securityConsoleForUser, 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 (!securityConsoleForUser.PasswordMatches(securityItemUser, model.Password))
|
||||
if (!securityConsoleForUser.PasswordMatches(securityItemUser, model.Password, userContext.DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Supplied password doesn't match Security Item. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}.");
|
||||
return false;
|
||||
@@ -182,7 +164,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SaSecurityItem GetSecurityItemForSignin(SaSecurityConsole securityConsoleForUser, Model_Security model)
|
||||
private SaSecurityItem GetSecurityItemForSignin(SbmUserContext_Web userContext, SaSecurityConsole securityConsoleForUser, Model_Security model)
|
||||
{
|
||||
// Retrieve security item by email address.
|
||||
SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress);
|
||||
@@ -198,7 +180,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
// Record invalid login attempt.
|
||||
securityItemUser.InvalidLoginCount++;
|
||||
securityItemUser.LastInvalidLoginAt = DateTime.Now;
|
||||
if (!securityConsoleForUser.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
||||
if (!securityConsoleForUser.UpdateSecurityItem(securityItemUser, userContext.DbUpdateInfo))
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to store invalid sign-in attempt against User: {model.EmailAddress}. {AccountMgr.ErrorStateMessage}", true);
|
||||
SaLogger.Warn($"{SysUtil.Fn} Attempt to sign-in to User {model.EmailAddress} with invalid password. Attempt: {securityItemUser.InvalidLoginCount}.", true);
|
||||
securityItemUser.Dispose(); securityItemUser = null;
|
||||
@@ -410,15 +392,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
RequestPasswordParams storePasswordParams = ExtractRequestPasswordLinkParams(model.rpe);
|
||||
if (storePasswordParams.IsValid())
|
||||
{
|
||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||
// Identify session contexts for databases with specified Id that hosts the specified email address.
|
||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(storePasswordParams.RepositoryContext, storePasswordParams.EmailAddress);
|
||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
||||
// Instance Repository configured on Control database identified by Context.
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(storePasswordParams.RepositoryContext);
|
||||
if (sessionContext != null)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContextForUser))
|
||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContextForUser))
|
||||
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||
{
|
||||
// Retrieve user details and validate email address.
|
||||
securityItemUser = securityConsoleForUser.GetSecurityItemById(SaSecurity.ItemType.User, storePasswordParams.SecurityItemId);
|
||||
@@ -429,7 +410,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
userContextForUser = userContext;
|
||||
validRequestPasswordParams = true;
|
||||
validSessionRequired = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -471,7 +451,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
String oldPasswordHashed = securityItemUser.PasswordHash;
|
||||
|
||||
// Store password.
|
||||
securityItemUser.PasswordHash = SbmPasswordHelper.GetPasswordHash(securityItemUser, model.Password);
|
||||
// NB Do not use Microsoft.AspNetCore.Identity.PasswordHasher.HashPassword() while legacy (C++) desktop application still in use.
|
||||
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++)
|
||||
@@ -489,7 +470,7 @@ 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, DbUpdateInfo))
|
||||
if (!securityConsole.UpdateSecurityItem(securityItemUser, userContextForUser?.DbUpdateInfo ?? DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to change password for {securityItemUser.EmailAddress}: {securityConsole.ErrorStateMessage}");
|
||||
return Json(responseData.SetControlError(nameof(model.Password), Localiser["security.msg.change.password.failed"]));
|
||||
@@ -537,9 +518,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
model.ValidateRequestPasswordData(responseData);
|
||||
if (responseData.HasControlErrors()) return Json(responseData);
|
||||
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(model.RepositoryContext, model.EmailAddress);
|
||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
||||
// Instance Repository configured on Control database identified by Context.
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(model.RepositoryContext);
|
||||
if (sessionContext != null)
|
||||
{
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
|
||||
|
||||
@@ -76,10 +76,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
{
|
||||
String logPrefix = $"{SysUtil.Fn} 'Request Password' parameters supplied but ";
|
||||
String logSuffix = changePasswordParams.GetValidParams().Concat("", " ", ".");
|
||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(changePasswordParams.RepositoryContext, changePasswordParams.EmailAddress);
|
||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
||||
// Instance Repository configured on Control database identified by Context.
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(changePasswordParams.RepositoryContext);
|
||||
if (sessionContext != null)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
@@ -99,7 +98,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
{
|
||||
model.rpe = encryptedParams;
|
||||
validSessionRequired = false;
|
||||
break;
|
||||
}
|
||||
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are incompatible with parameters. " + logSuffix);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Helpers
|
||||
//-------------------------------------------------------------------
|
||||
// Session Contexts for Repository Context and User Email Address.
|
||||
//-------------------------------------------------------------------
|
||||
[Obsolete("Deprecated - BusMgr databases only referenced via Control database rather than in application config.")]
|
||||
/// <summary>
|
||||
/// Identify the session context(s) that corresponds with the BusinessMgr
|
||||
/// repository by context for the specified user by email address.
|
||||
|
||||
@@ -40,6 +40,60 @@ namespace Sarand.BusinessMgr.Web.Portal.Models
|
||||
public bool UserCanCreateItem(Sbm.ItemType itemType) { return SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(itemType); }
|
||||
public bool UserCanUpdateItem(Sbm.ItemType itemType) { return SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(itemType); }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Page menu options.
|
||||
|
||||
public class MenuOptionData
|
||||
{
|
||||
public String Caption { get; set; }
|
||||
public String Page { get; set; }
|
||||
}
|
||||
public class MenuItemData
|
||||
{
|
||||
public String Caption { get; set; }
|
||||
public List<MenuOptionData> Options { get; } = new List<MenuOptionData>();
|
||||
}
|
||||
public class MenuData
|
||||
{
|
||||
public List<MenuItemData> Items { get; } = new List<MenuItemData>();
|
||||
}
|
||||
public MenuData Menu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Populate available menu options for the page.
|
||||
/// <para>- Invoked from SbmController_Portal.OnActionExecuting.</para>
|
||||
/// </summary>
|
||||
public void PopulateMenu()
|
||||
{
|
||||
Menu = new MenuData();
|
||||
|
||||
// Contacts.
|
||||
MenuItemData contactsItem = new MenuItemData() { Caption = @Localiser["label.contacts"] };
|
||||
contactsItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.contacts"], Page = "Contacts" });
|
||||
contactsItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.customers"], Page = "Customers" });
|
||||
contactsItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.suppliers"], Page = "Suppliers" });
|
||||
contactsItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.associations"], Page = "Associations" });
|
||||
if (contactsItem.Options.Any())
|
||||
Menu.Items.Add(contactsItem);
|
||||
|
||||
// Commodities.
|
||||
MenuItemData commoditiesItem = new MenuItemData() { Caption = @Localiser["label.commodities"] };
|
||||
commoditiesItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.commodities"], Page = "Commodity" });
|
||||
commoditiesItem.Options.Add(new MenuOptionData() { Caption = @Localiser["caption.asset.categories"], Page = "Assets/AssetCategory" });
|
||||
commoditiesItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.assets"], Page = "Assets/Asset" });
|
||||
commoditiesItem.Options.Add(new MenuOptionData() { Caption = @Localiser["caption.vehicle.classes"], Page = "Assets/VehicleClass" });
|
||||
commoditiesItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.vehicles"], Page = "Assets/Vehicle" });
|
||||
if (commoditiesItem.Options.Any())
|
||||
Menu.Items.Add(commoditiesItem);
|
||||
|
||||
// Reference.
|
||||
MenuItemData referenceItem = new MenuItemData() { Caption = @Localiser["label.reference"] };
|
||||
referenceItem.Options.Add(new MenuOptionData() { Caption = @Localiser["caption.code.types"], Page = "Codes/CodeType" });
|
||||
referenceItem.Options.Add(new MenuOptionData() { Caption = @Localiser["label.codes"], Page = "Codes/Code" });
|
||||
if (referenceItem.Options.Any())
|
||||
Menu.Items.Add(referenceItem);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// View reference data.
|
||||
|
||||
|
||||
@@ -40,13 +40,6 @@
|
||||
@* Filter Panel *@
|
||||
<div class="sbm-panel-filter">
|
||||
<div class="row">
|
||||
<div class="col-sm-4 row pb4">
|
||||
@* Commodity filter - code, description etc *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||
<div class="col-7 col-sm-8">
|
||||
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterCommodity sbm-input", @maxlength = "32" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
@* Commodity Category *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
@@ -54,6 +47,13 @@
|
||||
@Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
@* Commodity filter - code, description etc *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||
<div class="col-7 col-sm-8">
|
||||
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -119,38 +119,20 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
@Localiser["label.contacts"]
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Contact');">@Localiser["label.contacts"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Customers');">@Localiser["label.customers"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Suppliers');">@Localiser["label.suppliers"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Association');">@Localiser["label.associations"]</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
@Localiser["label.commodities"]
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Commodity');">@Localiser["label.commodities"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Assets/AssetCategory');">@Localiser["caption.asset.categories"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Assets/Asset');">@Localiser["label.assets"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Assets/VehicleClass');">@Localiser["caption.vehicle.classes"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Assets/Vehicle');">@Localiser["label.vehicles"]</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
@Localiser["label.reference"]
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Codes/CodeType');">@Localiser["caption.code.types"]</div>
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Codes/Code');">@Localiser["label.codes"]</div>
|
||||
</div>
|
||||
</li>
|
||||
@foreach (var menuItem in Model.Menu.Items)
|
||||
{
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
@(menuItem.Caption)
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
@foreach (var menuOption in menuItem.Options)
|
||||
{
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('@(menuOption.Page)');">@(menuOption.Caption)</div>
|
||||
}
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
@Localiser["label.security"]
|
||||
|
||||
@@ -8,38 +8,6 @@
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
"BusMgrDatabases": [
|
||||
{
|
||||
"Identifiers": [ "Sarand" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Sarand_Dev",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
{
|
||||
"Identifiers": [ "Cadix" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_Cadix",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
{
|
||||
"Identifiers": [ "BPE" ],
|
||||
"Location": "MsSql:Roman\\SQL2016.SaBusinessMgr_BPE",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
{
|
||||
"Identifiers": [ "MIMO" ],
|
||||
"Location": "MsSql:.\\SQL2016.SaBusinessMgr_Mimo",
|
||||
"User": "sapphire",
|
||||
"Password": "sarand"
|
||||
},
|
||||
{
|
||||
"Identifiers": [ "Firtree-X" ],
|
||||
"Location": "MsSql:Sarand110\\SQL2016.SaBusinessMgr_Firtree",
|
||||
"User": "firtree",
|
||||
"Password": "sarand"
|
||||
}
|
||||
],
|
||||
"Email": {
|
||||
"Context": "SBM-Dev",
|
||||
"ContactUs": {
|
||||
|
||||
@@ -183,7 +183,8 @@
|
||||
co.storeItem = function (env)
|
||||
{
|
||||
env.ajax.storeItem = env.ajax.storeItem || {
|
||||
url: sbm.url.base + 'Commodity/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { co.onStoreItem(env, response); } };
|
||||
url: sbm.url.base + 'Commodity/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { co.onStoreItem(env, response); }
|
||||
};
|
||||
sbm.doAjaxRequest(env.ajax.storeItem, 50);
|
||||
}
|
||||
co.onStoreItem = function (env, response)
|
||||
@@ -268,7 +269,7 @@
|
||||
env.$pnl.tmpls = env.$pnl.items.find('.sbm-panel-item-template');
|
||||
|
||||
env.$frm.filter = $('#frmCommodityFilter');
|
||||
env.$frm.filter.on('input', '.FilterSearch', function () { co.refreshResults(250); }).on('change', '.FilterCommodityType,.FilterStatusCat', function () { co.refreshResults(50); });
|
||||
env.$frm.filter.on('input', '.FilterSearch', function () { co.refreshResults(env, 250); }).on('change', '.FilterCommodityType,.FilterStatusCat', function () { co.refreshResults(env, 50); });
|
||||
var opt = sbm.dlgOpts();
|
||||
opt.dialogClass += " sbm-Commodity";
|
||||
env.$dlg.item = $('#dlgCommodity').dialog(opt);
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
}
|
||||
sbm.clearItemForm = function ($frm)
|
||||
{
|
||||
//sbm.clearControlErrors($frm);
|
||||
sbm.clearControlErrors($frm);
|
||||
$('.sbm-input,.sbm-textarea,.sbm-select', $frm).val('').prop('readonly', false).prop('disabled', false);
|
||||
$('.sbm-checkbox', $frm).prop('readonly', false).prop('disabled', false).removeAttr('checked');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user