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 ControlDatabase { get; private set; }
|
||||||
public DatabaseConfig TemplateDatabase { get; private set; }
|
public DatabaseConfig TemplateDatabase { get; private set; }
|
||||||
public List<DatabaseConfig> BusMgrDatabases { get; } = new List<DatabaseConfig>();
|
|
||||||
// Documents.
|
// Documents.
|
||||||
public class DocumentsConfig
|
public class DocumentsConfig
|
||||||
{
|
{
|
||||||
@@ -211,18 +210,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.App
|
|||||||
ExtractDatabaseConfig(TemplateDatabase, templateDatabaseSection);
|
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.
|
// Variants.
|
||||||
foreach (ConfigurationSection variantSection in configSection.GetSection("Variants").GetChildren())
|
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("Configuration", SbmSystem.DebugMode ? "Debug" : "Release");
|
||||||
applicationParams.Add("Environment", EnvironmentName);
|
applicationParams.Add("Environment", EnvironmentName);
|
||||||
applicationParams.Add("Control database", AppConfig.ControlDatabase.Location);
|
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);
|
applicationParams.Add("Application root", SbmSystem.ApplicationFolder);
|
||||||
if (!StringUtil.IsEmpty(AppConfig.Documents.RootFolder))
|
if (!StringUtil.IsEmpty(AppConfig.Documents.RootFolder))
|
||||||
applicationParams.Add("Documents root", AppConfig.Documents.RootFolder);
|
applicationParams.Add("Documents root", AppConfig.Documents.RootFolder);
|
||||||
|
|||||||
@@ -117,8 +117,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Model.
|
// Model.
|
||||||
//-------------------------------------------------------------------
|
protected virtual void RefreshModel(SbmModel_Base model)
|
||||||
protected void RefreshModel(SbmModel_Base model)
|
|
||||||
{
|
{
|
||||||
if (model == null) return;
|
if (model == null) return;
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
|
|||||||
ProspectGroup,
|
ProspectGroup,
|
||||||
// Associated data.
|
// Associated data.
|
||||||
GroupMembers,
|
GroupMembers,
|
||||||
Association_Count,
|
AssociationOwner_Count,
|
||||||
|
AssociationTarget_Count,
|
||||||
// Common properties.
|
// Common properties.
|
||||||
Notes,
|
Notes,
|
||||||
Flag,
|
Flag,
|
||||||
|
|||||||
@@ -366,7 +366,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|||||||
private static readonly String aliasAffiliate_AddPrim = "Aff_AddPrim";
|
private static readonly String aliasAffiliate_AddPrim = "Aff_AddPrim";
|
||||||
private static readonly String prefixAffiliate_AddPrim = aliasAffiliate_AddPrim + "_";
|
private static readonly String prefixAffiliate_AddPrim = aliasAffiliate_AddPrim + "_";
|
||||||
private static readonly String colNameAffiliate_GroupMembers = "GroupMembers";
|
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.
|
// Column definition population.
|
||||||
private void SetAffiliateColDfn
|
private void SetAffiliateColDfn
|
||||||
@@ -499,9 +500,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
|
|||||||
SetAffiliateColDfn(columnDfn, "Members", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
SetAffiliateColDfn(columnDfn, "Members", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
||||||
columnDfn.DataName = colNameAffiliate_GroupMembers;
|
columnDfn.DataName = colNameAffiliate_GroupMembers;
|
||||||
break;
|
break;
|
||||||
case SbmAffiliate.Column.Association_Count:
|
case SbmAffiliate.Column.AssociationOwner_Count:
|
||||||
SetAffiliateColDfn(columnDfn, "Associations", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
SetAffiliateColDfn(columnDfn, "Owner Assocs", 90, SbmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right);
|
||||||
columnDfn.DataName = colNameAffiliate_AssociationCount;
|
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;
|
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.
|
// Count active associations.
|
||||||
String aliasAffiliate_Associations = "AffAssocs";
|
String aliasAffiliate_Associations_Owner = "AffAssOwner";
|
||||||
DbQuery qryAssocs = new DbQuery(db.DbmsType);
|
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.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_AffIdOwner, aliasAffiliate_Associations_Owner)}={SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasAffiliate)}");
|
||||||
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Status, aliasAffiliate_Associations)}='{StatusCurrent}'");
|
qryAssocs.Filters.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Type, aliasAffiliate_Associations_Owner)}!={(int)Sbm.AssociationType.Internal}");
|
||||||
query.Columns.Add("(" + qryAssocs.BuildQuery() + ")", colNameAffiliate_AssociationCount);
|
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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Sarand.BusinessMgr.Net.Core.Web.Consoles;
|
||||||
using Sarand.Net.Standard.Base.App;
|
using Sarand.Net.Standard.Base.App;
|
||||||
using Sarand.Net.Standard.Base.Dbas;
|
using Sarand.Net.Standard.Base.Dbas;
|
||||||
using Sarand.Net.Standard.Base.Helpers;
|
using Sarand.Net.Standard.Base.Helpers;
|
||||||
|
using Sarand.Net.Standard.Base.Security;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -19,12 +21,16 @@ namespace Sarand.BusinessMgr.Test.Web.Portal.App
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Test_PasswordEncoding()
|
public void Test_PasswordEncoding()
|
||||||
{
|
{
|
||||||
|
using (SbmSecurityConsole_Web securityConsole = new SbmSecurityConsole_Web(UserContext))
|
||||||
|
{
|
||||||
|
|
||||||
Assert.IsNotNull(BusMgrDatabase);
|
Assert.IsNotNull(BusMgrDatabase);
|
||||||
StringAssert.Matches(BusMgrDatabase.EncodePassword_Hex(""), reHex);
|
StringAssert.Matches(securityConsole.EncodePassword_Hex(""), reHex);
|
||||||
|
|
||||||
// Iterate using random filename (8.3).
|
// Iterate using random filename (8.3).
|
||||||
for (int i = 0; i < 1000; i++)
|
for (int i = 0; i < 1000; i++)
|
||||||
StringAssert.Matches(BusMgrDatabase.EncodePassword_Hex(Path.GetRandomFileName()), reHex);
|
StringAssert.Matches(securityConsole.EncodePassword_Hex(Path.GetRandomFileName()), reHex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
@@ -34,11 +40,14 @@ namespace Sarand.BusinessMgr.Test.Web.Portal.App
|
|||||||
Assert.IsNotNull(BusMgrDatabase);
|
Assert.IsNotNull(BusMgrDatabase);
|
||||||
Dictionary<string, string> passwordHashes = new Dictionary<string, string>();
|
Dictionary<string, string> passwordHashes = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
using (SbmSecurityConsole_Web securityConsole = new SbmSecurityConsole_Web(UserContext))
|
||||||
|
{
|
||||||
|
|
||||||
// Iterate using random filename (8.3).
|
// Iterate using random filename (8.3).
|
||||||
for (int i = 0; i < 200; i++)
|
for (int i = 0; i < 200; i++)
|
||||||
{
|
{
|
||||||
string password = Path.GetRandomFileName();
|
string password = Path.GetRandomFileName();
|
||||||
string passwordHash = BusMgrDatabase.EncodePassword_Hex(password);
|
string passwordHash = securityConsole.EncodePassword_Hex(password);
|
||||||
StringAssert.Matches(passwordHash, reHex);
|
StringAssert.Matches(passwordHash, reHex);
|
||||||
passwordHashes.Add(password, passwordHash);
|
passwordHashes.Add(password, passwordHash);
|
||||||
}
|
}
|
||||||
@@ -46,7 +55,8 @@ namespace Sarand.BusinessMgr.Test.Web.Portal.App
|
|||||||
{
|
{
|
||||||
string passwordHash = passwordHashes.GetValueOrDefault(password);
|
string passwordHash = passwordHashes.GetValueOrDefault(password);
|
||||||
StringAssert.Matches(passwordHash, reHex);
|
StringAssert.Matches(passwordHash, reHex);
|
||||||
Assert.IsTrue(BusMgrDatabase.ComparePassword_Hex(password, passwordHash));
|
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 ControlOwnerId { get; protected set; }
|
||||||
public SysId ControlRepositoryId { 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
|
private class SessionContextData_Control : SessionContextData
|
||||||
{
|
{
|
||||||
public SessionContextData_Control(SbmSessionContext_Web sessionContext, SysId controlOwnerId, SysId controlRepositoryId) : base(sessionContext)
|
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);
|
controlDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
|
||||||
if (controlDatabase.HasErrorState())
|
if (controlDatabase.HasErrorState())
|
||||||
SaLogger.Warn($"{SysUtil.Fn} Control Database initialisation error: " + controlDatabase.ErrorStateMessage);
|
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)
|
catch (Exception exc)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Consoles
|
|||||||
{
|
{
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Data members.
|
// Data members.
|
||||||
private SaUpdateLogConsole updateLogConsole;
|
//private SaUpdateLogConsole updateLogConsole;
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Construction.
|
// Construction.
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
[Route("Commodity")]
|
||||||
|
[Route("Commodities")]
|
||||||
public IActionResult Index(Model_Commodity model)
|
public IActionResult Index(Model_Commodity model)
|
||||||
{
|
{
|
||||||
if (!ValidUserSession)
|
if (!ValidUserSession)
|
||||||
|
|||||||
@@ -234,7 +234,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
|||||||
ColumnDfn colPhoneMobile = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneMobile);
|
ColumnDfn colPhoneMobile = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneMobile);
|
||||||
ColumnDfn colPhoneDirect = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneDirect);
|
ColumnDfn colPhoneDirect = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneDirect);
|
||||||
ColumnDfn colEmail = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Email);
|
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 colNotes = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Notes);
|
||||||
ColumnDfn colStatus = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Status);
|
ColumnDfn colStatus = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Status);
|
||||||
ColumnDfn colCreatedOn = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.CreateOn_Date);
|
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>()
|
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||||
{
|
{
|
||||||
colId, colName, colAffiliateType,
|
colId, colName, colAffiliateType,
|
||||||
colAddress, colContact, colPhoneMain, colPhoneAlt, colPhoneMobile, colPhoneDirect, colEmail, colAssocCount,
|
colAddress, colContact, colPhoneMain, colPhoneAlt, colPhoneMobile, colPhoneDirect, colEmail, colAssocOwnerCount, colAssocTargetCount,
|
||||||
colNotes, colStatus, colCreatedOn, colUpdatedOn
|
colNotes, colStatus, colCreatedOn, colUpdatedOn
|
||||||
};
|
};
|
||||||
if (responseData.Config.Column.Hide.Contains($"{Model_Contact.ItemField.Address}"))
|
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}"))
|
if (responseData.Config.Column.Hide.Contains($"{Model_Contact.ItemField.Email}"))
|
||||||
columns.Remove(colEmail);
|
columns.Remove(colEmail);
|
||||||
if (responseData.Config.Column.Hide.Contains($"{Model_Contact.ItemField.Associations}"))
|
if (responseData.Config.Column.Hide.Contains($"{Model_Contact.ItemField.Associations}"))
|
||||||
columns.Remove(colAssocCount);
|
columns.Remove(colAssocOwnerCount);
|
||||||
|
|
||||||
// Sort Columns.
|
// Sort Columns.
|
||||||
if (!prmAffiliate.SortColumns.Any())
|
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.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.CreatedOn}", Localiser.FormatDate(values.GetDate(colCreatedOn.DataName)));
|
||||||
affiliateData.Field.Value.Add($"{Model_Contact.ItemField.UpdatedOn}", Localiser.FormatDate(values.GetDate(colUpdatedOn.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)
|
if (assocCount > 0)
|
||||||
affiliateData.AssociationCount = assocCount;
|
affiliateData.AssociationCount = assocCount;
|
||||||
// Cleanse item values.
|
// Cleanse item values.
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
|||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
[Route("Contact")]
|
||||||
|
[Route("Contacts")]
|
||||||
public IActionResult Index(Model_Contact model)
|
public IActionResult Index(Model_Contact model)
|
||||||
{
|
{
|
||||||
if (!ValidUserSession)
|
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.Standard.Base.Bus.Control;
|
||||||
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||||
using Sarand.BusinessMgr.Web.Portal.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
|
namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||||
{
|
{
|
||||||
@@ -218,6 +222,26 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
|||||||
base.OnActionExecuted(filterContext);
|
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.
|
// Keep Logged In.
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
@@ -238,12 +262,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
|||||||
String logSuffix = keepLoggedInParams.GetValidParams().Concat("", " ", ".");
|
String logSuffix = keepLoggedInParams.GetValidParams().Concat("", " ", ".");
|
||||||
if (keepLoggedInParams.IsValid())
|
if (keepLoggedInParams.IsValid())
|
||||||
{
|
{
|
||||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
// Instance Repository configured on Control database identified by Context.
|
||||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(keepLoggedInParams.RepositoryContext);
|
||||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(keepLoggedInParams.RepositoryContext, keepLoggedInParams.EmailAddress);
|
if (sessionContext != null)
|
||||||
if (sessionContexts.Any())
|
|
||||||
{
|
|
||||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
|
||||||
{
|
{
|
||||||
// Consoles and Managers must be associated with the specific context.
|
// Consoles and Managers must be associated with the specific context.
|
||||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||||
@@ -277,9 +298,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
|||||||
else SaLogger.Warn(logPrefix + "Security Item or Affiliate not found. " + 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);
|
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.
|
// Instance Repository configured on Control database.
|
||||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(model.RepositoryContext);
|
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(model.RepositoryContext);
|
||||||
String errorMessage = "";
|
String errorMessage = "";
|
||||||
|
|
||||||
if (!OpenUserSession(model, sessionContext, ref errorMessage))
|
if (!OpenUserSession(model, sessionContext, ref errorMessage))
|
||||||
{
|
{
|
||||||
if (!StringUtil.IsBlank(errorMessage))
|
if (!StringUtil.IsBlank(errorMessage))
|
||||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), 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))
|
if (!(SessionData_Portal?.ValidUser ?? false))
|
||||||
@@ -125,14 +107,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
|||||||
disposables.Add(accountMgrForUser);
|
disposables.Add(accountMgrForUser);
|
||||||
|
|
||||||
// User's security item.
|
// User's security item.
|
||||||
SaSecurityItem securityItemUser = GetSecurityItemForSignin(securityConsoleForUser, model);
|
SaSecurityItem securityItemUser = GetSecurityItemForSignin(userContext, securityConsoleForUser, model);
|
||||||
disposables.Add(securityItemUser);
|
disposables.Add(securityItemUser);
|
||||||
if (securityItemUser == null)
|
if (securityItemUser == null)
|
||||||
{
|
{
|
||||||
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve Security Item. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}.");
|
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve Security Item. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}.");
|
||||||
return false;
|
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}.");
|
SaLogger.Warn($"{SysUtil.Fn} Supplied password doesn't match Security Item. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}.");
|
||||||
return false;
|
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.
|
// Retrieve security item by email address.
|
||||||
SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress);
|
SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress);
|
||||||
@@ -198,7 +180,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
|||||||
// Record invalid login attempt.
|
// Record invalid login attempt.
|
||||||
securityItemUser.InvalidLoginCount++;
|
securityItemUser.InvalidLoginCount++;
|
||||||
securityItemUser.LastInvalidLoginAt = DateTime.Now;
|
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} 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);
|
SaLogger.Warn($"{SysUtil.Fn} Attempt to sign-in to User {model.EmailAddress} with invalid password. Attempt: {securityItemUser.InvalidLoginCount}.", true);
|
||||||
securityItemUser.Dispose(); securityItemUser = null;
|
securityItemUser.Dispose(); securityItemUser = null;
|
||||||
@@ -410,15 +392,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
|||||||
RequestPasswordParams storePasswordParams = ExtractRequestPasswordLinkParams(model.rpe);
|
RequestPasswordParams storePasswordParams = ExtractRequestPasswordLinkParams(model.rpe);
|
||||||
if (storePasswordParams.IsValid())
|
if (storePasswordParams.IsValid())
|
||||||
{
|
{
|
||||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
// Instance Repository configured on Control database identified by Context.
|
||||||
// Identify session contexts for databases with specified Id that hosts the specified email address.
|
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(storePasswordParams.RepositoryContext);
|
||||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(storePasswordParams.RepositoryContext, storePasswordParams.EmailAddress);
|
if (sessionContext != null)
|
||||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
|
||||||
{
|
{
|
||||||
// Consoles and Managers must be associated with the specific context.
|
// Consoles and Managers must be associated with the specific context.
|
||||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||||
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContextForUser))
|
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContextForUser))
|
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||||
{
|
{
|
||||||
// Retrieve user details and validate email address.
|
// Retrieve user details and validate email address.
|
||||||
securityItemUser = securityConsoleForUser.GetSecurityItemById(SaSecurity.ItemType.User, storePasswordParams.SecurityItemId);
|
securityItemUser = securityConsoleForUser.GetSecurityItemById(SaSecurity.ItemType.User, storePasswordParams.SecurityItemId);
|
||||||
@@ -429,7 +410,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
|||||||
userContextForUser = userContext;
|
userContextForUser = userContext;
|
||||||
validRequestPasswordParams = true;
|
validRequestPasswordParams = true;
|
||||||
validSessionRequired = false;
|
validSessionRequired = false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -471,7 +451,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
|||||||
String oldPasswordHashed = securityItemUser.PasswordHash;
|
String oldPasswordHashed = securityItemUser.PasswordHash;
|
||||||
|
|
||||||
// Store password.
|
// 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;
|
securityItemUser.PasswordChangedAt = DateTime.Now;
|
||||||
// Remove new password from history if present.
|
// Remove new password from history if present.
|
||||||
for (int passwordHistoryIdx = 0; passwordHistoryIdx < securityItemUser.PasswordHistory.Count; passwordHistoryIdx++)
|
for (int passwordHistoryIdx = 0; passwordHistoryIdx < securityItemUser.PasswordHistory.Count; passwordHistoryIdx++)
|
||||||
@@ -489,7 +470,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
|||||||
securityItemUser.PasswordHistory.Add(oldPasswordHashed);
|
securityItemUser.PasswordHistory.Add(oldPasswordHashed);
|
||||||
while (securityItemUser.PasswordHistory.Count > 10)
|
while (securityItemUser.PasswordHistory.Count > 10)
|
||||||
securityItemUser.PasswordHistory.RemoveAt(securityItemUser.PasswordHistory.Count - 1);
|
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}");
|
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"]));
|
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);
|
model.ValidateRequestPasswordData(responseData);
|
||||||
if (responseData.HasControlErrors()) return Json(responseData);
|
if (responseData.HasControlErrors()) return Json(responseData);
|
||||||
|
|
||||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
// Instance Repository configured on Control database identified by Context.
|
||||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(model.RepositoryContext, model.EmailAddress);
|
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(model.RepositoryContext);
|
||||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
if (sessionContext != null)
|
||||||
{
|
{
|
||||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
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 logPrefix = $"{SysUtil.Fn} 'Request Password' parameters supplied but ";
|
||||||
String logSuffix = changePasswordParams.GetValidParams().Concat("", " ", ".");
|
String logSuffix = changePasswordParams.GetValidParams().Concat("", " ", ".");
|
||||||
// User may be defined on any one of the BusinessMgr databases - need to find out which.
|
// Instance Repository configured on Control database identified by Context.
|
||||||
// Identify session contexts with a BusMgr database that hosts the specified email address.
|
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(changePasswordParams.RepositoryContext);
|
||||||
List<SbmSessionContext> sessionContexts = SbmSessionContextHelper_Portal.GetSessionContextForRepositoryContextUserEmail(changePasswordParams.RepositoryContext, changePasswordParams.EmailAddress);
|
if (sessionContext != null)
|
||||||
foreach (SbmSessionContext sessionContext in sessionContexts)
|
|
||||||
{
|
{
|
||||||
// Consoles and Managers must be associated with the specific context.
|
// Consoles and Managers must be associated with the specific context.
|
||||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||||
@@ -99,7 +98,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
|||||||
{
|
{
|
||||||
model.rpe = encryptedParams;
|
model.rpe = encryptedParams;
|
||||||
validSessionRequired = false;
|
validSessionRequired = false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else SaLogger.Warn(logPrefix + "Security Item and Affiliate are incompatible with parameters. " + logSuffix);
|
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.
|
// Session Contexts for Repository Context and User Email Address.
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
[Obsolete("Deprecated - BusMgr databases only referenced via Control database rather than in application config.")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Identify the session context(s) that corresponds with the BusinessMgr
|
/// Identify the session context(s) that corresponds with the BusinessMgr
|
||||||
/// repository by context for the specified user by email address.
|
/// 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 UserCanCreateItem(Sbm.ItemType itemType) { return SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(itemType); }
|
||||||
public bool UserCanUpdateItem(Sbm.ItemType itemType) { return SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(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.
|
// View reference data.
|
||||||
|
|
||||||
|
|||||||
@@ -40,13 +40,6 @@
|
|||||||
@* Filter Panel *@
|
@* Filter Panel *@
|
||||||
<div class="sbm-panel-filter">
|
<div class="sbm-panel-filter">
|
||||||
<div class="row">
|
<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">
|
<div class="col-sm-4 row pb4">
|
||||||
@* Commodity Category *@
|
@* Commodity Category *@
|
||||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
<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" })
|
@Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
|
||||||
</div>
|
</div>
|
||||||
</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 class="col-sm-4 row pb4">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -118,39 +118,21 @@
|
|||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
@foreach (var menuItem in Model.Menu.Items)
|
||||||
{
|
{
|
||||||
<li class="nav-item dropdown">
|
<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">
|
<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"]
|
@(menuItem.Caption)
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Contact');">@Localiser["label.contacts"]</div>
|
@foreach (var menuOption in menuItem.Options)
|
||||||
<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('@(menuOption.Page)');">@(menuOption.Caption)</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>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
}
|
||||||
<li class="nav-item dropdown">
|
<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">
|
<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"]
|
@Localiser["label.security"]
|
||||||
|
|||||||
@@ -8,38 +8,6 @@
|
|||||||
"User": "sapphire",
|
"User": "sapphire",
|
||||||
"Password": "sarand"
|
"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": {
|
"Email": {
|
||||||
"Context": "SBM-Dev",
|
"Context": "SBM-Dev",
|
||||||
"ContactUs": {
|
"ContactUs": {
|
||||||
|
|||||||
@@ -183,7 +183,8 @@
|
|||||||
co.storeItem = function (env)
|
co.storeItem = function (env)
|
||||||
{
|
{
|
||||||
env.ajax.storeItem = env.ajax.storeItem || {
|
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);
|
sbm.doAjaxRequest(env.ajax.storeItem, 50);
|
||||||
}
|
}
|
||||||
co.onStoreItem = function (env, response)
|
co.onStoreItem = function (env, response)
|
||||||
@@ -268,7 +269,7 @@
|
|||||||
env.$pnl.tmpls = env.$pnl.items.find('.sbm-panel-item-template');
|
env.$pnl.tmpls = env.$pnl.items.find('.sbm-panel-item-template');
|
||||||
|
|
||||||
env.$frm.filter = $('#frmCommodityFilter');
|
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();
|
var opt = sbm.dlgOpts();
|
||||||
opt.dialogClass += " sbm-Commodity";
|
opt.dialogClass += " sbm-Commodity";
|
||||||
env.$dlg.item = $('#dlgCommodity').dialog(opt);
|
env.$dlg.item = $('#dlgCommodity').dialog(opt);
|
||||||
|
|||||||
@@ -169,7 +169,7 @@
|
|||||||
}
|
}
|
||||||
sbm.clearItemForm = function ($frm)
|
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-input,.sbm-textarea,.sbm-select', $frm).val('').prop('readonly', false).prop('disabled', false);
|
||||||
$('.sbm-checkbox', $frm).prop('readonly', false).prop('disabled', false).removeAttr('checked');
|
$('.sbm-checkbox', $frm).prop('readonly', false).prop('disabled', false).removeAttr('checked');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user