Control - Repository initialisation.

This commit is contained in:
Andy Howard
2025-01-09 16:30:52 +00:00
parent d015470f58
commit 4a72043f00
103 changed files with 4324 additions and 469 deletions
@@ -6,12 +6,14 @@ using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Text; using System.Drawing.Text;
using System.Linq; using System.Linq;
using System.Runtime.Versioning;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Sarand.BusinessMgr.Net.Core.Procs.Reports namespace Sarand.BusinessMgr.Net.Core.Procs.Reports
{ {
//========================================================================== //==========================================================================
[SupportedOSPlatform("windows")]
public class SbmPrinter_Footer : SacsDisposable public class SbmPrinter_Footer : SacsDisposable
{ {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@@ -17,10 +17,12 @@ using System.Threading.Tasks;
using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Core;
using System.Runtime.Versioning;
namespace Sarand.BusinessMgr.Net.Core.Procs.Reports namespace Sarand.BusinessMgr.Net.Core.Procs.Reports
{ {
//======================================================================= //=======================================================================
[SupportedOSPlatform("windows")]
public abstract class SbmReport : SbmReport_Base public abstract class SbmReport : SbmReport_Base
{ {
//------------------------------------------------------------------- //-------------------------------------------------------------------
+1 -1
View File
@@ -17,7 +17,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="9.0.0" /> <PackageReference Include="System.Drawing.Common" Version="6.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+1 -1
View File
@@ -6,7 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.31" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.36" />
<PackageReference Include="System.Data.Odbc" Version="6.0.2" /> <PackageReference Include="System.Data.Odbc" Version="6.0.2" />
</ItemGroup> </ItemGroup>
@@ -1,6 +1,4 @@
using DocumentFormat.OpenXml.Drawing.Diagrams; using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control;
using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.App;
@@ -9,15 +7,12 @@ using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Sarand.BusinessMgr.Web.Portal.App namespace Sarand.BusinessMgr.Net.Core.Web.App
{ {
//======================================================================= //=======================================================================
public class SbmInstanceConfig_Portal : SbmInstanceConfig public class SbmInstanceConfig_Control : SbmInstanceConfig
{ {
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Definitions. // Definitions.
@@ -33,7 +28,7 @@ namespace Sarand.BusinessMgr.Web.Portal.App
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Construction. // Construction.
public SbmInstanceConfig_Portal(SysId controlOwnerId, SysId controlRepositoryId) public SbmInstanceConfig_Control(SysId controlOwnerId, SysId controlRepositoryId)
{ {
this.controlOwnerId = controlOwnerId; this.controlOwnerId = controlOwnerId;
this.controlRepositoryId = controlRepositoryId; this.controlRepositoryId = controlRepositoryId;
@@ -68,8 +68,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Controllers
public abstract SbmSessionContext SessionContext { get; } public abstract SbmSessionContext SessionContext { get; }
public abstract ISbmUserContext_Core UserContext_Core { get; } public abstract ISbmUserContext_Core UserContext_Core { get; }
// Business components. // Business components.
public SbmInternals Internals { get { if (internals == null) internals = new SbmInternals(UserContext_Core); return internals; } } public SbmInternals Internals { get { if (internals == null && UserContext_Core != null) { internals = new SbmInternals(UserContext_Core); } return internals; } }
public SbmInternals_Control Internals_Control { get { if (internals_Control == null) internals_Control = new SbmInternals_Control(); return internals_Control; } } public SbmInternals_Control Internals_Control { get { if (internals_Control == null) { internals_Control = new SbmInternals_Control(); } return internals_Control; } }
// Managers. // Managers.
public SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } } public SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } }
public SbmAssetMgr AssetMgr { get { return Internals.AssetMgr; } } public SbmAssetMgr AssetMgr { get { return Internals.AssetMgr; } }
+2
View File
@@ -18,6 +18,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
{ {
public static class Password public static class Password
{ {
public static int MinLength { get; } = 8;
public static int MaxLength { get; } = 16;
} }
public static class Activation public static class Activation
{ {
@@ -121,6 +121,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.App
public List<TypeCodeDesc> AssociationTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.AssociationType); } } public List<TypeCodeDesc> AssociationTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.AssociationType); } }
public List<TypeCodeDesc> CommodityTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.CommodityType); } } public List<TypeCodeDesc> CommodityTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.CommodityType); } }
public List<TypeCodeDesc> AssetTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.AssetType); } } public List<TypeCodeDesc> AssetTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.AssetType); } }
public List<TypeCodeDesc> TransactionTypeCodes { get { return GetCodesOfType(Sbm.SystemCode.TransactionType); } }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Code types. // Code types.
@@ -782,6 +782,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
public String Search { get; set; } public String Search { get; set; }
public String Name { get; set; } public String Name { get; set; }
public String NamePartial { get; set; } public String NamePartial { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String PhonePartial { get; set; } public String PhonePartial { get; set; }
public String EmailPartial { get; set; } public String EmailPartial { get; set; }
public String PostcodePartial { get; set; } public String PostcodePartial { get; set; }
@@ -742,6 +742,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Utilities. // Utilities.
public ItemId GetItemId()
{
return new ItemId((short)Sbm.ItemType.Requirement, Id);
}
public String GetPromotionCodeNONE() public String GetPromotionCodeNONE()
{ {
return "None"; return "None";
+27 -15
View File
@@ -661,7 +661,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Transaction status. // Transaction status.
public static SaStatus DefaultStatus { get { return SaStatus.Preparation; } } public static SaStatus DefaultStatus { get { return SaStatus.Preparation; } }
private static readonly List<SaStatus> transactionStatuses = new List<SaStatus>() private static readonly HashSet<SaStatus> transactionStatuses = new HashSet<SaStatus>()
{ {
SaStatus.Preparation, SaStatus.Preparation,
SaStatus.Active, SaStatus.Active,
@@ -679,7 +679,11 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
{ {
return DefaultStatus; return DefaultStatus;
} }
public static List<SaStatus> GetTransactionStatuses(Sbm.TransactionType transactionType) public static List<SaStatus> ValidStatuses()
{
return new List<SaStatus>(transactionStatuses);
}
public static List<SaStatus> ValidStatusesByType(Sbm.TransactionType transactionType)
{ {
switch (transactionType) switch (transactionType)
{ {
@@ -822,6 +826,12 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Utilities. // Utilities.
public ItemId GetItemId()
{
return new ItemId((short)Sbm.ItemType.Transaction, Id);
}
// Transaction type.
public List<Sbm.AssociationType> GetAssociationTypes() public List<Sbm.AssociationType> GetAssociationTypes()
{ {
return GetAssociationTypes(TransactionType); return GetAssociationTypes(TransactionType);
@@ -1646,21 +1656,22 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
public new class Params : SacsHierarchyItem.Params public new class Params : SacsHierarchyItem.Params
{ {
// List filtering. // List filtering.
public List<SysId> IdsIncluded { get; set; } = new List<SysId>(); public HashSet<SysId> IdsIncluded { get; set; } = new HashSet<SysId>();
public List<SysId> IdsExcluded { get; set; } = new List<SysId>(); public HashSet<SysId> IdsExcluded { get; set; } = new HashSet<SysId>();
// Transaction. // Transaction.
public SysId AssocId { get; set; } public String Search { get; set; }
public SysId TransIdSource { get; set; } public SysId AssociationId { get; set; }
public Sbm.TransactionType TransactionType { get; set; } = Sbm.TransactionType.Any; public Sbm.TransactionType TransactionType { get; set; } = Sbm.TransactionType.Any;
public SysId LocationIdStock { get; set; }
public String AssocPartial { get; set; }
public String AddressPartial { get; set; }
public String PostcodePartial { get; set; }
public String TransRefFull { get; set; } public String TransRefFull { get; set; }
public String TransRefPartial { get; set; } public String TransRefPartial { get; set; }
public String TransRefExtFull { get; set; } public String TransRefExtFull { get; set; }
public String TransRefExtPartial { get; set; } public String TransRefExtPartial { get; set; }
public String TransDescBriefPartial { get; set; } public String TransDescBriefPartial { get; set; }
public SysId TransIdSource { get; set; }
public SysId LocationIdStock { get; set; }
public String AddressPartial { get; set; }
public String PostcodePartial { get; set; }
public String AssocPartial { get; set; }
public String DefaultNominalCodeFull { get; set; } public String DefaultNominalCodeFull { get; set; }
public String DefaultNominalCodePartial { get; set; } public String DefaultNominalCodePartial { get; set; }
public String ContactAreaCode { get; set; } public String ContactAreaCode { get; set; }
@@ -1709,12 +1720,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Bus
public StatusCat StatusCat { get; set; } = StatusCat.Default; public StatusCat StatusCat { get; set; } = StatusCat.Default;
/// <summary>Results will be throttled unless a significant filter is applied.</summary> /// <summary>Results will be throttled unless a significant filter is applied.</summary>
public bool ForceFullResults { get; set; } = false; public bool ForceFullResults { get; set; } = false;
// Linked table alises.
public String TableAlias_Association { get; set; }
public String TableAlias_AffiliateOwner { get; set; }
public String TableAlias_AffiliateTarget { get; set; }
public String TableAlias_AddressTarget { get; set; }
public String TableAlias_AddressDelivery { get; set; }
// Utilities. // Utilities.
public List<StringPair> GetDisplayValues()
{
List<StringPair> values = new List<StringPair>();
return values;
}
public bool RequiresVolumeThrottle() public bool RequiresVolumeThrottle()
{ {
// The volume of transaction must be throttled if no 'significant' filter is requested. // The volume of transaction must be throttled if no 'significant' filter is requested.
@@ -0,0 +1,495 @@
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Security;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles
{
/// <summary>
/// Utilitiy function relating to a core BusinessMgr database instance.
/// <para>For instance:</para>
/// <para>- Initialisation of new repository.</para>
/// <para>- Bringing static (tax codes etc) and reference data up to date.</para>
/// </summary>
public abstract class SbmCoreInstanceConsole_Base : SaErrorStateItem
{
//-------------------------------------------------------------------
// Definitions.
public const String col_AffilId = "AffilId";
public const String col_AssocId = "AssocId";
public const String col_Name = "Name";
public const String col_Website = "Website";
public const String col_CompanyNo = "CompanyNo";
public const String col_VatReg = "VatReg";
public const String col_FirstName = "FirstName";
public const String col_LastName = "LastName";
public const String col_Email = "Email";
public const String col_UserId = "UserId";
public const String col_UserCode = "UserCode";
/// <summary>
/// Organisation and User info for Repository initialisation.
/// </summary>
public class RepositoryInitialisationData
{
public class UserData
{
public SysId AffiliateId { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Email { get; set; }
public SysId SecurityItemId { get; set; }
public String Code { get; set; }
public String Password { get; set; }
}
public UserData User { get; private set; } = new UserData();
public void ClearUser() { User = new UserData(); }
public class OrganisationData
{
public String Name { get; set; }
public String VatReg { get; set; }
public String CompanyNo { get; set; }
public String Website { get; set; }
public SysId AffiliateId { get; set; }
public SysId AssociationId { get; set; }
}
public OrganisationData Organisation { get; private set; } = new OrganisationData();
public void ClearOrganisation() { Organisation = new OrganisationData(); }
}
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
protected SbmCoreInstanceConsole_Base()
{
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
public String SecurityGroupCode_Super { get; } = SaSecurityConsole.GroupCode_Super;
// Core instance.
public abstract ISacsDatabase Database_Core { get; }
public abstract SbmInternals Internals_Core { get; }
public abstract DbUpdateInfo DbUpdateInfo_Core { get; }
//-------------------------------------------------------------------
// Utilities.
public abstract SaSecurityConsole CreateSecurityConsole();
//-------------------------------------------------------------------
/// <summary>
/// Is repository database valid.
/// <para>- Contains core tables (Affiliate, Association, Commodity etc).</para>
/// </summary>
/// <param name="database"></param>
/// <returns></returns>
public bool IsRepositoryValid()
{
ClearErrorState();
HashSet<String> tablesExpected = new HashSet<String>("Affiliate,Association,Commodity,Transaction,Requirement,SaSecItem,SaSecLink".Split(','));
String sql = $"Select {col_Name} From sys.tables";
try
{
using (DbResultSet resultSet = Database_Core.ExecuteQuery(sql))
{
if (resultSet != null)
{
HashSet<String> tablesFound = new HashSet<string>();
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
tablesFound.Add(values.GetString(col_Name));
}
HashSet<String> tablesNotFound = new HashSet<string>(tablesExpected.Where(item => !tablesFound.ContainsCI(item)));
if (tablesNotFound.Any())
return SetErrorState($"Core tables not found: {String.Join(", ", tablesNotFound)}.");
}
}
}
catch (Exception exc)
{
String msg = "checking repository validity";
SaLogger.Warn($"{SysUtil.Fn} {ExceptionUtil.GetLogMessage(exc, msg)}");
return SetErrorState($"{exc.GetType().Name} {msg}");
}
return OK;
}
//-------------------------------------------------------------------
/// <summary>
/// Is repository database initialised.
/// <para>- Has a valid internal association.</para>
/// <para>- Has at least one user.</para>
/// </summary>
public bool IsRepositoryInitialised()
{
ClearErrorState();
RepositoryInitialisationData initData = new RepositoryInitialisationData();
try
{
// Query first internal association.
List<String> sql = new List<string>()
{
$"Select {col_AssocId}=ass.Id, {col_AffilId}=aff.Id, {col_Name}=aff.Name, {col_Website}=aff.Website, {col_CompanyNo}=aff.CompanyNo, {col_VatReg}=aff.VatReg",
$"From Association ass",
$"Left Join Affiliate aff On aff.Id=ass.AffIdOwner And aff.Id=ass.AffIdTarget And aff.Type<>{(int)Sbm.AffiliateType.Individual}",
$"Where ass.Type={(int)Sbm.AssociationType.Internal};"
};
using (DbResultSet resultSet = Database_Core.ExecuteQuery(String.Join(" ", sql)))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
initData.ClearOrganisation();
initData.Organisation.Name = values.GetString(col_Name);
initData.Organisation.Website = values.GetString(col_Website);
initData.Organisation.CompanyNo = values.GetString(col_CompanyNo);
initData.Organisation.VatReg = values.GetString(col_VatReg);
initData.Organisation.AffiliateId = new SysId(values.GetLong(col_AffilId));
initData.Organisation.AssociationId = new SysId(values.GetLong(col_AssocId));
if (SysId.IsValid(initData.Organisation.AssociationId) && SysId.IsValid(initData.Organisation.AffiliateId))
break;
}
if (!SysId.IsValid(initData.Organisation.AssociationId))
return SetErrorState("Internal association not found.");
if (!SysId.IsValid(initData.Organisation.AffiliateId))
return SetErrorState("Owner affiliate not found.");
}
// Query Employees for the Organisation.
sql = new List<string>()
{
$"Select {col_AffilId}=aff.Id, {col_FirstName}=aff.FirstName, {col_LastName}=aff.LastName, {col_UserId}=aff.UserId, {col_UserCode}=seci.Code",
$"From Association ass",
$"Inner Join Affiliate aff On aff.Id=ass.AffIdTarget And aff.Type={(int)Sbm.AffiliateType.Individual} And IsNull(aff.UserId,0)>0",
$"Left Join SaSecItem seci On seci.Id=aff.UserId",
$"Where ass.AffIdOwner={SysId.ToLong(initData.Organisation.AffiliateId)} And ass.Type={(int)Sbm.AssociationType.Member};"
};
using (DbResultSet resultSet = Database_Core.ExecuteQuery(String.Join(" ", sql)))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
initData.ClearUser();
initData.User.AffiliateId = new SysId(values.GetLong(col_AffilId));
initData.User.FirstName = values.GetString(col_FirstName);
initData.User.LastName = values.GetString(col_LastName);
initData.User.Email = values.GetString(col_Email);
initData.User.SecurityItemId = new SysId(values.GetLong(col_UserId));
initData.User.Code = values.GetString(col_UserCode);
if (SysId.IsValid(initData.User.AffiliateId) && SysId.IsValid(initData.User.SecurityItemId))
break;
}
if (!SysId.IsValid(initData.User.AffiliateId))
return SetErrorState("User affiliate not found.");
if (!SysId.IsValid(initData.User.SecurityItemId))
return SetErrorState("User security item not found.");
}
}
catch (Exception exc)
{
String msg = "checking repository initialisation";
SaLogger.Warn($"{SysUtil.Fn} {ExceptionUtil.GetLogMessage(exc, msg)}");
return SetErrorState($"{exc.GetType().Name} {msg}");
}
return OK;
}
//-------------------------------------------------------------------
/// <summary>
/// Validate repository initialisation data.
/// </summary>
public bool ValidateRepositoryInitialisionData(RepositoryInitialisationData initData)
{
ClearErrorState();
// Organisation name.
if (StringUtil.IsBlank(initData.Organisation.Name))
return SetErrorState("Organisation name must be supplied.");
if ((ulong)StringUtil.GetLength(initData.Organisation.Name) > SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_Name))
return SetErrorState("Organisation name exceeds max chars.");
// Organisation VAT reg.
if ((ulong)StringUtil.GetLength(initData.Organisation.VatReg) > SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_VatReg))
return SetErrorState("Company VAT reg exceeds max chars.");
// Organisation Company Number.
if ((ulong)StringUtil.GetLength(initData.Organisation.CompanyNo) > SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_CompanyNo))
return SetErrorState("Company number exceeds max chars.");
// Organisation Company Number.
if ((ulong)StringUtil.GetLength(initData.Organisation.Website) > SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_Website))
return SetErrorState("Company website address exceeds max chars.");
// User first name.
if (StringUtil.IsBlank(initData.User.FirstName))
return SetErrorState("User first name must be supplied.");
if ((ulong)StringUtil.GetLength(initData.User.FirstName) > SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_FirstName))
return SetErrorState("User first name exceeds max chars.");
// User last name.
if (StringUtil.IsBlank(initData.User.LastName))
return SetErrorState("User last name must be supplied.");
if ((ulong)StringUtil.GetLength(initData.User.LastName) > SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_LastName))
return SetErrorState("User last name exceeds max chars.");
// User email.
if (StringUtil.IsBlank(initData.User.Email))
return SetErrorState("User email must be supplied.");
if ((ulong)StringUtil.GetLength(initData.User.Email) > SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Affiliate_Email) || (ulong)StringUtil.GetLength(initData.User.Email) > SaSecurityDbDfn.GetColTextLen(SaSecurityDbDfn.ColumnIdx.SaSecItem_EmailAddress))
return SetErrorState("User email exceeds max chars.");
// User code.
if (StringUtil.IsBlank(initData.User.Code))
return SetErrorState("User code must be supplied.");
if ((ulong)StringUtil.GetLength(initData.User.Code) > SaSecurityDbDfn.GetColTextLen(SaSecurityDbDfn.ColumnIdx.SaSecItem_Code))
return SetErrorState("User code exceeds max chars.");
// 'Super' security group.
if (StringUtil.IsBlank(SecurityGroupCode_Super))
return SetErrorState($"Failed to identify code for 'Super' security group.");
return OK;
}
//-------------------------------------------------------------------
/// <summary>
/// Initialise repository.
/// </summary>
public bool InitialiseRepository(RepositoryInitialisationData initData)
{
ClearErrorState();
if (!ValidateRepositoryInitialisionData(initData)) return false;
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
//-----------------------------------------------------------
// Organisation Contact.
// Retrieve existing Organisation.
SbmAffiliate affiliateOrganisation = Internals_Core.AccountMgr.GetAffiliateById(initData.Organisation.AffiliateId);
if (affiliateOrganisation != null && !affiliateOrganisation.IsOrganisation())
return SetErrorState("Identified contact is not an organisation.");
if (affiliateOrganisation == null)
affiliateOrganisation = Internals_Core.AccountMgr.GetAffiliateByTypeName(Sbm.AffiliateType.AnyOrganisation, initData.Organisation.Name);
if (affiliateOrganisation == null)
{
// Create new organisation.
affiliateOrganisation = Internals_Core.AccountMgr.CreateAffiliate(Sbm.AffiliateType.Commercial);
}
disposables.Add(affiliateOrganisation);
// Populate properties.
affiliateOrganisation.Name = initData.Organisation.Name;
if (!StringUtil.IsBlank(initData.Organisation.VatReg))
affiliateOrganisation.VatReg = initData.Organisation.VatReg;
if (!StringUtil.IsBlank(initData.Organisation.CompanyNo))
affiliateOrganisation.CompanyNo = initData.Organisation.CompanyNo;
if (!StringUtil.IsBlank(initData.Organisation.Website))
affiliateOrganisation.Website = initData.Organisation.Website;
// Store Organisation Contact.
if (!SysId.IsValid(affiliateOrganisation.Id))
{
if (!Internals_Core.AccountMgr.InsertAffiliate(affiliateOrganisation, DbUpdateInfo_Core))
return SetErrorState($"Failed to insert Organisation contact - {Internals_Core.AccountMgr.ErrorStateMessage}");
}
else
{
if (!Internals_Core.AccountMgr.UpdateAffiliate(affiliateOrganisation, DbUpdateInfo_Core))
return SetErrorState($"Failed to update Organisation contact - {Internals_Core.AccountMgr.ErrorStateMessage}");
}
//-----------------------------------------------------------
// Organisation Internal association.
// Retrieve existing Internal Association for Organisation.
SbmAssociation associationInternal = Internals_Core.AccountMgr.GetAssociationByOwnerTypeTarget(affiliateOrganisation.Id, Sbm.AssociationType.Internal, affiliateOrganisation.Id);
disposables.Add(associationInternal);
if (associationInternal != null && SysId.IsValid(initData.Organisation.AssociationId) && !associationInternal.Id.Equals(initData.Organisation.AssociationId))
// Failed to validate existing Internal Association against supplied Association Id.
return SetErrorState($"Supplied Internal Association Id ({initData.Organisation.AssociationId}) doesn't match existing association ({associationInternal.Id}).");
if (associationInternal == null && SysId.IsValid(initData.Organisation.AssociationId))
{
// No existing Internal Association found for Organisation - retrieve specified Association.
associationInternal = Internals_Core.AccountMgr.GetAssociationById(initData.Organisation.AssociationId);
if (associationInternal == null)
return SetErrorState($"Failed to retrieve supplied Internal Association. Id: {initData.Organisation.AssociationId}.");
disposables.Add(associationInternal);
if (!associationInternal.AffiliateIdOwner.Equals(affiliateOrganisation.Id))
return SetErrorState($"Supplied Internal Association has different Owner ({associationInternal.AffiliateIdOwner}) to Organisation ({affiliateOrganisation.Id}).");
if (!associationInternal.AffiliateIdTarget.Equals(affiliateOrganisation.Id))
return SetErrorState($"Supplied Internal Association has different Target ({associationInternal.AffiliateIdTarget}) to Organisation ({affiliateOrganisation.Id}).");
}
if (associationInternal == null)
associationInternal = Internals_Core.AccountMgr.CreateAssociation(affiliateOrganisation.Id, Sbm.AssociationType.Internal, affiliateOrganisation.Id);
disposables.Add(associationInternal);
// Store Internal Association.
if (!SysId.IsValid(associationInternal.Id))
{
if (!Internals_Core.AccountMgr.InsertAssociation(associationInternal, DbUpdateInfo_Core))
return SetErrorState($"Failed to insert Internal Association for Organisation - {Internals_Core.AccountMgr.ErrorStateMessage}");
}
else
{
if (!Internals_Core.AccountMgr.UpdateAssociation(associationInternal, DbUpdateInfo_Core))
return SetErrorState($"Failed to update Internal Association for Organisation - {Internals_Core.AccountMgr.ErrorStateMessage}");
}
//-----------------------------------------------------------
// Security.
// Core security console.
SaSecurityConsole securityConsole = CreateSecurityConsole();
disposables.Add(securityConsole);
// Initialise security data if required.
if (securityConsole.RequiresPopulation() && !securityConsole.PopulateSecurityRights(DbUpdateInfo_Core))
return SetErrorState(securityConsole.ErrorStateMessage);
// User Security Item.
SaSecurityItem securityItemUser = null;
// Retrieve supplied Security Item.
if (SysId.IsValid(initData.User.SecurityItemId))
{
securityItemUser = securityConsole.GetSecurityItemById(SaSecurity.ItemType.User, initData.User.SecurityItemId);
if (securityItemUser == null)
return SetErrorState($"Failed to retrieve supplied User Security Item. Id: {initData.User.SecurityItemId}.");
disposables.Add(securityItemUser);
if (!securityItemUser.Code.Equals(initData.User.Code))
return SetErrorState($"Supplied User Security Item doesn't match supplied code. Expected: {initData.User.Code}. Found: {securityItemUser.Code}.");
}
if (securityItemUser == null)
{
// Retrieve Security Item by code.
securityItemUser = securityConsole.GetSecurityItemByCode(SaSecurity.ItemType.User, initData.User.Code);
disposables.Add(securityItemUser);
}
if (securityItemUser == null)
{
// Create User Security Item.
if (!securityConsole.CreateUser(initData.User.Code, $"{initData.User.LastName}, {initData.User.FirstName}", DbUpdateInfo_Core))
return SetErrorState($"Failed to create User Security Item - {securityConsole.ErrorStateMessage}.");
securityItemUser = securityConsole.GetSecurityItemByCode(SaSecurity.ItemType.User, initData.User.Code);
if (securityItemUser == null)
return SetErrorState($"Failed to retrieve User Security Item after creation. Code: {initData.User.Code}.");
disposables.Add(securityItemUser);
}
// Populate User Security Item properties.
securityItemUser.EmailAddress = initData.User.Email;
securityConsole.SetPassword(securityItemUser, initData.User.Password);
if (!securityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo_Core))
return SetErrorState($"Failed to update User Security Item - {securityConsole.ErrorStateMessage}.");
// Assign to 'Super' Group.
SysId securityGroupIdSuper = securityConsole.GetIdForItemCode(SaSecurity.ItemType.Group, SecurityGroupCode_Super);
if (!SysId.IsValid(securityGroupIdSuper))
return SetErrorState($"Failed to identify 'Super' security group. Code: '{SecurityGroupCode_Super}'.");
if (!securityConsole.ItemsAreLinked(securityItemUser.Id, securityGroupIdSuper) && !securityConsole.AssignUserToGroup(securityItemUser.Code, SecurityGroupCode_Super, DbUpdateInfo_Core))
return SetErrorState($"Failed to assign User Security Item to Super Group - {securityConsole.ErrorStateMessage}.");
//-----------------------------------------------------------
// User Contact.
SbmAffiliate affiliateUser = null;
if (SysId.IsValid(initData.User.AffiliateId))
{
// Retrieve supplied User Contact.
affiliateUser = Internals_Core.AccountMgr.GetAffiliateById(initData.User.AffiliateId);
if (affiliateUser == null)
return SetErrorState($"Failed to retrieve User Contact. Id: {initData.User.AffiliateId}.");
disposables.Add(affiliateUser);
}
if (affiliateUser == null)
{
// Retrieve User Contact by User Code.
affiliateUser = Internals_Core.AccountMgr.GetAffiliateByUserId(securityItemUser.Id);
disposables.Add(affiliateUser);
}
if (affiliateUser == null)
{
// Retrieve User Contact by name.
affiliateUser = Internals_Core.AccountMgr.GetIndividualByName(initData.User.FirstName, initData.User.LastName);
disposables.Add(affiliateUser);
}
if (affiliateUser == null)
{
// Create User Contact.
affiliateUser = Internals_Core.AccountMgr.CreateAffiliate(Sbm.AffiliateType.Individual);
disposables.Add(affiliateUser);
}
// Populate User Contact properties.
affiliateUser.FirstName = initData.User.FirstName;
affiliateUser.LastName = initData.User.LastName;
affiliateUser.Email = initData.User.Email;
affiliateUser.UserId = securityItemUser.Id;
// Store User Contact.
if (!SysId.IsValid(affiliateUser.Id))
{
if (!Internals_Core.AccountMgr.InsertAffiliate(affiliateUser, DbUpdateInfo_Core))
return SetErrorState($"Failed to insert User contact - {Internals_Core.AccountMgr.ErrorStateMessage}");
}
else
{
if (!Internals_Core.AccountMgr.UpdateAffiliate(affiliateUser, DbUpdateInfo_Core))
return SetErrorState($"Failed to update User contact - {Internals_Core.AccountMgr.ErrorStateMessage}");
}
//-----------------------------------------------------------
// User Member Association.
// Attempt to retrieve existing Member Association.
SbmAssociation associationMember = Internals_Core.AccountMgr.GetAssociationByOwnerTypeTarget(affiliateOrganisation.Id, Sbm.AssociationType.Member, affiliateUser.Id);
if (associationMember == null)
// Create Member Association.
associationMember = Internals_Core.AccountMgr.CreateAssociation(affiliateOrganisation.Id, Sbm.AssociationType.Member, affiliateUser.Id);
disposables.Add(associationMember);
// Store User Association.
if (!SysId.IsValid(associationMember.Id))
{
if (!Internals_Core.AccountMgr.InsertAssociation(associationMember, DbUpdateInfo_Core))
return SetErrorState($"Failed to insert Member Association for User - {Internals_Core.AccountMgr.ErrorStateMessage}");
}
else
{
if (!Internals_Core.AccountMgr.UpdateAssociation(associationMember, DbUpdateInfo_Core))
return SetErrorState($"Failed to update Member Association for User - {Internals_Core.AccountMgr.ErrorStateMessage}");
}
//-----------------------------------------------------------
}
return OK;
}
//-------------------------------------------------------------------
}
}
@@ -70,9 +70,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Data members. // Data members.
private SbmInternals internals;
private List<TypeCodeDesc> transactionTypes_Full = new List<TypeCodeDesc>(); private List<TypeCodeDesc> transactionTypes_Full = new List<TypeCodeDesc>();
private SbmInstanceConfig instanceConfig; private SbmInstanceConfig instanceConfig;
private SbmAccountsDfn accountsDfn;
private AccountsInterfaceDfn dfnSageInt = new AccountsInterfaceDfn(); private AccountsInterfaceDfn dfnSageInt = new AccountsInterfaceDfn();
private AccountsInterfaceDfn dfnQBooksInt = new AccountsInterfaceDfn(); private AccountsInterfaceDfn dfnQBooksInt = new AccountsInterfaceDfn();
private bool createTransaction_PurchaseOrder, createTransaction_SalesQuote, createTransaction_SalesOrder, createTrans_SalesInvoice; private bool createTransaction_PurchaseOrder, createTransaction_SalesQuote, createTransaction_SalesOrder, createTrans_SalesInvoice;
@@ -91,6 +91,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles
{ {
if (disposing) if (disposing)
{ {
if (internals != null) internals.Dispose(); internals = null;
} }
} }
@@ -102,6 +103,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles
public SbmVersion AppVersion { get; } public SbmVersion AppVersion { get; }
public SbmVersion ConsoleVersion { get; } public SbmVersion ConsoleVersion { get; }
public SbmInstanceConfig InstanceConfig { get { if (instanceConfig == null) instanceConfig = SbmGlobals.Application.GetInstanceConfig(SessionContext); return instanceConfig; } } public SbmInstanceConfig InstanceConfig { get { if (instanceConfig == null) instanceConfig = SbmGlobals.Application.GetInstanceConfig(SessionContext); return instanceConfig; } }
private SbmInternals Internals { get { if (internals == null) internals = new SbmInternals(UserContext); return internals; } }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// C r e a t e C o n s o l e // C r e a t e C o n s o l e
@@ -178,16 +180,14 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles
{ {
if (InstanceConfig.AllowApplicationOption(option, false)) if (InstanceConfig.AllowApplicationOption(option, false))
return true; return true;
if (accountsDfn == null) accountsDfn = new SbmAccountsDfn(UserContext); return Internals.AccountsDfn.IsUsingSageInterface() && Internals.AccountsDfn.IsAssociationTypeManagedByAccounts(Sbm.AssociationType.Customer) && !Internals.AccountsDfn.UseLocalCustomerPricing();
return accountsDfn.IsUsingSageInterface() && accountsDfn.IsAssociationTypeManagedByAccounts(Sbm.AssociationType.Customer) && !accountsDfn.UseLocalCustomerPricing();
} }
case Sbm.ConfigOption.SupplierPriceSet: case Sbm.ConfigOption.SupplierPriceSet:
case Sbm.ConfigOption.SupplierDiscount: case Sbm.ConfigOption.SupplierDiscount:
{ {
if (InstanceConfig.AllowApplicationOption(option, false)) if (InstanceConfig.AllowApplicationOption(option, false))
return true; return true;
SbmAccountsDfn account = null; return Internals.AccountsDfn.IsUsingSageInterface() && Internals.AccountsDfn.IsAssociationTypeManagedByAccounts(Sbm.AssociationType.Supplier) && !Internals.AccountsDfn.UseLocalSupplierPricing();
return account.IsUsingSageInterface() && account.IsAssociationTypeManagedByAccounts(Sbm.AssociationType.Supplier) && !account.UseLocalSupplierPricing();
} }
} }
return InstanceConfig.AllowApplicationOption(option, false); return InstanceConfig.AllowApplicationOption(option, false);
@@ -502,37 +502,36 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Consoles
dfnQBooksInt.ClearConfig(); dfnQBooksInt.ClearConfig();
dfnQBooksInt.AffiliateId_Owner = UserContext.OrganisationAffiliateId; dfnQBooksInt.AffiliateId_Owner = UserContext.OrganisationAffiliateId;
// Identify the interfaces. // Identify the interfaces.
SbmAccountsDfn accountsDfn = new SbmAccountsDfn(UserContext); dfnSageInt.InterfaceId = Internals.AccountsDfn.GetAccountInterfaceId(Sbm.InterfaceType_Accounts.SageLine50);
dfnSageInt.InterfaceId = accountsDfn.GetAccountInterfaceId(Sbm.InterfaceType_Accounts.SageLine50); dfnQBooksInt.InterfaceId = Internals.AccountsDfn.GetAccountInterfaceId(Sbm.InterfaceType_Accounts.QuickBooks);
dfnQBooksInt.InterfaceId = accountsDfn.GetAccountInterfaceId(Sbm.InterfaceType_Accounts.QuickBooks);
// Sales and purchase orders/invoices can only be created locally if they are not imported from one of these interfaces. // Sales and purchase orders/invoices can only be created locally if they are not imported from one of these interfaces.
if (SysId.IsValid(dfnSageInt.InterfaceId)) if (SysId.IsValid(dfnSageInt.InterfaceId))
{ {
// Interpret interface options. // Interpret interface options.
dfnSageInt.importPurchaseOrder = accountsDfn.GetSageImportOption(Sage.ItemType.PurchaseOrder); dfnSageInt.importPurchaseOrder = Internals.AccountsDfn.GetSageImportOption(Sage.ItemType.PurchaseOrder);
dfnSageInt.importSalesOrder = accountsDfn.GetSageImportOption(Sage.ItemType.SalesOrder); dfnSageInt.importSalesOrder = Internals.AccountsDfn.GetSageImportOption(Sage.ItemType.SalesOrder);
dfnSageInt.importProductInvoice = accountsDfn.GetSageImportOption(Sage.ItemType.Invoice_Product); dfnSageInt.importProductInvoice = Internals.AccountsDfn.GetSageImportOption(Sage.ItemType.Invoice_Product);
dfnSageInt.importServiceInvoice = accountsDfn.GetSageImportOption(Sage.ItemType.Invoice_Service); dfnSageInt.importServiceInvoice = Internals.AccountsDfn.GetSageImportOption(Sage.ItemType.Invoice_Service);
dfnSageInt.importSalesOrderInvoice = accountsDfn.GetSageImportOption(Sage.ItemType.Invoice_SalesOrder); dfnSageInt.importSalesOrderInvoice = Internals.AccountsDfn.GetSageImportOption(Sage.ItemType.Invoice_SalesOrder);
dfnSageInt.exportPurchaseOrder = accountsDfn.GetSageExportOption(Sage.ItemType.PurchaseOrder); dfnSageInt.exportPurchaseOrder = Internals.AccountsDfn.GetSageExportOption(Sage.ItemType.PurchaseOrder);
dfnSageInt.exportSalesOrder = accountsDfn.GetSageExportOption(Sage.ItemType.SalesOrder); dfnSageInt.exportSalesOrder = Internals.AccountsDfn.GetSageExportOption(Sage.ItemType.SalesOrder);
dfnSageInt.exportProductInvoice = accountsDfn.GetSageExportOption(Sage.ItemType.Invoice_Product); dfnSageInt.exportProductInvoice = Internals.AccountsDfn.GetSageExportOption(Sage.ItemType.Invoice_Product);
dfnSageInt.exportServiceInvoice = accountsDfn.GetSageExportOption(Sage.ItemType.Invoice_Service); dfnSageInt.exportServiceInvoice = Internals.AccountsDfn.GetSageExportOption(Sage.ItemType.Invoice_Service);
dfnSageInt.exportSalesOrder = accountsDfn.GetSageExportOption(Sage.ItemType.Invoice_SalesOrder); dfnSageInt.exportSalesOrder = Internals.AccountsDfn.GetSageExportOption(Sage.ItemType.Invoice_SalesOrder);
} }
if (SysId.IsValid(dfnQBooksInt.InterfaceId)) if (SysId.IsValid(dfnQBooksInt.InterfaceId))
{ {
// Interpret interface options. // Interpret interface options.
dfnQBooksInt.importPurchaseOrder = accountsDfn.GetQuickBooksImportOption(Qbk.EntityType.PurchaseOrder); dfnQBooksInt.importPurchaseOrder = Internals.AccountsDfn.GetQuickBooksImportOption(Qbk.EntityType.PurchaseOrder);
dfnQBooksInt.importSalesOrder = accountsDfn.GetQuickBooksImportOption(Qbk.EntityType.SalesOrder); dfnQBooksInt.importSalesOrder = Internals.AccountsDfn.GetQuickBooksImportOption(Qbk.EntityType.SalesOrder);
dfnQBooksInt.importProductInvoice = accountsDfn.GetQuickBooksImportOption(Qbk.EntityType.Invoice_Product); dfnQBooksInt.importProductInvoice = Internals.AccountsDfn.GetQuickBooksImportOption(Qbk.EntityType.Invoice_Product);
dfnQBooksInt.importServiceInvoice = accountsDfn.GetQuickBooksImportOption(Qbk.EntityType.Invoice_Service); dfnQBooksInt.importServiceInvoice = Internals.AccountsDfn.GetQuickBooksImportOption(Qbk.EntityType.Invoice_Service);
dfnQBooksInt.importSalesOrderInvoice = false; dfnQBooksInt.importSalesOrderInvoice = false;
dfnQBooksInt.exportPurchaseOrder = accountsDfn.GetQuickBooksExportOption(Qbk.EntityType.PurchaseOrder); dfnQBooksInt.exportPurchaseOrder = Internals.AccountsDfn.GetQuickBooksExportOption(Qbk.EntityType.PurchaseOrder);
dfnQBooksInt.exportSalesOrder = accountsDfn.GetQuickBooksExportOption(Qbk.EntityType.SalesOrder); dfnQBooksInt.exportSalesOrder = Internals.AccountsDfn.GetQuickBooksExportOption(Qbk.EntityType.SalesOrder);
dfnQBooksInt.exportProductInvoice = accountsDfn.GetQuickBooksExportOption(Qbk.EntityType.Invoice_Product); dfnQBooksInt.exportProductInvoice = Internals.AccountsDfn.GetQuickBooksExportOption(Qbk.EntityType.Invoice_Product);
dfnQBooksInt.exportServiceInvoice = accountsDfn.GetQuickBooksExportOption(Qbk.EntityType.Invoice_Service); dfnQBooksInt.exportServiceInvoice = Internals.AccountsDfn.GetQuickBooksExportOption(Qbk.EntityType.Invoice_Service);
dfnQBooksInt.bexport_SalesOrderInvoice = false; dfnQBooksInt.bexport_SalesOrderInvoice = false;
} }
@@ -7,6 +7,7 @@ using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm;
namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
{ {
@@ -90,55 +91,61 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
if (!SysId.IsValid(userId)) return null; if (!SysId.IsValid(userId)) return null;
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
prmAffiliate.UserId = userId; prmAffiliate.UserId = userId;
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.Any; prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted;
return GetAffiliate(prmAffiliate); return GetAffiliate(prmAffiliate);
} }
public SbmAffiliate GetAffiliateByTypeName(Sbm.AffiliateType affiliateType, String affiliateName) public SbmAffiliate GetAffiliateByTypeName(Sbm.AffiliateType affiliateType, String affiliateName)
{ {
ClearErrorState(); ClearErrorState();
if (!StringUtil.IsEmpty(affiliateName)) return null; if (StringUtil.IsBlank(affiliateName)) return null;
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
prmAffiliate.AffiliateType = affiliateType;
prmAffiliate.Name = affiliateName; prmAffiliate.Name = affiliateName;
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.Any; prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted;
return GetAffiliate(prmAffiliate); prmAffiliate.ResultsPaging.Set(1,2);
foreach (SbmAffiliate affiliate in GetAffiliateList(prmAffiliate))
return affiliate;
return null;
} }
public SbmAffiliate GetIndividualByName(String firstName, String lastName) public SbmAffiliate GetIndividualByName(String firstName, String lastName)
{ {
ClearErrorState(); ClearErrorState();
if (!StringUtil.IsEmpty(firstName) || !StringUtil.IsEmpty(lastName)) return null; if (StringUtil.IsBlank(firstName) || StringUtil.IsBlank(lastName)) return null;
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
prmAffiliate.Name = firstName; prmAffiliate.AffiliateType = AffiliateType.Individual;
prmAffiliate.Name = lastName; prmAffiliate.FirstName = firstName;
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.Any; prmAffiliate.LastName = lastName;
return GetAffiliate(prmAffiliate); prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted;
prmAffiliate.ResultsPaging.Set(1, 2);
foreach (SbmAffiliate affiliate in GetAffiliateList(prmAffiliate))
return affiliate;
return null;
} }
public SbmAffiliate GetOrganisationByName(String organisationName) public SbmAffiliate GetOrganisationByName(String organisationName)
{ {
ClearErrorState(); return GetAffiliateByTypeName(Sbm.AffiliateType.AnyOrganisation, organisationName);
if (!StringUtil.IsEmpty(organisationName)) return null;
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
prmAffiliate.Name = organisationName;
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.Any;
return GetAffiliate(prmAffiliate);
} }
public SbmAffiliate GetTargetAffiliateByAssocId(SysId associationId) public SbmAffiliate GetTargetAffiliateByAssocId(SysId associationId)
{ {
ClearErrorState(); ClearErrorState();
if (!SysId.IsValid(associationId)) return null; if (!SysId.IsValid(associationId)) return null;
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); using (SbmAssociation association = GetAssociationById(associationId))
prmAffiliate.IdsIncluded.Add(associationId); {
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.Any; if (association != null)
return GetAffiliate(prmAffiliate); return GetAffiliateById(association.AffiliateIdTarget);
}
return null;
} }
public SbmAffiliate GetTargetAffiliateByAssocTypeCode(Sbm.AssociationType associationType, String associationCode) public SbmAffiliate GetTargetAffiliateByAssocTypeCode(Sbm.AssociationType associationType, String associationCode)
{ {
ClearErrorState(); ClearErrorState();
if ((int)associationType < 1 || !StringUtil.IsEmpty(associationCode)) return null; if ((int)associationType < 1 || StringUtil.IsBlank(associationCode)) return null;
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params(); using (SbmAssociation association = GetAssociationByTypeCode(associationType, associationCode))
prmAffiliate.AssociationType = associationType; {
//prmAffiliate.Code = associationCode; if (association != null)
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.Any; return GetAffiliateById(association.AffiliateIdTarget);
return GetAffiliate(prmAffiliate); }
return null;
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
@@ -76,7 +76,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
return GetTransaction(prmTransaction); return GetTransaction(prmTransaction);
} }
public abstract List<SysId> GetRequirementByIds(SbmTransaction.Params prmTrans); public abstract List<SysId> GetRequirementIds(SbmTransaction.Params prmTrans);
public SbmTransaction GetTransactionByOwnerTypeRef(SysId affIdOwner, Sbm.TransactionType transactionType, String transRef) public SbmTransaction GetTransactionByOwnerTypeRef(SysId affIdOwner, Sbm.TransactionType transactionType, String transRef)
{ {
@@ -129,12 +129,19 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
} }
} }
// NB Ref, RefInt is optional. // References.
if (errField.Ref != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.RefExt, "external", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Ref)))
{
errField.Ref = SacsHierarchyItem.ValidValue.Invalid;
return false;
}
if (errField.RefExt != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.RefExt, "external ref", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_RefExt))) if (errField.RefExt != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.RefExt, "external ref", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_RefExt)))
{ {
errField.RefExt = SacsHierarchyItem.ValidValue.Invalid; errField.RefExt = SacsHierarchyItem.ValidValue.Invalid;
return false; return false;
} }
// Raised by.
if (errField.RaisedBy != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.RaisedBy, "raised by", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_RaisedBy))) if (errField.RaisedBy != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.RaisedBy, "raised by", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_RaisedBy)))
{ {
errField.RaisedBy = SacsHierarchyItem.ValidValue.Invalid; errField.RaisedBy = SacsHierarchyItem.ValidValue.Invalid;
@@ -146,6 +153,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
errField.ContactName = SacsHierarchyItem.ValidValue.Invalid; errField.ContactName = SacsHierarchyItem.ValidValue.Invalid;
return false; return false;
} }
if (errField.Likelihood != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Likelihood, "likelihood", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Likelihood))) if (errField.Likelihood != SacsHierarchyItem.ValidValue.Ignore && !IsValidValue(data.Likelihood, "likelihood", (long)SbmDbDfn.GetColTextLen(SbmDbDfn.ColumnIdx.Transaction_Likelihood)))
{ {
errField.Likelihood = SacsHierarchyItem.ValidValue.Invalid; errField.Likelihood = SacsHierarchyItem.ValidValue.Invalid;
@@ -281,7 +289,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
errField.Status = SacsHierarchyItem.ValidValue.Invalid; errField.Status = SacsHierarchyItem.ValidValue.Invalid;
return false; return false;
} }
if (!SbmTransaction.GetTransactionStatuses(data.TransactionType).Contains(data.Status)) if (!SbmTransaction.ValidStatusesByType(data.TransactionType).Contains(data.Status))
{ {
errField.Status = SacsHierarchyItem.ValidValue.Invalid; errField.Status = SacsHierarchyItem.ValidValue.Invalid;
return SetErrorState(ErrorMessage.InvalidStatus); return SetErrorState(ErrorMessage.InvalidStatus);
@@ -191,6 +191,9 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Consoles
// Register Security Rights. // Register Security Rights.
public override void RegisterSecurityRights() public override void RegisterSecurityRights()
{ {
// Reset.
ClearRegisteredSecurityRights();
//--------------------------------------------------------------- //---------------------------------------------------------------
// Register data item types. [Not used - to demonstrate option] // Register data item types. [Not used - to demonstrate option]
RegisterDataItemType((short)Sbm.ItemType.Commodity, "Commodity"); RegisterDataItemType((short)Sbm.ItemType.Commodity, "Commodity");
@@ -416,6 +416,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
filter.Add(searchFilter.Concat(" OR ", "(", ")")); filter.Add(searchFilter.Concat(" OR ", "(", ")"));
} }
} }
// Common Properties. // Common Properties.
// Notes. // Notes.
@@ -610,6 +610,13 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
if (!StringUtil.IsEmpty(prm.NamePartial)) if (!StringUtil.IsEmpty(prm.NamePartial))
filter.Add(colAffiliate_Name + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%' OR " + colAffiliate_FirstName + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%' OR " + colAffiliate_LastName + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%'"); filter.Add(colAffiliate_Name + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%' OR " + colAffiliate_FirstName + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%' OR " + colAffiliate_LastName + " LIKE '%" + DbQuery.FormatForLike(prm.NamePartial) + "%'");
// First Name.
if (!StringUtil.IsEmpty(prm.FirstName))
filter.Add(colAffiliate_FirstName + "='" + DbQuery.FormatForCondition(prm.FirstName) + "'");
// Last Name.
if (!StringUtil.IsEmpty(prm.LastName))
filter.Add(colAffiliate_LastName + "='" + DbQuery.FormatForCondition(prm.LastName) + "'");
// Partial Email. // Partial Email.
if (!StringUtil.IsEmpty(prm.EmailPartial)) if (!StringUtil.IsEmpty(prm.EmailPartial))
filter.Add(colAffiliate_Email + " LIKE '%" + DbQuery.FormatForLike(prm.EmailPartial) + "%'"); filter.Add(colAffiliate_Email + " LIKE '%" + DbQuery.FormatForLike(prm.EmailPartial) + "%'");
@@ -732,8 +732,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
// Performance of querying requirements for transaction(s) within movement query is very poor - eg. ItemIdSource in (Select Id From Requirement Where TransactionId in (1,2,3)). // Performance of querying requirements for transaction(s) within movement query is very poor - eg. ItemIdSource in (Select Id From Requirement Where TransactionId in (1,2,3)).
// Get list of requirement Ids first and then explicitly query against these in the movement query. // Get list of requirement Ids first and then explicitly query against these in the movement query.
SbmTransaction.Params prmTrans = new SbmTransaction.Params(); SbmTransaction.Params prmTrans = new SbmTransaction.Params();
prmTrans.IdsIncluded = prm.ItemIdSource; prmTrans.IdsIncluded.UnionWith(prm.ItemIdSource);
List<SysId> requirementId = TransactionMgr.GetRequirementByIds(prmTrans); List<SysId> requirementId = TransactionMgr.GetRequirementIds(prmTrans);
// Movements can be matched: either directly to one of the transactions or to any of their associated requirements. // Movements can be matched: either directly to one of the transactions or to any of their associated requirements.
List<String> filtersTrans = new List<String>(); List<String> filtersTrans = new List<String>();
@@ -14,6 +14,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
{ {
@@ -429,7 +430,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
return prmTransaction; return prmTransaction;
} }
public override List<SysId> GetRequirementByIds(SbmTransaction.Params prmTrans) public override List<SysId> GetRequirementIds(SbmTransaction.Params prmTrans)
{ {
ClearErrorState(); ClearErrorState();
List<SysId> ids = new List<SysId>(); List<SysId> ids = new List<SysId>();
@@ -1270,15 +1271,86 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
// Column names. // Column names.
String colTransaction_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id, tableAlias); String colTransaction_Id = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Id, tableAlias);
String colTransaction_Type = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Type, tableAlias); String colTransaction_Type = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Type, tableAlias);
String colTransaction_Ref = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Ref, tableAlias);
String colTransaction_RefInt = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_RefInt, tableAlias);
String colTransaction_RefExt = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_RefExt, tableAlias);
String colTransaction_DescBrief = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_DescBrief, tableAlias);
String colTransaction_StatusCat = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_StatusCat, tableAlias); String colTransaction_StatusCat = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_StatusCat, tableAlias);
String colTransaction_Status = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Status, tableAlias); String colTransaction_Status = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Status, tableAlias);
String colTransaction_Notes = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Notes, tableAlias);
//--------------------------------------------------------------- //---------------------------------------------------------------
// Transaction Id. // Transaction Id.
if (prm.IdsIncluded.HasValidIds()) if (prm.IdsIncluded.HasValidIds())
filter.Add(colTransaction_Id + " IN (" + prm.IdsIncluded.Concat(",") + ")"); filter.Add($"{colTransaction_Id} IN ({prm.IdsIncluded.Concat(",")})");
if (prm.IdsExcluded.HasValidIds()) if (prm.IdsExcluded.HasValidIds())
filter.Add(colTransaction_Id + " NOT IN (" + prm.IdsExcluded.Concat(",") + ")"); filter.Add($"{colTransaction_Id} NOT IN ({prm.IdsExcluded.Concat(",")})");
//---------------------------------------------------------------
// Transaction search.
if (!StringUtil.IsBlank(prm.Search))
{
foreach (String search in Regex.Split(prm.Search, "[\\s,;\\-+]+"))
{
if (StringUtil.IsBlank(search)) continue;
String searchForLike = DbQuery.FormatForLike(search, true);
List<String> searchFilter = new List<string>();
searchFilter.Add($"{colTransaction_Ref} LIKE '%{searchForLike}%'");
searchFilter.Add($"{colTransaction_RefExt} LIKE '%{searchForLike}%'");
searchFilter.Add($"{colTransaction_DescBrief} LIKE '%{searchForLike}%'");
if (!StringUtil.IsBlank(prm.TableAlias_AffiliateTarget))
{
searchFilter.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Name, prm.TableAlias_AffiliateTarget)} LIKE '%{searchForLike}%'");
}
if (searchFilter.Any())
filter.Add(searchFilter.Concat(" OR ", "(", ")"));
}
}
// Restrict transactions to the current owner if required.
if (SysId.IsValid(AffiliateId_Owner))
{
// Only need to filter on owner if no association specified, no transaction Ids and no source transaction id.
if (!SysId.IsValid(prm.AssociationId) && !prm.IdsIncluded.HasValidIds() && !SysId.IsValid(prm.TransIdSource))
filter.Add($"{SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_AffIdOwner, tableAlias)}={SysId.ToLong(AffiliateId_Owner)}");
}
// Association Id.
String colTransaction_AssocId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_AssocId, tableAlias);
if (SysId.IsValid(prm.AssociationId))
filter.Add($"{colTransaction_AssocId}={SysId.ToLong(prm.AssociationId)}");
// Transaction Type.
if (prm.TransactionType > 0)
filter.Add($"{colTransaction_Type}={(int)prm.TransactionType}");
//---------------------------------------------------------------
// Transaction Reference.
if (!StringUtil.IsEmpty(prm.TransRefFull))
{
String filterTransRef = $"{colTransaction_Ref}='{DbQuery.FormatForCondition(prm.TransRefFull)})'";
if (prm.TransRefFull.IsNumeric() && prm.TransRefFull.ToLong() >= 1)
filterTransRef += $" OR {colTransaction_RefInt}={prm.TransRefFull}";
filter.Add(filterTransRef);
}
else if (!StringUtil.IsEmpty(prm.TransRefPartial))
{
String filterTranRefPartial = $"{colTransaction_Ref} Like '%{DbQuery.FormatForLike(prm.TransRefPartial)}%'";
if (prm.TransRefPartial.IsNumeric() && prm.TransRefPartial.ToLong() >= 1)
filterTranRefPartial += $" OR {colTransaction_RefInt}={prm.TransRefPartial.ToLong()}";
filter.Add(filterTranRefPartial);
}
// Transaction External reference.
if (!StringUtil.IsEmpty(prm.TransRefExtFull))
filter.Add($"{colTransaction_RefExt}='{DbQuery.FormatForCondition(prm.TransRefExtFull)}'");
else if (!StringUtil.IsEmpty(prm.TransRefExtPartial))
filter.Add($"{colTransaction_RefExt} Like '%{DbQuery.FormatForLike(prm.TransRefExtPartial)}%'");
// Transaction DescBrief.
String sTransDescBrief = DbQuery.FormatForLike(prm.TransDescBriefPartial);
if (!StringUtil.IsEmpty(prm.TransDescBriefPartial))
filter.Add($"{colTransaction_DescBrief} LIKE '%{DbQuery.FormatForLike(prm.TransDescBriefPartial)}%'");
//--------------------------------------------------------------- //---------------------------------------------------------------
// Transaction Source. // Transaction Source.
@@ -1396,9 +1468,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
} }
//--------------------------------------------------------------- //---------------------------------------------------------------
// Transaction Type.
if (prm.TransactionType > 0)
filter.Add(colTransaction_Type + "=" + ((int)prm.TransactionType).ToString());
// Location Id Stock. // Location Id Stock.
if (SysId.IsValid(prm.LocationIdStock)) if (SysId.IsValid(prm.LocationIdStock))
@@ -1416,51 +1485,6 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
else if (!StringUtil.IsEmpty(TransactionStatusCats.GetCodeForType(prm.StatusCat))) else if (!StringUtil.IsEmpty(TransactionStatusCats.GetCodeForType(prm.StatusCat)))
filter.Add(colTransaction_StatusCat + "='" + TransactionStatusCats.GetCodeForType(prm.StatusCat) + "'"); filter.Add(colTransaction_StatusCat + "='" + TransactionStatusCats.GetCodeForType(prm.StatusCat) + "'");
// Restrict transactions to the current owner if required.
if (SysId.IsValid(AffiliateId_Owner))
{
// Only need to filter on owner if no association specified, no transaction Ids and no source transaction id.
if (!SysId.IsValid(prm.AssocId) && !prm.IdsIncluded.HasValidIds() && !SysId.IsValid(prm.TransIdSource))
filter.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_AffIdOwner, tableAlias) + "=" + SysId.ToString(AffiliateId_Owner));
}
//---------------------------------------------------------------
// Transaction Reference.
String colTransaction_Ref = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_Ref, tableAlias);
String colTransaction_RefInt = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_RefInt, tableAlias);
if (!StringUtil.IsEmpty(prm.TransRefFull))
{
String filterTransRef = colTransaction_Ref + "='" + DbQuery.FormatForCondition(prm.TransRefFull) + "'";
if (prm.TransRefFull.IsNumeric() && prm.TransRefFull.ToLong() >= 1)
filterTransRef += " OR " + colTransaction_RefInt + "=" + prm.TransRefFull;
filter.Add(filterTransRef);
}
else if (!StringUtil.IsEmpty(prm.TransRefPartial))
{
//String sFilter (DbQuery.FormatFn_Left(sColRef,prm.sTransRefPartial.Len())+"='"+sTransRefPartial+"'");
String filterTranRefPartial = colTransaction_Ref + " Like '%" + DbQuery.FormatForLike(prm.TransRefPartial) + "%'";
if (prm.TransRefPartial.IsNumeric() && prm.TransRefPartial.ToLong() >= 1)
filterTranRefPartial += " OR " + colTransaction_RefInt + "=" + prm.TransRefPartial;
filter.Add(filterTranRefPartial);
}
// Transaction External reference.
String colTransaction_RefExt = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_RefExt, tableAlias);
if (!StringUtil.IsEmpty(prm.TransRefExtFull))
filter.Add(colTransaction_RefExt + "='" + DbQuery.FormatForCondition(prm.TransRefExtFull) + "'");
else if (!StringUtil.IsEmpty(prm.TransRefExtPartial))
{
//filter.Add(DbQuery.FormatFn_Left(sColRefExt,prm.TransRefExtPartial.Len())+"='"+TransRefExtPartial+"'");
filter.Add(colTransaction_RefExt + " Like '%" + DbQuery.FormatForLike(prm.TransRefExtPartial) + "%'");
}
// Transaction DescBrief.
String sTransDescBrief = DbQuery.FormatForLike(prm.TransDescBriefPartial);
String colTransaction_DescBrief = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_DescBrief, tableAlias);
if (!StringUtil.IsEmpty(prm.TransDescBriefPartial))
//filter.Add(DbQuery.FormatFn_Left(sColDescBrief,prm.sTransDescBriefPartial.Len())+"='"+sTransDescBrief+"'");
filter.Add(colTransaction_DescBrief + " LIKE '%" + DbQuery.FormatForLike(prm.TransDescBriefPartial) + "%'");
//--------------------------------------------------------------- //---------------------------------------------------------------
// Raised date. // Raised date.
if (DateUtil.IsValid(prm.RaisedFrom)) if (DateUtil.IsValid(prm.RaisedFrom))
@@ -1542,12 +1566,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
} }
//--------------------------------------------------------------- //---------------------------------------------------------------
// Association Id.
String colTransaction_AssocId = SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_AssocId, tableAlias);
if (SysId.IsValid(prm.AssocId))
filter.Add(colTransaction_AssocId + "=" + prm.AssocId.ToString());
// Association Target. // Association Target.
String assocFilter = DbQuery.FormatForCondition(prm.AssocPartial); String assocFilter = DbQuery.FormatForCondition(prm.AssocPartial);
String defaultNominalCodeFull = DbQuery.FormatForCondition(prm.DefaultNominalCodeFull); String defaultNominalCodeFull = DbQuery.FormatForCondition(prm.DefaultNominalCodeFull);
String defaultNominalCodePartial = DbQuery.FormatForLike(prm.DefaultNominalCodePartial); String defaultNominalCodePartial = DbQuery.FormatForLike(prm.DefaultNominalCodePartial);
@@ -1854,8 +1874,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
if (hasAssocCols || hasOwnerAffCols || hasTgtAffCols || hasTgtAddrCols) if (hasAssocCols || hasOwnerAffCols || hasTgtAffCols || hasTgtAddrCols)
{ {
//--------------------------------------------------------------------- //---------------------------------------------------------------------
//Association.
// Join to the Association. // Join to the Association.
prm.TableAlias_Association = aliasTransaction_Association;
DbQueryJoin joinAssoc = new DbQueryJoin(DbJoinType.LeftOuter); DbQueryJoin joinAssoc = new DbQueryJoin(DbJoinType.LeftOuter);
joinAssoc.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Association), aliasTransaction_Association); joinAssoc.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Association), aliasTransaction_Association);
joinAssoc.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Id, aliasTransaction_Association, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_AssocId, aliasTransaction)); joinAssoc.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_Id, aliasTransaction_Association, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Transaction_AssocId, aliasTransaction));
@@ -1874,7 +1894,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
// Owner Affiliate. // Owner Affiliate.
if (hasOwnerAffCols) if (hasOwnerAffCols)
{ {
// Join to the Owner affiliate. // Join to the Owner Affiliate.
prm.TableAlias_AffiliateOwner = aliasTransaction_AffiliateOwner;
DbQueryJoin joinAffOwner = new DbQueryJoin(DbJoinType.LeftOuter); DbQueryJoin joinAffOwner = new DbQueryJoin(DbJoinType.LeftOuter);
joinAffOwner.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasTransaction_AffiliateOwner); joinAffOwner.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasTransaction_AffiliateOwner);
joinAffOwner.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasTransaction_AffiliateOwner, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdOwner, aliasTransaction_Association, false)); joinAffOwner.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasTransaction_AffiliateOwner, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdOwner, aliasTransaction_Association, false));
@@ -1889,7 +1910,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
// Target Affiliate. // Target Affiliate.
if (hasTgtAffCols || hasTgtAddrCols) if (hasTgtAffCols || hasTgtAddrCols)
{ {
// Join to the target affiliate. // Join to the Target Affiliate.
prm.TableAlias_AffiliateTarget = aliasTransaction_AffiliateTarget;
DbQueryJoin joinAffTarget = new DbQueryJoin(DbJoinType.LeftOuter); DbQueryJoin joinAffTarget = new DbQueryJoin(DbJoinType.LeftOuter);
joinAffTarget.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasTransaction_AffiliateTarget); joinAffTarget.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Affiliate), aliasTransaction_AffiliateTarget);
joinAffTarget.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasTransaction_AffiliateTarget, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdTarget, aliasTransaction_Association, false)); joinAffTarget.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Affiliate_Id, aliasTransaction_AffiliateTarget, false) + "=" + SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Association_AffIdTarget, aliasTransaction_Association, false));
@@ -1905,7 +1927,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
// Target Address. // Target Address.
if (hasTgtAddrCols) if (hasTgtAddrCols)
{ {
// Join to the target affiliate - NB Use an alias to avoid clashing with the owner affiliate. // Join to the Primary Target Address.
prm.TableAlias_AddressTarget = aliasTransaction_AddressTarget;
DbQueryJoin joinAddr = new DbQueryJoin(DbJoinType.LeftOuter); DbQueryJoin joinAddr = new DbQueryJoin(DbJoinType.LeftOuter);
joinAddr.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address), aliasTransaction_AddressTarget); joinAddr.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address), aliasTransaction_AddressTarget);
joinAddr.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_ItemType, aliasTransaction_AddressTarget, false) + "=" + Sbm.ItemType.Affiliate.ToString()); joinAddr.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_ItemType, aliasTransaction_AddressTarget, false) + "=" + Sbm.ItemType.Affiliate.ToString());
@@ -1935,7 +1958,8 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Mgr
bool hasColDelAddr_Email = columns.HasId((int)SbmTransaction.Column.DeliveryAddress_Email); bool hasColDelAddr_Email = columns.HasId((int)SbmTransaction.Column.DeliveryAddress_Email);
if (hasColDeliveryAddress || hasColDelAddr_Line1 || hasColDelAddr_Postcode || hasColDelAddr_Phone || hasColDelAddr_Email) if (hasColDeliveryAddress || hasColDelAddr_Line1 || hasColDelAddr_Postcode || hasColDelAddr_Phone || hasColDelAddr_Email)
{ {
// Join to the address table. // Join to the Delivery Address.
prm.TableAlias_AddressDelivery = aliasTransaction_DeliveryAddress;
DbQueryJoin joinDelAddr = new DbQueryJoin(DbJoinType.LeftOuter); DbQueryJoin joinDelAddr = new DbQueryJoin(DbJoinType.LeftOuter);
joinDelAddr.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address), aliasTransaction_DeliveryAddress); joinDelAddr.Table = new StringPair(SbmDbDfn.GetTableName(SbmDbDfn.TableIdx.Address), aliasTransaction_DeliveryAddress);
joinDelAddr.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_Type, aliasTransaction_DeliveryAddress, false) + "=" + Sbm.AddressType.Delivery); joinDelAddr.Filters.Add(SbmDbDfn.GetColumnNameQual(SbmDbDfn.ColumnIdx.Address_Type, aliasTransaction_DeliveryAddress, false) + "=" + Sbm.AddressType.Delivery);
@@ -31,7 +31,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Utils
// Open database. // Open database.
// NB Must be ODBC connection - especially to retrieve index columns. // NB Must be ODBC connection - especially to retrieve index columns.
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
config.connectionString = connectionString; config.ConnectionString = connectionString;
SacsDatabase database = SacsDatabaseConsole.OpenOdbcDatabase(config); SacsDatabase database = SacsDatabaseConsole.OpenOdbcDatabase(config);
// Generate database definition. // Generate database definition.
@@ -37,7 +37,7 @@ namespace Sarand.BusinessMgr.Net.Standard.Dbas.Utils
// Open database. // Open database.
// NB Must be ODBC connection - especially to retrieve index columns. // NB Must be ODBC connection - especially to retrieve index columns.
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
config.connectionString = connectionString; config.ConnectionString = connectionString;
SacsDatabase database = SacsDatabaseConsole.OpenOdbcDatabase(config); SacsDatabase database = SacsDatabaseConsole.OpenOdbcDatabase(config);
// Generate database definition. // Generate database definition.
@@ -15,11 +15,10 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="jQuery" Version="3.5.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Moq" Version="4.20.72" /> <PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="MSTest.TestAdapter" Version="3.6.3" /> <PackageReference Include="MSTest.TestAdapter" Version="3.6.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.6.3" /> <PackageReference Include="MSTest.TestFramework" Version="3.6.4" />
<PackageReference Include="System.Data.Odbc" Version="6.0.2" /> <PackageReference Include="System.Data.Odbc" Version="6.0.2" />
</ItemGroup> </ItemGroup>
@@ -1,12 +1,17 @@
using Microsoft.AspNetCore.Hosting; using DocumentFormat.OpenXml.EMMA;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Moq; using Moq;
using Sarand.BusinessMgr.Net.Core.Web.App; using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control; using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control;
using Sarand.BusinessMgr.Web.Control.App; using Sarand.BusinessMgr.Web.Control.App;
using Sarand.BusinessMgr.Web.Control.Consoles;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Dbas;
using System;
namespace Sarand.BusinessMgr.Test.Web.Control.App namespace Sarand.BusinessMgr.Test.Web.Control.App
{ {
@@ -37,24 +42,13 @@ namespace Sarand.BusinessMgr.Test.Web.Control.App
mockEnvironment.Setup(m => m.EnvironmentName).Returns(Environments.Development); mockEnvironment.Setup(m => m.EnvironmentName).Returns(Environments.Development);
mockEnvironment.Setup(m => m.ContentRootPath).Returns(@"D:\Sarand\Projects\Users\AHoward\VS2022\BusinessMgr\Workspace\SaBusinessMgrCoreWebControl"); mockEnvironment.Setup(m => m.ContentRootPath).Returns(@"D:\Sarand\Projects\Users\AHoward\VS2022\BusinessMgr\Workspace\SaBusinessMgrCoreWebControl");
App = new SbmApplication_Control_Test(mockConfiguration.Object, mockEnvironment.Object); App = new SbmApplication_Control_Test(mockConfiguration.Object, mockEnvironment.Object);
// Session configuration.
SessionContextIdx = App.GetSessionContextIdxs()[0];
SessionContext = App.GetSessionContextByIndex(SessionContextIdx);
Internals = new SbmInternals(GetUserContext(SessionContext));
Internals_Control = new SbmInternals_Control(); Internals_Control = new SbmInternals_Control();
UserContext = GetUserContext(SessionContext);
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Properties. // Properties.
protected ushort SessionContextIdx { get; }
protected SbmApplication_Control App { get; } protected SbmApplication_Control App { get; }
protected SbmSessionContext SessionContext { get; }
protected ISacsDatabase BusMgrDatabase { get { return App.GetBusMgrDatabase(SessionContext); } }
protected SbmInternals Internals { get; }
protected SbmInternals_Control Internals_Control { get; } protected SbmInternals_Control Internals_Control { get; }
protected SbmUserContext UserContext { get; }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// User Context. // User Context.
@@ -65,6 +59,19 @@ namespace Sarand.BusinessMgr.Test.Web.Control.App
return userContext; return userContext;
} }
//-------------------------------------------------------------------
// Core Instance Console.
protected SbmCoreInstanceConsole_Control CreateCoreInstanceConsole(String instanceContext)
{
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
SbmcRepository repository = Internals_Control.ControlInstanceMgr.GetRepositoryByContext(instanceContext);
disposables.Add(repository);
return new SbmCoreInstanceConsole_Control(repository);
}
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
} }
//======================================================================= //=======================================================================
@@ -1,4 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json; using Newtonsoft.Json;
using Sarand.BusinessMgr.Net.Core.Web.Controllers; using Sarand.BusinessMgr.Net.Core.Web.Controllers;
using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.App;
@@ -34,8 +35,6 @@ namespace Sarand.BusinessMgr.Test.Web.Control.App
{ {
// Internals. // Internals.
SaSecurityConsole securityConsole = App.CreateSecurityConsole(UserContext);
Assert.IsNotNull(securityConsole);
SbmcAccountMgr accountMgr = Internals_Control.ControlAccountMgr; SbmcAccountMgr accountMgr = Internals_Control.ControlAccountMgr;
Assert.IsNotNull(accountMgr); Assert.IsNotNull(accountMgr);
@@ -43,10 +42,15 @@ namespace Sarand.BusinessMgr.Test.Web.Control.App
SbmcUserAccount userAccount = accountMgr.GetUserAccountByEmailAddress("andy@sarand.com"); SbmcUserAccount userAccount = accountMgr.GetUserAccountByEmailAddress("andy@sarand.com");
Assert.IsNotNull(userAccount); Assert.IsNotNull(userAccount);
// Session Context?
SbmSessionContext sessionContext_Core = null;
// Populate User Session. // Populate User Session.
SbmSessionData_Control sessionData = new SbmSessionData_Control(SessionContext, userAccount); SbmSessionData_Control sessionData = new SbmSessionData_Control(sessionContext_Core, userAccount);
Assert.IsNotNull(sessionData); Assert.IsNotNull(sessionData);
Assert.IsTrue(!StringUtil.IsBlank(sessionData.Base64IV_ControlApp));
Assert.IsTrue(sessionData.SessionIdx >= 1000);
Assert.IsTrue(sessionData.ItemIdx >= 1000);
// Validate user session. // Validate user session.
Assert.IsNotNull(sessionData.User); Assert.IsNotNull(sessionData.User);
@@ -68,12 +72,9 @@ namespace Sarand.BusinessMgr.Test.Web.Control.App
Assert.IsNotNull(sessionDataDeserialized); Assert.IsNotNull(sessionDataDeserialized);
// Validate deserialised data. // Validate deserialised data.
Assert.IsTrue(!StringUtil.IsBlank(sessionData.Base64IV_ControlApp));
Assert.IsTrue(!StringUtil.IsBlank(sessionDataDeserialized.Base64IV_ControlApp)); Assert.IsTrue(!StringUtil.IsBlank(sessionDataDeserialized.Base64IV_ControlApp));
Assert.AreEqual(sessionData.Base64IV_ControlApp, sessionDataDeserialized.Base64IV_ControlApp); Assert.AreEqual(sessionData.Base64IV_ControlApp, sessionDataDeserialized.Base64IV_ControlApp);
Assert.IsTrue(sessionData.SessionIdx >= 1000);
Assert.AreEqual(sessionData.SessionIdx, sessionDataDeserialized.SessionIdx); Assert.AreEqual(sessionData.SessionIdx, sessionDataDeserialized.SessionIdx);
Assert.IsTrue(sessionData.ItemIdx >= 1000);
Assert.AreEqual(sessionData.ItemIdx, sessionDataDeserialized.ItemIdx); Assert.AreEqual(sessionData.ItemIdx, sessionDataDeserialized.ItemIdx);
// User details. // User details.
@@ -14,11 +14,10 @@
<RootNamespace>Sarand.BusinessMgr.Test</RootNamespace> <RootNamespace>Sarand.BusinessMgr.Test</RootNamespace>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="jQuery" Version="3.5.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Moq" Version="4.20.72" /> <PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="MSTest.TestAdapter" Version="3.6.3" /> <PackageReference Include="MSTest.TestAdapter" Version="3.6.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.6.3" /> <PackageReference Include="MSTest.TestFramework" Version="3.6.4" />
<PackageReference Include="coverlet.collector" Version="6.0.2"> <PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -0,0 +1,56 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Helpers;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
namespace Sarand.BusinessMgr.Test.Web.Portal.App
{
//=======================================================================
[TestClass]
public class SbmApplication_Database_Tester : SbmPortalApp_Tester_Base
{
//-------------------------------------------------------------------
private static Regex reHex = new Regex("^(?:[A-F0-9]{2})+$", RegexOptions.IgnoreCase);
//-------------------------------------------------------------------
[TestMethod]
public void Test_PasswordEncoding()
{
Assert.IsNotNull(BusMgrDatabase);
StringAssert.Matches(BusMgrDatabase.EncodePassword_Hex(""), reHex);
// Iterate using random filename (8.3).
for (int i = 0; i < 1000; i++)
StringAssert.Matches(BusMgrDatabase.EncodePassword_Hex(Path.GetRandomFileName()), reHex);
}
//-------------------------------------------------------------------
[TestMethod]
public void Test_PasswordCompare()
{
Assert.IsNotNull(BusMgrDatabase);
Dictionary<string, string> passwordHashes = new Dictionary<string, string>();
// Iterate using random filename (8.3).
for (int i = 0; i < 200; i++)
{
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));
}
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -20,6 +20,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Sarand.Net.Standard.Base.ReferenceData; using Sarand.Net.Standard.Base.ReferenceData;
using Sarand.Net.Standard.Base.Bus;
using static Sarand.Net.Standard.Dbas.Base.SacsDatabaseConsole;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Net.Standard.Base.Mgr.Control;
using Sarand.Net.Standard.Base.Security;
namespace Sarand.BusinessMgr.Web.Control.App namespace Sarand.BusinessMgr.Web.Control.App
{ {
@@ -30,6 +35,7 @@ namespace Sarand.BusinessMgr.Web.Control.App
// Data members. // Data members.
private bool generateDatabaseDefinitions_Control = false; private bool generateDatabaseDefinitions_Control = false;
private bool generateDatabaseDefinitions_BusMgr = false; private bool generateDatabaseDefinitions_BusMgr = false;
private static SbmApplication_Control appInstance;
private PropertySet propertySet; private PropertySet propertySet;
private Dictionary<String, Net.Core.Web.App.SbmAppConfig> appConfigs = new Dictionary<string, Net.Core.Web.App.SbmAppConfig>(); private Dictionary<String, Net.Core.Web.App.SbmAppConfig> appConfigs = new Dictionary<string, Net.Core.Web.App.SbmAppConfig>();
private Dictionary<String, SbmEmailConfig> emailConfigs = new Dictionary<string, SbmEmailConfig>(); private Dictionary<String, SbmEmailConfig> emailConfigs = new Dictionary<string, SbmEmailConfig>();
@@ -37,29 +43,45 @@ namespace Sarand.BusinessMgr.Web.Control.App
// Singular databases. // Singular databases.
private ISacsDatabase controlDatabase = null; private ISacsDatabase controlDatabase = null;
private ISacsDatabase templateDatabase = null; private ISacsDatabase templateDatabase = null;
// Session contexts. // Core Session contexts - to access Core database via repository configuration.
private static ushort sessionContextIdx_Next = 100; private static ushort sessionContextIdx_Next = 101;
private class SessionContextData private class CoreInstanceContextData
{ {
public SessionContextData(SbmSessionContext_Web sessionContext) public CoreInstanceContextData(SbmSessionContext_Web sessionContext, SysId controlOwnerId, SysId controlRepositoryId)
{ {
SessionContext = sessionContext; SessionContext = sessionContext;
ControlOwnerId = controlOwnerId;
ControlRepositoryId = controlRepositoryId;
} }
public SbmSessionContext_Web SessionContext { get; } public SbmSessionContext_Web SessionContext { get; }
public SysId ControlOwnerId { get; }
public SysId ControlRepositoryId { get; }
public HashSet<string> RepositoryContexts { get; } = new HashSet<string>(); public HashSet<string> RepositoryContexts { get; } = new HashSet<string>();
public ISacsDatabase BusMgrDatabase { get; set; } public ISacsDatabase BusMgrDatabase { get; set; }
// Core Instance config.
private SbmInstanceConfig instanceConfig = null;
public SbmInstanceConfig InstanceConfig
{
get
{
if (instanceConfig == null)
instanceConfig = new SbmInstanceConfig_Control(ControlOwnerId, ControlRepositoryId);
return instanceConfig;
} }
private readonly Dictionary<ushort, SessionContextData> sessionContexts = new Dictionary<ushort, SessionContextData>(); }
}
private readonly Dictionary<ushort, CoreInstanceContextData> coreInstances = new Dictionary<ushort, CoreInstanceContextData>();
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Construction. // Construction.
public SbmApplication_Control(IConfiguration configuration) public SbmApplication_Control(IConfiguration configuration)
{ {
appInstance = this;
InitialiseTemporaryLoggingFolder(); InitialiseTemporaryLoggingFolder();
try try
{ {
propertySet = new PropertySet(); propertySet = new PropertySet();
SbmGlobals.System = (System_Web = new SbmSystem_Web(propertySet)); SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Web(propertySet)));
Configuration = configuration; Configuration = configuration;
} }
catch (Exception exc) catch (Exception exc)
@@ -71,53 +93,94 @@ namespace Sarand.BusinessMgr.Web.Control.App
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Properties. // Properties.
public static SbmApplication_Control Instance { get { return appInstance; } }
// Application Configuration. // Application Configuration.
public override Net.Core.Web.App.SbmAppConfig AppConfig { get { return appConfigs.Values.ToList().getConfigForApplication(); } } public override Net.Core.Web.App.SbmAppConfig AppConfig { get { return appConfigs.Values.ToList().getConfigForApplication(); } }
// Session Configuration. // Session Configuration.
public override String SessionCookieName { get { return Sbm.Config.Control.Session.Cookie.Name; } } public override String SessionCookieName { get { return Sbm.Config.Control.Session.Cookie.Name; } }
public override List<ushort> GetSessionContextIdxs() public override List<ushort> GetSessionContextIdxs()
{ {
return sessionContexts.Values.Select(item => item.SessionContext.Index).ToList(); return coreInstances.Values.Select(item => item.SessionContext.Index).ToList();
} }
public override SbmSessionContext GetSessionContextByIndex(ushort index) public override SbmSessionContext GetSessionContextByIndex(ushort index)
{ {
return sessionContexts.GetValue(index, null)?.SessionContext ?? null; return coreInstances.GetValue(index, null)?.SessionContext ?? null;
} }
public override List<SbmSessionContext> GetSessionContexts() public override List<SbmSessionContext> GetSessionContexts()
{ {
return new List<SbmSessionContext>(sessionContexts.Values.Select(item => item.SessionContext)); return new List<SbmSessionContext>(coreInstances.Values.Select(item => item.SessionContext));
} }
/// <summary>
/// Identify the Core session context by the Repository Id.
/// <para>If context not yet defined for Repository, load and then return index.</para>
/// <para>If repository not found, return 0.</para>
/// </summary>
public ushort GetCoreSessionIndexForControlRepository(SysId ownerId, SysId repositoryId)
{
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
CoreInstanceContextData sessionContext = coreInstances.Values.FirstOrDefault(item => item.ControlRepositoryId.Equals(repositoryId));
if (sessionContext != null) return sessionContext.SessionContext.Index;
// Repository context not yet loaded.
SbmcInstanceMgr instanceMgr = System.CreateControlInstanceMgr();
disposables.Add(instanceMgr);
SbmcRepository repository = instanceMgr.GetRepositoryById(repositoryId);
disposables.Add(repository);
if (repository != null)
{
// Core database connection.
SacsDatabaseConsole.OdbcConfig odbcConfig = SbmCoreInstanceConsole_Control.GetRepositoryOdbcConfig(repository);
SacsDatabase busMgrDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
if (busMgrDatabase.HasErrorState())
SaLogger.Warn($"{SysUtil.Fn} BusMgr Database: " + busMgrDatabase.DatabaseName + ". Initialisation error: " + busMgrDatabase.ErrorStateMessage);
// Session context.
ushort sessionContextIdx = sessionContextIdx_Next++;
if (sessionContextIdx_Control < 1)
sessionContextIdx_Control = sessionContextIdx;
CoreInstanceContextData sessionContextData = new CoreInstanceContextData(new SbmSessionContext_Web(sessionContextIdx, Sbm.Application.WebControl), ownerId, repositoryId);
sessionContextData.RepositoryContexts.Add(repository.Context);
sessionContextData.BusMgrDatabase = busMgrDatabase;
coreInstances.Add(sessionContextData.SessionContext.Index, sessionContextData);
return sessionContextData.SessionContext.Index;
}
}
return 0;
}
// Databases. // Databases.
public override ISacsDatabase GetControlDatabase() public override ISacsDatabase GetControlDatabase() { return controlDatabase; }
{ public override ISacsDatabase GetTemplateDatabase() { return templateDatabase; }
return controlDatabase;
}
public override ISacsDatabase GetTemplateDatabase()
{
return templateDatabase;
}
public override HashSet<string> GetRepositoryContexts(SbmSessionContext sessionContext) public override HashSet<string> GetRepositoryContexts(SbmSessionContext sessionContext)
{ {
return sessionContexts.GetValue(sessionContext.Index, null)?.RepositoryContexts ?? new HashSet<string>(); return coreInstances.GetValue(sessionContext.Index, null)?.RepositoryContexts ?? new HashSet<string>();
} }
public override ISacsDatabase GetBusMgrDatabase(SbmSessionContext sessionContext) public override ISacsDatabase GetBusMgrDatabase(SbmSessionContext sessionContext)
{ {
return sessionContexts.GetValue(sessionContext.Index, null)?.BusMgrDatabase; return coreInstances.GetValue(sessionContext.Index, null)?.BusMgrDatabase;
} }
// Instance configuration. // Instance configuration.
public override SbmInstanceConfig GetInstanceConfig(SbmSessionContext sessionContext) public override SbmInstanceConfig GetInstanceConfig(SbmSessionContext sessionContext)
{ {
throw new NotSupportedException("InstanceConfig not supported in Control application."); return coreInstances.GetValue(sessionContext.Index, null)?.InstanceConfig;
} }
// Email configuration. // Email configuration.
public override SbmEmailConfig EmailConfig { get { return emailConfigs.Values.ToList().getConfigForSession(AppConfig); } } public override SbmEmailConfig EmailConfig { get { return emailConfigs.Values.ToList().getConfigForSession(AppConfig); } }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Create Consoles. // Consoles.
//-------------------------------------------------------------------
public override SaSecurityConsole CreateSecurityConsole(ISbmUserContext_Core userContext)
{
return new SbmSecurityConsole_Web(userContext);
}
public override SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserContext_Core userContext) public override SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserContext_Core userContext)
{ {
return null; return null;
} }
public override SbmEmailConsole CreateEmailConsole(ISbmUserContext_Core userContext) public override SbmEmailConsole CreateEmailConsole(ISbmUserContext_Core userContext)
{ {
return new SbmEmailConsole_Control(EmailConfig); return new SbmEmailConsole_Control(EmailConfig);
@@ -173,9 +236,9 @@ namespace Sarand.BusinessMgr.Web.Control.App
// Control database connection. // Control database connection.
SacsDatabaseConsole.OdbcConfig odbcConfig = new SacsDatabaseConsole.OdbcConfig(); SacsDatabaseConsole.OdbcConfig odbcConfig = new SacsDatabaseConsole.OdbcConfig();
odbcConfig.location = AppConfig.ControlDatabase.Location; odbcConfig.Location = AppConfig.ControlDatabase.Location;
odbcConfig.user = AppConfig.ControlDatabase.User; odbcConfig.User = AppConfig.ControlDatabase.User;
odbcConfig.pword = AppConfig.ControlDatabase.Password; odbcConfig.Password = AppConfig.ControlDatabase.Password;
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);
@@ -184,34 +247,13 @@ namespace Sarand.BusinessMgr.Web.Control.App
if (AppConfig.TemplateDatabase != null) if (AppConfig.TemplateDatabase != null)
{ {
odbcConfig = new SacsDatabaseConsole.OdbcConfig(); odbcConfig = new SacsDatabaseConsole.OdbcConfig();
odbcConfig.location = AppConfig.TemplateDatabase.Location; odbcConfig.Location = AppConfig.TemplateDatabase.Location;
odbcConfig.user = AppConfig.TemplateDatabase.User; odbcConfig.User = AppConfig.TemplateDatabase.User;
odbcConfig.pword = AppConfig.TemplateDatabase.Password; odbcConfig.Password = AppConfig.TemplateDatabase.Password;
templateDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig); templateDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
if (templateDatabase.HasErrorState()) if (templateDatabase.HasErrorState())
SaLogger.Warn($"{SysUtil.Fn} Template Database initialisation error: " + controlDatabase.ErrorStateMessage); SaLogger.Warn($"{SysUtil.Fn} Template Database initialisation error: " + controlDatabase.ErrorStateMessage);
} }
// BusinessMgr database connections.
foreach (Net.Core.Web.App.SbmAppConfig.DatabaseConfig dbConfig in AppConfig.BusMgrDatabases)
{
odbcConfig = new SacsDatabaseConsole.OdbcConfig();
odbcConfig.location = dbConfig.Location;
odbcConfig.user = dbConfig.User;
odbcConfig.pword = dbConfig.Password;
SacsDatabase busMgrDatabase = SacsDatabaseConsole.OpenOdbcDatabase(odbcConfig);
if (busMgrDatabase.HasErrorState())
SaLogger.Warn($"{SysUtil.Fn} BusMgr Database: " + busMgrDatabase.DatabaseName + ". Initialisation error: " + busMgrDatabase.ErrorStateMessage);
// Session context.
ushort sessionContextIdx = sessionContextIdx_Next++;
if (sessionContextIdx_Control < 1)
sessionContextIdx_Control = sessionContextIdx;
SessionContextData sessionContextData = new SessionContextData(new SbmSessionContext_Web(sessionContextIdx, Sbm.Application.WebControl));
sessionContextData.RepositoryContexts.UnionWith(dbConfig.Identifiers);
sessionContextData.BusMgrDatabase = busMgrDatabase;
sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData);
}
} }
catch (Exception exc) catch (Exception exc)
{ {
@@ -225,9 +267,9 @@ namespace Sarand.BusinessMgr.Web.Control.App
{ {
// Use the 'template' database connection parameters. // Use the 'template' database connection parameters.
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
config.location = AppConfig.TemplateDatabase.Location; config.Location = AppConfig.TemplateDatabase.Location;
config.user = AppConfig.TemplateDatabase.User; config.User = AppConfig.TemplateDatabase.User;
config.pword = AppConfig.TemplateDatabase.Password; config.Password = AppConfig.TemplateDatabase.Password;
GenerateDatabaseDefinition(SbmDbDfnGenerator.DatabaseInstance.Core, GetTemplateDatabase()); GenerateDatabaseDefinition(SbmDbDfnGenerator.DatabaseInstance.Core, GetTemplateDatabase());
} }
} }
@@ -106,6 +106,28 @@ namespace Sarand.BusinessMgr.Web.Control.App
/// <summary>User - JSON deserialisation route.</summary> /// <summary>User - JSON deserialisation route.</summary>
public UserData_Control User { get; private set; } public UserData_Control User { get; private set; }
//-------------------------------------------------------------------
/// <summary>
/// User Profile.
/// <para>- Filter settings.</para>
/// </summary>
public class UserProfileData
{
public UserProfileData() { }
// Common filter.
public class FilterData
{
/// <summary>Id for currently selected Association.</summary>
public String InstanceContext { get; set; }
}
/// <summary>
/// Common filter properties.
/// </summary>
public FilterData Filter { get; private set; } = new FilterData();
}
public UserProfileData Profile { get; protected set; } = new UserProfileData();
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Control application encryption IV value - for consistent encryption during session. // Control application encryption IV value - for consistent encryption during session.
public String Base64IV_ControlApp { get; private set; } = SacsEncryptionHelper.InitSymmetricEncryptionIV(SbmController_Control.Base64Key_ControlApp); public String Base64IV_ControlApp { get; private set; } = SacsEncryptionHelper.InitSymmetricEncryptionIV(SbmController_Control.Base64Key_ControlApp);
@@ -0,0 +1,94 @@
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
using Sarand.BusinessMgr.Web.Control.App;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Security;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Dbas.Base;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sarand.BusinessMgr.Web.Control.Consoles
{
//=======================================================================
public class SbmCoreInstanceConsole_Control : SbmCoreInstanceConsole_Base
{
//-------------------------------------------------------------------
// Definitions.
//-------------------------------------------------------------------
// Data members.
private readonly SacsDatabase coreDatabase;
private readonly SysId organisationId;
private readonly SysId repositoryId;
private SbmInternals internals;
//-------------------------------------------------------------------
// Construction.
public SbmCoreInstanceConsole_Control(SbmcRepository repository)
{
organisationId = repository.OwnerId;
repositoryId = repository.Id;
// Repository connection.
SacsDatabaseConsole.OdbcConfig config = GetRepositoryOdbcConfig(repository);
coreDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config);
if (coreDatabase.HasErrorState())
SetErrorState(coreDatabase.ErrorStateMessage);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
public SbmApplication_Control App { get { return SbmApplication_Control.Instance; } }
public override ISacsDatabase Database_Core { get { return coreDatabase; } }
public override SbmInternals Internals_Core { get { if (internals == null) { internals = CreateCoreInternals(); } return internals; } }
public override DbUpdateInfo DbUpdateInfo_Core { get { return Internals_Core.DbUpdateInfo; } }
//-------------------------------------------------------------------
// Utilities.
public static SacsDatabaseConsole.OdbcConfig GetRepositoryOdbcConfig(SbmcRepository repository)
{
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
config.Location = $"MsSql:{repository.ServerName}\\{repository.InstanceName}.{repository.DatabaseName}";
config.User = repository.UserName;
config.Password = repository.Password;
return config;
}
/// <summary>Core internals for accessing core managers etc.</summary>
public SbmInternals CreateCoreInternals()
{
ushort sessionIndex = App.GetCoreSessionIndexForControlRepository(organisationId, repositoryId);
SbmSessionContext sessionContext = new SbmSessionContext_Web(sessionIndex, Sbm.Application.WebControl);
SbmUserContext userContext = new SbmUserContext_Web(sessionContext);
return new SbmInternals(userContext);
}
/// <summary>
/// Create core security console.
/// </summary>
/// <returns></returns>
public override SaSecurityConsole CreateSecurityConsole()
{
return App.CreateSecurityConsole(internals.UserContext);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -185,7 +185,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Account
{ {
// Identify item. // Identify item.
SysId userAccountId = model.User.Id.ToSysId(); SysId userAccountId = SysId.ToSysId(model.User.Id);
if (!SysId.IsValid(userAccountId)) if (!SysId.IsValid(userAccountId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -265,7 +265,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Account
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId userAccountId = model.User.Id.ToSysId(); SysId userAccountId = SysId.ToSysId(model.User.Id);
if (StringUtil.ToBool(model.User.Exists) && !SysId.IsValid(userAccountId)) if (StringUtil.ToBool(model.User.Exists) && !SysId.IsValid(userAccountId))
{ {
SaLogger.Warn($"{SysUtil.Fn} User Id not supplied for existing item."); SaLogger.Warn($"{SysUtil.Fn} User Id not supplied for existing item.");
@@ -366,7 +366,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Account
{ {
// Retrieve user. // Retrieve user.
SysId userAccountId = model.User.Id.ToSysId(); SysId userAccountId = SysId.ToSysId(model.User.Id);
SbmcUserAccount userAccount = ControlAccountMgr.GetUserAccountById(userAccountId); SbmcUserAccount userAccount = ControlAccountMgr.GetUserAccountById(userAccountId);
disposables.Add(userAccount); disposables.Add(userAccount);
if (userAccount == null) if (userAccount == null)
@@ -0,0 +1,139 @@
using DocumentFormat.OpenXml.Drawing.Charts;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Web.Control.Consoles;
using Sarand.BusinessMgr.Web.Control.Models;
using Sarand.BusinessMgr.Web.Control.Models.Instance;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
{
//=======================================================================
partial class CoreDatabaseController
{
//-------------------------------------------------------------------
// Definitions.
// Core Database Table list data.
private class TableListData : AjaxResponse_Data.ItemData_Base
{
public String SchemaName { get; set; }
public String TableName { get; set; }
public long? ColumnCount { get; set; }
public long? IndexCount { get; set; }
public long? RowCount { get; set; }
}
//-------------------------------------------------------------------
// Get Core Database Table list ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_CoreDatabaseTableList : AjaxResponse_Data
{
// Construction.
public AjaxResponse_CoreDatabaseTableList(SbmModel_Control model) : base(model) { }
// CoreDatabase list.
public List<TableListData> Tables { get; } = new List<TableListData>();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Instance/CoreDatabase/Ajax/GetTableList")]
[Route("Instance/CoreDatabase/Ajax/GetTables")]
public IActionResult Ajax_GetTableList(Model_CoreDatabase model)
{
String messageTitle = Localiser["label.database"];
AjaxResponse_CoreDatabaseTableList responseData = new AjaxResponse_CoreDatabaseTableList(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// Validate Repository.
SessionData_Control.Profile.Filter.InstanceContext = model.Filter.Context;
if (StringUtil.IsBlank(model.Filter.Context))
{
SaLogger.Warn($"{SysUtil.Fn} Instance Context not supplied.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
SbmcRepository repository = ControlInstanceMgr.GetRepositoryByContext(model.Filter.Context);
disposables.Add(repository);
if (repository == null)
{
SaLogger.Warn($"{SysUtil.Fn} Repository does not exist. Context: {model.Filter.Context}.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Repository Console.
SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(repository);
disposables.Add(instanceConsole);
// Columns.
String colSchemaName = "SchemaName";
String colTableName = "TableName";
String colColumnCount = "ColumnCount";
String colIndexCount = "IndexCount";
String colRowCount = "RowCount";
// Table filter.
List<String> filter = new List<string>();
if (!StringUtil.IsBlank(model.Filter.Search))
filter.Add($"tbl.name Like '%{DbQuery.FormatForLike(model.Filter.Search)}%'");
if (!filter.Any()) filter.Add("1=1");
// Construction query.
List<String> sql = new List<string>()
{
$"Select Top 2000",
$"[{colSchemaName}]=sch.name, [{colTableName}]=tbl.name,",
$"[{colColumnCount}]=(Select Count(*) From sys.columns col Where col.object_id=tbl.object_id),",
$"[{colIndexCount}]=(Select Count(*) From sys.indexes idx Where idx.object_id=tbl.object_id),",
$"[{colRowCount}]=(Select Sum(ptn.rows) From sys.partitions ptn Where ptn.object_id=tbl.object_id And ptn.index_id<2)",
$"From sys.tables tbl",
$"Left Join sys.schemas sch On sch.schema_id=tbl.schema_id",
$"Where tbl.type='U' And {filter.Concat(" And ","(",")")}",
$"Order By tbl.name, sch.name;"
};
// Query items.
using (DbResultSet resultSet = instanceConsole.Database_Core.ExecuteQuery(String.Join("\n", sql)))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
TableListData tableData = new TableListData()
{
SchemaName = values.GetString(colSchemaName),
TableName = values.GetString(colTableName),
ColumnCount = values.GetLong(colColumnCount),
IndexCount = values.GetLong(colIndexCount),
RowCount = values.GetLong(colRowCount),
};
responseData.Tables.Add(tableData);
}
}
if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Tables.Count;
}
// Complete response.
responseData.SetPaging(model);
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,46 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Web.Control.Models.Instance;
namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
{
//======================================================================
public partial class CoreDatabaseController : SbmController_Control
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
public CoreDatabaseController(SbmLocaliser localiser, ILogger<CoreDatabaseController> logger) :
base(localiser, logger)
{
}
//-------------------------------------------------------------------
[Route("Instance/CoreDatabase")]
public IActionResult Index(Model_CoreDatabase model)
{
if (!ValidUserSession)
AutoLoginUser();
// Redirect to sign-in if not signed-in.
if (!ValidUserSession)
{
ClearKeepLoggedInCookie();
return RedirectToAction("", "Security");
}
// Refresh model.
RefreshModel(model);
model.Filter.Context = SessionData_Control.Profile.Filter.InstanceContext;
// Core Database view.
return View("Views/Instance/CoreDatabase/Index.cshtml", model);
}
//-------------------------------------------------------------------
}
//======================================================================
}
@@ -169,7 +169,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
{ {
// Identify item. // Identify item.
SysId ownerId = model.Owner.Id.ToSysId(); SysId ownerId = SysId.ToSysId(model.Owner.Id);
if (!SysId.IsValid(ownerId)) if (!SysId.IsValid(ownerId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -206,7 +206,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId ownerId = model.Owner.Id.ToSysId(); SysId ownerId = SysId.ToSysId(model.Owner.Id);
if (StringUtil.ToBool(model.Owner.Exists) && !SysId.IsValid(ownerId)) if (StringUtil.ToBool(model.Owner.Exists) && !SysId.IsValid(ownerId))
{ {
SaLogger.Warn($"{SysUtil.Fn} Owner Id not supplied for existing item."); SaLogger.Warn($"{SysUtil.Fn} Owner Id not supplied for existing item.");
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Web.Control.Consoles;
using Sarand.BusinessMgr.Web.Control.Models; using Sarand.BusinessMgr.Web.Control.Models;
using Sarand.BusinessMgr.Web.Control.Models.Instance; using Sarand.BusinessMgr.Web.Control.Models.Instance;
using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.App;
@@ -7,6 +8,7 @@ using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Dbas.Base;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Security; using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Security;
@@ -168,7 +170,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
{ {
// Identify item. // Identify item.
SysId repositoryId = model.Repository.Id.ToSysId(); SysId repositoryId = SysId.ToSysId(model.Repository.Id);
if (!SysId.IsValid(repositoryId)) if (!SysId.IsValid(repositoryId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -197,6 +199,82 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
return Json(responseData); return Json(responseData);
} }
//-------------------------------------------------------------------
// Get Repository ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_RepositoryInfo : AjaxResponse_Data
{
// Construction.
public AjaxResponse_RepositoryInfo(SbmModel_Control model) : base(model) { }
// Repository details.
public class RepositoryInfoData : AjaxResponse_Data.ItemData_Base
{
public byte? Initialised { get; set; }
/// <summary>Tooltip text if database uninitialised.</summary>
public String Uninitialised { get; set; }
/// <summary>Tooltip text if database unavailable.</summary>
public String Unavailable { get; set; }
}
public RepositoryInfoData repository { get; } = new RepositoryInfoData();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Instance/Repository/Ajax/GetItemInfo")]
[Route("Instance/Repository/Ajax/GetRepositoryInfo")]
[Route("Instance/Repository/Ajax/GetRepoInfo")]
public IActionResult Ajax_GetRepositoryInfo(Model_Repository model)
{
String messageTitle = Localiser["label.repository"];
AjaxResponse_RepositoryInfo responseData = new AjaxResponse_RepositoryInfo(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
// Identify item.
SysId repositoryId = SysId.ToSysId(model.Repository.Id);
if (!SysId.IsValid(repositoryId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
// Retrieve item.
SbmcRepository repository = ControlInstanceMgr.GetRepositoryById(repositoryId);
disposables.Add(repository);
if (repository == null)
{
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve repository for Id: '" + repositoryId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
responseData.repository.Id = SysId.ToString(repository.Id);
// Repository console.
SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(repository);
if (!instanceConsole.HasErrorState())
{
// Validate database.
if (instanceConsole.IsRepositoryValid())
{
// Check whether repository is initialised.
if (instanceConsole.IsRepositoryInitialised())
{
responseData.repository.Initialised = 1;
}
else responseData.repository.Uninitialised = instanceConsole.ErrorStateMessage;
}
else responseData.repository.Unavailable = instanceConsole.ErrorStateMessage;
}
else responseData.repository.Unavailable = instanceConsole.ErrorStateMessage;
// Complete response.
responseData.Success = true;
}
return Json(responseData);
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Store Repository ajax request. // Store Repository ajax request.
//------------------------------------------------------------------- //-------------------------------------------------------------------
@@ -214,7 +292,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId repositoryId = model.Repository.Id.ToSysId(); SysId repositoryId = SysId.ToSysId(model.Repository.Id);
if (StringUtil.ToBool(model.Repository.Exists) && !SysId.IsValid(repositoryId)) if (StringUtil.ToBool(model.Repository.Exists) && !SysId.IsValid(repositoryId))
{ {
SaLogger.Warn($"{SysUtil.Fn} Repository Id not supplied for existing item."); SaLogger.Warn($"{SysUtil.Fn} Repository Id not supplied for existing item.");
@@ -245,7 +323,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
} }
// Owner. // Owner.
SysId ownerId = repository?.OwnerId ?? StringUtil.ToSysId(model.Repository.OwnerId); SysId ownerId = repository?.OwnerId ?? SysId.ToSysId(model.Repository.OwnerId);
SbmcOwner owner = ControlInstanceMgr.GetOwnerById(ownerId); SbmcOwner owner = ControlInstanceMgr.GetOwnerById(ownerId);
disposables.Add(owner); disposables.Add(owner);
if (owner == null) if (owner == null)
@@ -0,0 +1,279 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Core.Web.Consoles;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
using Sarand.BusinessMgr.Web.Control.Consoles;
using Sarand.BusinessMgr.Web.Control.Models;
using Sarand.BusinessMgr.Web.Control.Models.Instance;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Security;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance
{
//=======================================================================
public partial class RepositoryInitController : SbmController_Control
{
//-------------------------------------------------------------------
// Definitions.
// Repository data.
/// <summary>
/// Repository initialisation data.
/// <para>- May have multiple (internal) Organisations.</para>
/// <para>- Each Organisation may have multiple 'Superuser' users.</para>
/// </summary>
public class RepositoryData
{
// Repository data.
public String Id { get; set; }
public String OwnerId { get; set; }
public String OwnerName { get; set; }
public String Context { get; set; }
// Organisations.
public List<RepositoryOrganisationData> Organisations { get; } = new List<RepositoryOrganisationData>();
}
public class RepositoryOrganisationData
{
// Organisation data.
public String AffiliateId { get; set; }
public String AssociationId { get; set; }
public String Name { get; set; }
public String Website { get; set; }
public String CompanyNo { get; set; }
public String VatReg { get; set; }
// Registered users.
public List<RepositoryUserData> Users { get; } = new List<RepositoryUserData>();
}
public class RepositoryUserData
{
public String AffiliateId { get; set; }
public String SecurityItemId { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Email { get; set; }
public String Code { get; set; }
public String Password { get; set; }
}
//-------------------------------------------------------------------
// Construction.
public RepositoryInitController(SbmLocaliser localiser, ILogger<RepositoryController> logger) :
base(localiser, logger)
{
}
//-------------------------------------------------------------------
// Get Repository Initialisation Info ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_RepositoryInitInfo : AjaxResponse_Data
{
// Construction.
public AjaxResponse_RepositoryInitInfo(SbmModel_Control model) : base(model) { }
// Repository initialisation info.
public RepositoryData Repository { get; } = new RepositoryData();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Instance/Repository/Ajax/GetInitInfo")]
public IActionResult Ajax_GetRepositoryInitInfo(Model_RepositoryInit model)
{
String messageTitle = Localiser["label.repository"];
AjaxResponse_RepositoryInitInfo responseData = new AjaxResponse_RepositoryInitInfo(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// Validate Repository.
SysId repositoryId = SysId.ToSysId(model.Repository.Id);
if (!SysId.IsValid(repositoryId))
{
SaLogger.Warn($"{SysUtil.Fn} Repository Id not supplied.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
SbmcRepository repository = ControlInstanceMgr.GetRepositoryById(repositoryId);
disposables.Add(repository);
if (repository == null)
{
SaLogger.Warn($"{SysUtil.Fn} Repository does not exist. Id: {repositoryId}.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
responseData.Repository.Id = $"{SysId.ToLong(repository.Id)}";
responseData.Repository.Context = repository.Context;
// Owner.
SbmcOwner owner = ControlInstanceMgr.GetOwnerById(repository.OwnerId);
disposables.Add(owner);
if (owner == null)
{
SaLogger.Warn($"{SysUtil.Fn} Owner does not exist. Id: {repository.OwnerId}.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
responseData.Repository.OwnerId = $"{SysId.ToLong(owner.Id)}";
responseData.Repository.OwnerName = owner.Name;
// Repository Console.
SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(repository);
disposables.Add(instanceConsole);
// Core internals.
SbmInternals internals = instanceConsole.CreateCoreInternals();
disposables.Add(internals);
// Core security console.
SaSecurityConsole securityConsole = App.CreateSecurityConsole(internals.UserContext);
disposables.Add(securityConsole);
// Query Organisations.
SbmAssociation.Params prm = new SbmAssociation.Params();
prm.AssociationType = Sbm.AssociationType.Internal;
prm.StatusCat = SbmAssociation.StatusCat.Current;
foreach (SbmAssociation association in internals.AccountMgr.GetAssociationList(prm))
{
// Retrieve Organisation details.
disposables.Add(association);
SbmAffiliate affiliateOrganisation = internals.AccountMgr.GetAffiliateById(association.AffiliateIdOwner);
disposables.Add(affiliateOrganisation);
// Organisation details.
RepositoryOrganisationData organisation = new RepositoryOrganisationData()
{
AssociationId = SysId.ToString(association.Id),
AffiliateId = SysId.ToString(affiliateOrganisation.Id),
Name = affiliateOrganisation.Name,
Website = affiliateOrganisation.Website,
CompanyNo = affiliateOrganisation.CompanyNo,
VatReg = affiliateOrganisation.VatReg,
};
// Retrieve user details.
SbmAffiliate.Params prmAffiliateUser = new SbmAffiliate.Params();
prmAffiliateUser.AffiliateIdAssocOwner = affiliateOrganisation.Id;
prmAffiliateUser.AssociationType = Sbm.AssociationType.Member;
prmAffiliateUser.StatusCat = SbmAffiliate.StatusCat.CurrentOnly;
foreach (SbmAffiliate affiliateUser in internals.AccountMgr.GetAffiliateList(prmAffiliateUser))
{
disposables.Add(affiliateUser);
// Lookup security details.
if (!SysId.IsValid(affiliateUser.UserId)) continue;
SaSecurityItem securityUser = securityConsole.GetSecurityItemById(SaSecurity.ItemType.User, affiliateUser.UserId);
disposables.Add(securityUser);
if (securityUser == null) continue;
// Confirm security rights (SuperUser).
SaSecurityProfile securityProfile = securityConsole.GetUserSecurityProfile(securityUser.Id);
if (!securityProfile.Rights.Any(right => right.Code.EqualsCI(SaSecurityConsole.GroupCode_Super))) continue;
// Add User to the Organisation.
RepositoryUserData userData = new RepositoryUserData()
{
FirstName = affiliateUser.FirstName,
LastName = affiliateUser.LastName,
Email = StringUtil.OnBlank(securityUser.EmailAddress, affiliateUser.Email),
Code = securityUser.Code,
};
organisation.Users.Add(userData);
}
// Add this Organisation to the list.
responseData.Repository.Organisations.Add(organisation);
}
// Complete response.
responseData.Success = true;
}
return Json(responseData);
}
//-------------------------------------------------------------------
// Initialise Repository ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_RepositoryInitialise : AjaxResponse_Data
{
// Construction.
public AjaxResponse_RepositoryInitialise(SbmModel_Control model) : base(model) { }
}
[HttpPost]
[Route("Instance/Repository/Ajax/Initialise")]
public IActionResult Ajax_StoreRepository(Model_RepositoryInit model)
{
String messageTitle = Localiser["label.repository"];
AjaxResponse_RepositoryInitialise responseData = new AjaxResponse_RepositoryInitialise(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
// Validate Repository.
SysId repositoryId = SysId.ToSysId(model.Repository.Id);
if (!SysId.IsValid(repositoryId))
{
SaLogger.Warn($"{SysUtil.Fn} Repository Id not supplied.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
SbmcRepository repository = ControlInstanceMgr.GetRepositoryById(repositoryId);
disposables.Add(repository);
if (repository == null)
{
SaLogger.Warn($"{SysUtil.Fn} Repository does not exist. Id: {repositoryId}.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Validate item properties.
model.ValidateRepositoryData(responseData, repository);
if (responseData.HasControlErrors())
return Json(responseData);
// Repository Console.
SbmCoreInstanceConsole_Control repositoryConsole = new SbmCoreInstanceConsole_Control(repository);
disposables.Add(repositoryConsole);
SbmCoreInstanceConsole_Base.RepositoryInitialisationData repoInitData = new SbmCoreInstanceConsole_Base.RepositoryInitialisationData();
repoInitData.Organisation.AffiliateId = SysId.ToSysId(model.Organisation.AffiliateId);
repoInitData.Organisation.AssociationId = SysId.ToSysId(model.Organisation.AssociationId);
repoInitData.Organisation.Name = model.Organisation.Name;
repoInitData.Organisation.VatReg = model.Organisation.VatReg;
repoInitData.Organisation.CompanyNo = model.Organisation.CompanyNo;
repoInitData.Organisation.Website = model.Organisation.Website;
repoInitData.User.AffiliateId = SysId.ToSysId(model.User.AffiliateId);
repoInitData.User.FirstName = model.User.FirstName;
repoInitData.User.LastName = model.User.LastName;
repoInitData.User.Email = model.User.Email;
repoInitData.User.SecurityItemId = SysId.ToSysId(model.User.SecurityItemId);
repoInitData.User.Code = model.User.Code;
repoInitData.User.Password = model.User.Password;
if (!repositoryConsole.InitialiseRepository(repoInitData))
return Json(responseData.SetMessage(messageTitle, repositoryConsole.ErrorStateMessage));
// Complete response.
responseData.Success = true;
}
return Json(responseData);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -200,7 +200,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Param
// Item filter. // Item filter.
SbmcItemParam.Params prmParam = new SbmcItemParam.Params(); SbmcItemParam.Params prmParam = new SbmcItemParam.Params();
ItemId itemId = new ItemId(StringUtil.ToShort(model.Filter.ItemType), StringUtil.ToSysId(model.Filter.ItemId)); ItemId itemId = new ItemId(StringUtil.ToShort(model.Filter.ItemType), SysId.ToSysId(model.Filter.ItemId));
if (ItemId.IsValid(itemId)) if (ItemId.IsValid(itemId))
prmParam.ItemIdsIncluded.Add(itemId); prmParam.ItemIdsIncluded.Add(itemId);
prmParam.Search = model.Filter.Search; prmParam.Search = model.Filter.Search;
@@ -284,7 +284,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Param
{ {
// Identify item. // Identify item.
SysId itemParamId = model.Param.Id.ToSysId(); SysId itemParamId = SysId.ToSysId(model.Param.Id);
if (!SysId.IsValid(itemParamId)) if (!SysId.IsValid(itemParamId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -321,7 +321,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Param
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId itemParamId = model.Param.Id.ToSysId(); SysId itemParamId = SysId.ToSysId(model.Param.Id);
if (StringUtil.ToBool(model.Param.Exists) && !SysId.IsValid(itemParamId)) if (StringUtil.ToBool(model.Param.Exists) && !SysId.IsValid(itemParamId))
{ {
SaLogger.Warn($"{SysUtil.Fn} Id not supplied for existing Item Param."); SaLogger.Warn($"{SysUtil.Fn} Id not supplied for existing Item Param.");
@@ -352,7 +352,7 @@ namespace Sarand.BusinessMgr.Web.Control.Controllers.Param
} }
// Contruct item id. // Contruct item id.
ItemId itemId = new ItemId(StringUtil.ToShort(model.Param.ItemType), model.Param.ItemId.ToSysId()); ItemId itemId = new ItemId(StringUtil.ToShort(model.Param.ItemType), SysId.ToSysId(model.Param.ItemId));
if (itemParam != null && !itemParam.ItemId.Equals(itemId)) if (itemParam != null && !itemParam.ItemId.Equals(itemId))
{ {
@@ -86,7 +86,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Account
{ {
// Check for duplicate email address. // Check for duplicate email address.
SbmcUserAccount.Params prmUserAccount = new SbmcUserAccount.Params(); SbmcUserAccount.Params prmUserAccount = new SbmcUserAccount.Params();
SysId userAccountId = User.Id.ToSysId(); SysId userAccountId = SysId.ToSysId(User.Id);
if (SysId.IsValid(userAccountId)) if (SysId.IsValid(userAccountId))
prmUserAccount.IdsExcluded.Add(userAccountId); prmUserAccount.IdsExcluded.Add(userAccountId);
prmUserAccount.EmailAddress = User.EmailAddress; prmUserAccount.EmailAddress = User.EmailAddress;
@@ -0,0 +1,28 @@
using Sarand.BusinessMgr.Net.Core.Web.App;
using System;
namespace Sarand.BusinessMgr.Web.Control.Models.Instance
{
//=======================================================================
public class Model_CoreDatabase : SbmModel_Control
{
//-------------------------------------------------------------------
// Construction.
public Model_CoreDatabase(SbmLocaliser localiser) :
base(localiser)
{
}
//-------------------------------------------------------------------
// Filter properties.
public class FilterData
{
public String Context { get; set; }
public String Search { get; set; }
}
public FilterData Filter { get; } = new FilterData();
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -68,7 +68,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance
if (Repository.OwnerId != null) if (Repository.OwnerId != null)
{ {
String controlName = "RepositoryOwner"; String controlName = "RepositoryOwner";
SysId ownerId = Repository.OwnerId.ToSysId(); SysId ownerId = SysId.ToSysId(Repository.OwnerId);
if (!SysId.IsValid(ownerId)) if (!SysId.IsValid(ownerId))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else else
@@ -93,7 +93,7 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Instance
{ {
// Check for duplicate context. // Check for duplicate context.
SbmcRepository.Params prmRepository = new SbmcRepository.Params(); SbmcRepository.Params prmRepository = new SbmcRepository.Params();
SysId repositoryId = Repository.Id.ToSysId(); SysId repositoryId = SysId.ToSysId(Repository.Id);
if (SysId.IsValid(repositoryId)) if (SysId.IsValid(repositoryId))
prmRepository.IdsExcluded.Add(repositoryId); prmRepository.IdsExcluded.Add(repositoryId);
prmRepository.ContextsIncluded.Add(Repository.Context); prmRepository.ContextsIncluded.Add(Repository.Context);
@@ -0,0 +1,254 @@
using DocumentFormat.OpenXml.Spreadsheet;
using NPOI.OpenXml4Net.Exceptions;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Web.Control.Consoles;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.Security;
using Sarand.Net.Standard.Base.Utils;
using System;
namespace Sarand.BusinessMgr.Web.Control.Models.Instance
{
//=======================================================================
public class Model_RepositoryInit : SbmModel_Control
{
//-------------------------------------------------------------------
// Definitions.
public enum Control
{
RepositoryOwnerName,
RepositoryContext,
OrganisationName,
OrganisationWebsite,
OrganisationCompanyNo,
OrganisationVatReg,
UserFirstName,
UserLastName,
UserEmail,
UserCode,
UserPassword,
}
//-------------------------------------------------------------------
// Construction.
public Model_RepositoryInit(SbmLocaliser localiser) :
base(localiser)
{
}
//-------------------------------------------------------------------
// Item properties.
// Repository.
public class RepositoryData
{
public String Id { get; set; }
}
public RepositoryData Repository { get; } = new RepositoryData();
public SysId GetRepositoryId()
{
return SysId.ToSysId(Repository.Id);
}
// Organisation.
public class OrganisationData
{
public String AffiliateId { get; set; }
public String AssociationId { get; set; }
public String Name { get; set; }
public String Website { get; set; }
public String CompanyNo { get; set; }
public String VatReg { get; set; }
}
public OrganisationData Organisation { get; } = new OrganisationData();
public SysId GetOrganisationAffiliateId()
{
return SysId.ToSysId(Organisation.AffiliateId);
}
public SysId GetOrganisationAssociationId()
{
return SysId.ToSysId(Organisation.AssociationId);
}
// User.
public class UserData
{
public String AffiliateId { get; set; }
public String SecurityItemId { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Email { get; set; }
public String Code { get; set; }
public String Password { get; set; }
}
public UserData User { get; } = new UserData();
public SysId GetUserAffiliateId()
{
return SysId.ToSysId(User.AffiliateId);
}
public SysId GetUserSecurityItemId()
{
return SysId.ToSysId(User.SecurityItemId);
}
//-------------------------------------------------------------------
// Configuration.
//-------------------------------------------------------------------
public static String GetControlName(Control control)
{
return $"{control}";
}
//-------------------------------------------------------------------
// Validation.
//-------------------------------------------------------------------
// Repository.
public bool ValidateRepositoryData(SbmController_Base.AjaxResponse_Data responseData, SbmcRepository repository)
{
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
{
//-----------------------------------------------------------
// Repository Console.
SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(repository);
disposables.Add(instanceConsole);
// Core internals.
SbmInternals internals = instanceConsole.CreateCoreInternals();
disposables.Add(internals);
// Core security console.
SaSecurityConsole securityConsole = ControlApp.CreateSecurityConsole(internals.UserContext);
disposables.Add(securityConsole);
//-----------------------------------------------------------
// Organisation Name.
if (Organisation.Name != null)
{
String controlName = GetControlName(Control.OrganisationName);
responseData.SetControlValue(controlName, Organisation.Name);
if (StringUtil.IsBlank(Organisation.Name))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(Organisation.Name) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name)]);
else
{
// Check that organisation name is not already in use.
if (internals.AccountMgr.OrganisationExistsByName(Organisation.Name, GetOrganisationAffiliateId()))
responseData.SetControlError(controlName, Localiser["msg.validation.duplicate.value"]);
}
}
// Organisation Website.
if (Organisation.Website != null)
{
String controlName = GetControlName(Control.OrganisationWebsite);
responseData.SetControlValue(controlName, Organisation.Website);
if (StringUtil.GetLength(Organisation.Website) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Website))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Website)]);
}
// Organisation CompanyNo.
if (Organisation.CompanyNo != null)
{
String controlName = GetControlName(Control.OrganisationCompanyNo);
responseData.SetControlValue(controlName, Organisation.CompanyNo);
if (StringUtil.GetLength(Organisation.CompanyNo) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_CompanyNo))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_CompanyNo)]);
}
// Organisation VatReg.
if (Organisation.VatReg != null)
{
String controlName = GetControlName(Control.OrganisationVatReg);
responseData.SetControlValue(controlName, Organisation.VatReg);
if (StringUtil.GetLength(Organisation.VatReg) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_VatReg))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_VatReg)]);
}
//-----------------------------------------------------------
// User FirstName.
if (User.FirstName != null)
{
String controlName = GetControlName(Control.UserFirstName);
responseData.SetControlValue(controlName, User.FirstName);
if (StringUtil.IsBlank(User.FirstName))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(User.FirstName) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_FirstName))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_FirstName)]);
}
// User LastName.
if (User.LastName != null)
{
String controlName = GetControlName(Control.UserLastName);
responseData.SetControlValue(controlName, User.LastName);
if (StringUtil.IsBlank(User.LastName))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(User.LastName) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_LastName))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_LastName)]);
}
// User Email.
if (User.Email != null)
{
String controlName = GetControlName(Control.UserEmail);
responseData.SetControlValue(controlName, User.Email);
if (StringUtil.IsBlank(User.Email))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(User.Email) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Email))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Email)]);
}
// User Code.
if (User.Code != null)
{
String controlName = GetControlName(Control.UserCode);
responseData.SetControlValue(controlName, User.Code);
if (StringUtil.IsBlank(User.Code))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(User.Code) > GetControlMaxLength(SaSecurityDbDfn.ColumnIdx.SaSecItem_Code))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SaSecurityDbDfn.ColumnIdx.SaSecItem_Code)]);
else
{
// Ensure that user name is not already in use.
SysId securityItemId = securityConsole.GetIdForItemCode(SaSecurity.ItemType.User, User.Code);
if (SysId.IsValid(securityItemId) && !securityItemId.Equals(GetUserSecurityItemId()))
{
}
}
}
// User Password.
if (User.Password != null)
{
String controlName = GetControlName(Control.UserPassword);
responseData.SetControlValue(controlName, User.Password);
if (StringUtil.IsBlank(User.Password))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(User.Password) < Sbm.Config.Security.Password.MinLength)
responseData.SetControlError(controlName, Localiser["msg.validation.minimum.length", Sbm.Config.Security.Password.MinLength]);
else if (StringUtil.GetLength(User.Password) > Sbm.Config.Security.Password.MaxLength)
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", Sbm.Config.Security.Password.MaxLength]);
}
//-----------------------------------------------------------
}
return !responseData.HasControlErrors();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -80,13 +80,13 @@ namespace Sarand.BusinessMgr.Web.Control.Models.Param
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>()) using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{ {
// Check whether data suggests that Param exists. // Check whether data suggests that Param exists.
bool paramExists = StringUtil.ToBool(Param.Exists) && SysId.IsValid(Param.Id.ToSysId()); bool paramExists = StringUtil.ToBool(Param.Exists) && SysId.IsValid(SysId.ToSysId(Param.Id));
// Item. // Item.
if (Param.ItemType != null || Param.ItemId != null) if (Param.ItemType != null || Param.ItemId != null)
{ {
string controlName = "ParamItem"; string controlName = "ParamItem";
ItemId itemId = new ItemId(StringUtil.ToShort(Param.ItemType), Param.ItemId.ToSysId()); ItemId itemId = new ItemId(StringUtil.ToShort(Param.ItemType), SysId.ToSysId(Param.ItemId));
if (!paramExists && (Param.ItemType.IsBlank() || Param.ItemId.IsBlank())) if (!paramExists && (Param.ItemType.IsBlank() || Param.ItemId.IsBlank()))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.IsBlank(ControlItemMgr.GetItemCaption(itemId))) else if (StringUtil.IsBlank(ControlItemMgr.GetItemCaption(itemId)))
@@ -1,9 +1,13 @@
using Sarand.BusinessMgr.Net.Core.Web.App; using Microsoft.AspNetCore.Mvc.Rendering;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Core.Web.Models; using Sarand.BusinessMgr.Net.Core.Web.Models;
using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.BusinessMgr.Net.Standard.Base.Core;
using Sarand.BusinessMgr.Web.Control.App; using Sarand.BusinessMgr.Web.Control.App;
using Sarand.Net.Standard.Base.Core;
using System; using System;
using System.Collections.Generic;
namespace Sarand.BusinessMgr.Web.Control.Models namespace Sarand.BusinessMgr.Web.Control.Models
{ {
@@ -19,9 +23,21 @@ namespace Sarand.BusinessMgr.Web.Control.Models
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Properties. // Properties.
protected SbmApplication_Control ControlApp { get { return SbmApplication_Control.Instance; } }
public SbmSessionData_Control SessionData_Control { get { return SessionData as SbmSessionData_Control; } } public SbmSessionData_Control SessionData_Control { get { return SessionData as SbmSessionData_Control; } }
public override ISbmUserContext_Core UserContext_Core { get { return new SbmUserContext_Control(SessionData_Control); } } public override ISbmUserContext_Core UserContext_Core { get { return new SbmUserContext_Control(SessionData_Control); } }
//-------------------------------------------------------------------
public IEnumerable<SelectListItem> GetInstanceContextsForSelect()
{
List<SelectListItem> items = new List<SelectListItem>();
SbmcRepository.Params prmRepository = new SbmcRepository.Params();
prmRepository.StatusCat = SbmcRepository.StatusCat.NotDeleted;
foreach (SbmcRepository repository in ControlInstanceMgr.GetRepositoryList(prmRepository))
items.Add(new SelectListItem(repository.Context, repository.Context));
return items;
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
/// <summary> /// <summary>
/// Form control value max length - BusinessMgr tables. /// Form control value max length - BusinessMgr tables.
@@ -405,4 +405,52 @@
<data name="msg.warn.item.not.selected" xml:space="preserve"> <data name="msg.warn.item.not.selected" xml:space="preserve">
<value>Item must be selected.</value> <value>Item must be selected.</value>
</data> </data>
<data name="label.initialised" xml:space="preserve">
<value>Initialised</value>
</data>
<data name="msg.validation.minimum.length" xml:space="preserve">
<value>Value must be at least {0} characters</value>
</data>
<data name="label.login.code" xml:space="preserve">
<value>Login code</value>
</data>
<data name="label.initialise" xml:space="preserve">
<value>Initialise</value>
</data>
<data name="label.organisation" xml:space="preserve">
<value>Organisation</value>
</data>
<data name="label.website" xml:space="preserve">
<value>Website</value>
</data>
<data name="label.company.no" xml:space="preserve">
<value>Company No</value>
</data>
<data name="label.vat.reg" xml:space="preserve">
<value>VAT reg.</value>
</data>
<data name="caption.instance.initialise" xml:space="preserve">
<value>Initialise Instance</value>
</data>
<data name="label.database.core" xml:space="preserve">
<value>Core database</value>
</data>
<data name="caption.database.core" xml:space="preserve">
<value>Core Database</value>
</data>
<data name="label.schema" xml:space="preserve">
<value>Schema</value>
</data>
<data name="label.table" xml:space="preserve">
<value>Table</value>
</data>
<data name="label.columns" xml:space="preserve">
<value>Columns</value>
</data>
<data name="label.indices" xml:space="preserve">
<value>Indices</value>
</data>
<data name="label.rows" xml:space="preserve">
<value>Rows</value>
</data>
</root> </root>
@@ -8,9 +8,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="jQuery" Version="3.5.1" /> <PackageReference Include="jQuery" Version="3.7.1" />
<PackageReference Include="jQuery.UI.Combined" Version="1.13.3" /> <PackageReference Include="jQuery.UI.Combined" Version="1.14.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.31" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.36" />
<PackageReference Include="System.Data.Odbc" Version="6.0.2" /> <PackageReference Include="System.Data.Odbc" Version="6.0.2" />
</ItemGroup> </ItemGroup>
@@ -55,6 +55,10 @@
<ExcludeFromSingleFile>true</ExcludeFromSingleFile> <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content> </Content>
<Content Update="Views\Instance\Repository\Initialise.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -0,0 +1,110 @@
@* Instance - Core Database*@
@model Model_CoreDatabase
@inject SbmLocaliser Localiser
@{
ViewData["Title"] = "Instance - Core Database";
Model.AdditionalFiles_JS.Add("js/sbc-ins-coredb.js");
}
<div class="sbc-panel Tables fullheight">
<script type="text/javascript">
</script>
<div class="sbc-panel-data sbc-flex">
@* Filter form - wrap header to include paging controls. *@
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmTableFilter", @class = "sbc-form", @onSubmit = "return false;" }))
{
<div class="sbc-panel-header">
<div class="row">
<div class="fixed">
@* <partial name="~/Views/Common/ResultsPaging.cshtml" /> *@
</div>
<div class="col center"><div class="sbc-panel-caption">@Localiser["caption.database.core"]</div></div>
<div class="fixed">
@* Burger menu *@
<ul class="nav navbar-nav navbar-dark navbar-right sbc-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbc-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div>
</div>
</div>
@* Filter Panel *@
<div class="sbc-panel-filter">
<div class="row">
<div class="col-sm-4 row pb4">
<div class="col-sm-5 sbc-label text-left text-sm-right">@Localiser["label.context"]</div>
<div class="col-sm-7">
@Html.DropDownListFor(model => model.Filter.Context, Model.GetInstanceContextsForSelect(), "", new { @id = "", @class = "FilterContext" })
</div>
</div>
<div class="col-sm-4 row pb4">
<div class="col-sm-5 sbc-label text-left text-sm-right">@Localiser["label.search"]</div>
<div class="col-sm-7">
@Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" })
</div>
</div>
</div>
</div>
}
<div class="sbc-panel-item-table sbc-flex">
<table class="sbc-item-list">
<thead>
<tr>
<th class="width20pc pl-1">@Localiser["label.schema"]</th>
<th class="width25pc">@Localiser["label.table"]</th>
<th class="width10pc center">@Localiser["label.columns"]</th>
<th class="width10pc center">@Localiser["label.indices"]</th>
<th class="width10pc center">@Localiser["label.rows"]</th>
<th class="width5pc"></th>
</tr>
<tr><td colspan="6"><div class="sbc-panel-messages"></div></td></tr>
</thead>
<tbody></tbody>
</table>
</div>
@* Element templates *@
<div class="sbc-panel-item-template">
@* Filter Burger option template - ul is ignored *@
<ul class="sbc-dropdown-menu TableFilter">
<li class="sbc-dropdown-item sbc-action"><div class="sbc-label">XXX</div></li>
</ul>
@* Table row template - table is ignored. *@
<table class="">
<tr class="sbc-row-item Table">
<td><div class="SchemaName pl-1"></div></td>
<td><div class="TableName"></div></td>
<td><div class="ColumnCount center"></div></td>
<td><div class="IndexCount center"></div></td>
<td><div class="RowCount center"></div></td>
<td>
<div class="right">
@* Burger menu *@
<ul class="nav navbar-nav navbar-light navbar-right sbc-burger">
<li class="dropdown-toggle caret-off">
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="sbc-ellipsis-dot"></span><span class="sbc-ellipsis-dot"></span><span class="sbc-ellipsis-dot"></span></a>
<ul class="dropdown-menu dropdown-menu-right sbc-dropdown-menu">@* Menu items will be inserted here. *@</ul>
</li>
</ul>
</div>
</td>
</tr>
</table>
@* Item Burger option template - ul is ignored *@
<ul class="sbc-dropdown-menu Table">
<li class="sbc-dropdown-item sbc-action"><div class="sbc-label">XXX</div></li>
</ul>
</div>
</div>
</div>
@@ -2,7 +2,7 @@
@model Model_Owner @model Model_Owner
@inject SbmLocaliser Localiser @inject SbmLocaliser Localiser
@{ @{
ViewData["Title"] = "Owner Accounts"; ViewData["Title"] = "Instance - Owner";
Model.AdditionalFiles_JS.Add("js/sbc-res-pag.js"); Model.AdditionalFiles_JS.Add("js/sbc-res-pag.js");
Model.AdditionalFiles_JS.Add("js/sbc-ins-own.js"); Model.AdditionalFiles_JS.Add("js/sbc-ins-own.js");
} }
@@ -2,7 +2,7 @@
@model Model_Repository @model Model_Repository
@inject SbmLocaliser Localiser @inject SbmLocaliser Localiser
@{ @{
ViewData["Title"] = "Repository Accounts"; ViewData["Title"] = "Instance - Repository";
Model.AdditionalFiles_JS.Add("js/sbc-res-pag.js"); Model.AdditionalFiles_JS.Add("js/sbc-res-pag.js");
Model.AdditionalFiles_JS.Add("js/sbc-ins-rep.js"); Model.AdditionalFiles_JS.Add("js/sbc-ins-rep.js");
} }
@@ -60,6 +60,7 @@
<th class="">@Localiser["label.server"]</th> <th class="">@Localiser["label.server"]</th>
<th class="">@Localiser["label.instance"]</th> <th class="">@Localiser["label.instance"]</th>
<th class="">@Localiser["label.database"]</th> <th class="">@Localiser["label.database"]</th>
<th class="center">@Localiser["label.initialised"]</th>
<th class="center">@Localiser["label.status"]</th> <th class="center">@Localiser["label.status"]</th>
<th class="right" style="width:2%;"></th> <th class="right" style="width:2%;"></th>
</tr> </tr>
@@ -83,6 +84,7 @@
<td><div class="RepositoryServerName"></div></td> <td><div class="RepositoryServerName"></div></td>
<td><div class="RepositoryInstanceName"></div></td> <td><div class="RepositoryInstanceName"></div></td>
<td><div class="RepositoryDatabaseName"></div></td> <td><div class="RepositoryDatabaseName"></div></td>
<td><div class="RepositoryInitialised center"></div></td>
<td><div class="RepositoryStatusDesc center"></div></td> <td><div class="RepositoryStatusDesc center"></div></td>
<td> <td>
<div class="right"> <div class="right">
@@ -266,7 +268,10 @@
</div> </div>
@* Select Item dialog and script *@
<partial name="~/Views/Common/SelectItem.cshtml" />
</div> </div>
@* Repository Initialisation view. *@
<partial name="Initialise.cshtml" />
@* Select Item view. *@
<partial name="~/Views/Common/SelectItem.cshtml" />
@@ -0,0 +1,223 @@
@* Instance - Repository - Initialise *@
@model SbmModel_Control
@inject SbmLocaliser Localiser
@{
Model.AdditionalFiles_JS.Add("js/sbc-ins-rep-init.js");
}
<div class="sbc-panel RepositoryInit">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "RepositoryIdForm", @onSubmit = "return false;" }))
{
@Html.Hidden("Repository.Id", "", new { @id = "", @class = "RepositoryId" })
}
<div id="" class="sbc-dialog RepositoryInitDlg" title="@(Localiser.GetJavascriptText("caption.instance.initialise"))">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "RepositoryInitForm sbc-form", @onSubmit = "return false;" }))
{
@Html.Hidden("Repository.Id", "", new { @id = "", @class = "RepositoryId sbc-input" })
<div class="sbc-caption">@Localiser["label.instance"]</div>
@* Owner *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.RepositoryOwnerName)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for=""><span>@Localiser["label.owner"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
<input type="text" class="OwnerName sbc-input" readonly="readonly" />
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
@* Context *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.RepositoryContext)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for=""><span>@Localiser["label.context"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
<input type="text" class="RepositoryContext sbc-input" readonly="readonly" />
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
<div class="spacer2"></div>
<div class="sbc-caption">@Localiser["label.organisation"]</div>
@Html.Hidden("Organisation.AffiliateId", "", new { @id = "", @class = "OrganisationAffiliateId sbc-input" })
@Html.Hidden("Organisation.AssociationId", "", new { @id = "", @class = "OrganisationAssociationId sbc-input" })
@* Organisation Name *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.OrganisationName)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for=""><span>@Localiser["label.name"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.TextBox("Organisation.Name", "", new { @id = "", @class = "OrganisationName sbc-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Name) })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
@* Organisation Website *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.OrganisationWebsite)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for="ifRepositoryContext"><span>@Localiser["label.website"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.TextBox("Organisation.Website", "", new { @id = "", @class = "OrganisationWebsite sbc-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Website) })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
@* Organisation CompanyNo *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.OrganisationCompanyNo)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for="ifRepositoryContext"><span>@Localiser["label.company.no"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.TextBox("Organisation.CompanyNo", "", new { @id = "", @class = "OrganisationCompanyNo sbc-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_CompanyNo) })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
@* Organisation VatReg *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.OrganisationVatReg)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for="ifRepositoryContext"><span>@Localiser["label.vat.reg"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.TextBox("Organisation.VatReg", "", new { @id = "", @class = "OrganisationVatReg sbc-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_VatReg) })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
<div class="spacer2"></div>
<div class="sbc-caption">@Localiser["label.user"]</div>
@Html.Hidden("User.AffiliateId", "", new { @id = "", @class = "UserAffiliateId sbc-input" })
@Html.Hidden("User.AssociationId", "", new { @id = "", @class = "UserSecurityItemId sbc-input" })
@* User FirstName *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.UserFirstName)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for="ifRepositoryContext"><span>@Localiser["label.first.name"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.TextBox("User.FirstName", "", new { @id = "", @class = "UserFirstName sbc-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_FirstName) })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
@* User LastName *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.UserLastName)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for="ifRepositoryContext"><span>@Localiser["label.last.name"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.TextBox("User.LastName", "", new { @id = "", @class = "UserLastName sbc-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_LastName) })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
@* User Email *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.UserEmail)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for="ifRepositoryContext"><span>@Localiser["label.email"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.TextBox("User.Email", "", new { @id = "", @class = "UserEmail sbc-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Affiliate_Email) })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
@* User Code *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.UserCode)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for="ifRepositoryContext"><span>@Localiser["label.login.code"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.TextBox("User.Code", "", new { @id = "", @class = "UserCode sbc-input", @maxlength = @Model.GetControlMaxLength(Sarand.Net.Standard.Base.Security.SaSecurityDbDfn.ColumnIdx.SaSecItem_Code) })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
@* User Password *@
<div class="sbc-form-control @Model_RepositoryInit.GetControlName(Model_RepositoryInit.Control.UserPassword)">
<div class="row">
<div class="col-sm-3">
<div class="sbc-label">
<label for="ifRepositoryContext"><span>@Localiser["label.password"]</span></label>
</div>
</div>
<div class="col-sm-9">
<div class="sbc-control">
@Html.Password("User.Password", "", new { @id = "", @class = "UserPassword sbc-input", @maxlength = Sbm.Config.Security.Password.MaxLength })
</div>
<div class="sbc-message"></div>
</div>
</div>
</div>
}
<div class="spacer2"></div>
</div>
</div>
@@ -71,6 +71,7 @@
sbc.lbl.refresh = '@(Localiser.GetJavascriptText("label.refresh"))'; sbc.lbl.refresh = '@(Localiser.GetJavascriptText("label.refresh"))';
sbc.lbl.create = '@(Localiser.GetJavascriptText("label.create"))'; sbc.lbl.create = '@(Localiser.GetJavascriptText("label.create"))';
sbc.lbl.edit = '@(Localiser.GetJavascriptText("label.edit"))'; sbc.lbl.edit = '@(Localiser.GetJavascriptText("label.edit"))';
sbc.lbl.init = '@(Localiser.GetJavascriptText("label.initialise"))';
sbc.lbl.emails = '@(Localiser.GetJavascriptText("label.emails"))'; sbc.lbl.emails = '@(Localiser.GetJavascriptText("label.emails"))';
sbc.lbl.charAvailable = '@Localiser.GetJavascriptText("info.char.available")'; sbc.lbl.charAvailable = '@Localiser.GetJavascriptText("info.char.available")';
sbc.lbl.charsAvailable = '@Localiser.GetJavascriptText("info.chars.available", "{0}")'; sbc.lbl.charsAvailable = '@Localiser.GetJavascriptText("info.chars.available", "{0}")';
@@ -118,14 +119,8 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">@Localiser["label.home"]</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">@Localiser["label.home"]</a>
</li> </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"> @* Instances *@
@Localiser["label.accounts"]
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Account/UserAccount');">@Localiser["label.users"]</div>
</div>
</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.instances"] @Localiser["label.instances"]
@@ -133,8 +128,11 @@
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Instance/Owner');">@Localiser["label.owners"]</div> <div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Instance/Owner');">@Localiser["label.owners"]</div>
<div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Instance/Repository');">@Localiser["label.repositories"]</div> <div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Instance/Repository');">@Localiser["label.repositories"]</div>
<div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Instance/CoreDatabase');">@Localiser["label.database.core"]</div>
</div> </div>
</li> </li>
@* Configuration *@
<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.configuration"] @Localiser["label.configuration"]
@@ -143,6 +141,8 @@
<div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Param/Param');">@Localiser["label.params"]</div> <div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Param/Param');">@Localiser["label.params"]</div>
</div> </div>
</li> </li>
@* System *@
<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.system"] @Localiser["label.system"]
@@ -152,11 +152,15 @@
<div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('System/Logs');">@Localiser["label.logs"]</div> <div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('System/Logs');">@Localiser["label.logs"]</div>
</div> </div>
</li> </li>
@* Security *@
<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"]
</a> </a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sbc-action" onclick="sbc.goToPage('Account/UserAccount');">@Localiser["label.users"]</div>
<div class="dropdown-divider"></div>
<div class="dropdown-item text-dark sbc-action" onclick="sbc.navigateTo('Security/ChangePassword');">@Localiser["caption.change.password"]</div> <div class="dropdown-item text-dark sbc-action" onclick="sbc.navigateTo('Security/ChangePassword');">@Localiser["caption.change.password"]</div>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<div class="dropdown-item text-dark sbc-action" onclick="sbc.onSignOut();">@Localiser["label.signout"]</div> <div class="dropdown-item text-dark sbc-action" onclick="sbc.onSignOut();">@Localiser["label.signout"]</div>
@@ -170,8 +174,8 @@
</header> </header>
@* Page body *@ @* Page body *@
<div id="sbc-page-body" class="container"> <div id="sbc-page-body">
<main role="main" class="pb-3 fullheight"> <main role="main" class="container pt-2 pb-2 fullheight">
@RenderBody() @RenderBody()
</main> </main>
</div> </div>
@@ -13,26 +13,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"
}
],
"Email": { "Email": {
"Context": "SBM-Dev", "Context": "SBM-Dev",
"ContactUs": { "ContactUs": {
@@ -6,7 +6,7 @@
.sbc-panel-data .sbc-panel-data
{ {
margin: 6px auto; margin: 0 auto;
background-color: #f8f8f8; background-color: #f8f8f8;
border: solid 1px var(--color-panel-data-border); border: solid 1px var(--color-panel-data-border);
border-radius: 6px; border-radius: 6px;
@@ -62,6 +62,14 @@
color: var(--color-primary-dark); color: var(--color-primary-dark);
} }
.sbc-form .sbc-caption
{
margin: 0 0 12px 0;
font-size: 1.25rem;
font-weight: bold;
color: var(--color-primary-dark);
}
.sbc-panel-info .sbc-panel-info > .sbc-header .sbc-caption .sbc-panel-info .sbc-panel-info > .sbc-header .sbc-caption
{ {
font-size: 1.25rem; font-size: 1.25rem;
@@ -65,6 +65,7 @@ body
{ {
flex: 1; flex: 1;
min-height: 0; min-height: 0;
overflow-y: auto;
} }
} }
@@ -0,0 +1,113 @@
/*
* SBM - Control - Instance - Core Database.
*/
(function (win, doc, undef)
{
"use strict";
let cd = sbc.mdl.coreDatabase = { env: {}, data: {} };
//--------------------------------------------------------------
cd.refreshItems = function (env, delay)
{
//sbc.debug('refreshItems', env);
if (!env.$frm.filter.find('.FilterContext').val()) return;
if (!cd.awaitingRefreshResponse)
{
env.$pnl.bgr.invisible();
env.$pnl.table.find('tbody tr').remove();
env.$pnl.msgs.hide().empty().append($('<div class="sbc-message">' + sbc.msg.dataQuerying + '</div>')).fadeIn(200);
}
env.ajax.tables = env.ajax.tables || { url: sbc.url.base + 'Instance/CoreDatabase/Ajax/GetTables', formSel: env.$frm.filter, callbackFn: function (response) { cd.displayItems(env, response); } };
sbc.doAjaxRequest(env.ajax.tables, delay || 50);
cd.awaitingRefreshResponse = true;
}
cd.displayItems = function (env, response)
{
//sbc.debug('displayItems', env, response);
delete cd.awaitingRefreshResponse;
env.$pnl.msgs.hide().empty();
let $table = $('table', env.$pnl.table).find('tbody tr').remove().end();
if (!response.success) return;
env.config = response.config || {};
// Menu.
if (env.$pnl.bgr.length)
{
env.$pnl.bgr.invisible();
env.$pnl.mnu.empty();
env.$pnl.mnu.append(cd.getFilterMenuOption(env, sbc.lbl.refresh, function () { cd.refreshItems(env); }, 'sbc-refresh'));
env.$pnl.bgr.toggleVisibility(!!$('.sbc-dropdown-item', env.$pnl.mnu).length);
}
// Items.
var items = response.tables || [];
if (!items.length)
return env.$pnl.msgs.append($('<div class="sbc-message">' + sbc.msg.dataNoneFound + '</div>')).fadeIn(500);
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
$table.append(cd.populateItem(env, cd.getItemTemplate(env), items[itemIdx]));
sbc.configureItemTable(env.config, $table);
}
cd.populateItem = function (env, $item, item)
{
if (!item) return $item;
$item.prop('id', cd.getItemId(item));
$('.SchemaName', $item).text(item.schemaName);
$('.TableName', $item).text(item.tableName);
if (item.columnCount) $('.ColumnCount', $item).text(item.columnCount);
if (item.indexCount) $('.IndexCount', $item).text(item.indexCount);
if (item.rowCount) $('.RowCount', $item).text(item.rowCount);
return $item;
}
cd.getItemId = function (item)
{
return 'Tbl_' + (item || {}).TableName;
}
//--------------------------------------------------------------
cd.getFilterDropdownTemplate = function (env)
{
return env.$pnl.tmpls.find('.sbc-dropdown-menu.TableFilter li.sbc-dropdown-item').clone();
}
cd.getItemTemplate = function (env)
{
return env.$pnl.tmpls.find('table tr.sbc-row-item.Table').clone();
}
cd.getItemDropdownTemplate = function (env)
{
return env.$pnl.tmpls.find('.sbc-dropdown-menu.Table li.sbc-dropdown-item').clone();
}
cd.getFilterMenuOption = function (env, lbl, fn, cls)
{
return cd.getMenuOption(cd.getFilterDropdownTemplate(env), lbl, fn, cls);
}
cd.getItemMenuOption = function (env, lbl, fn, cls)
{
return cd.getMenuOption(cd.getItemDropdownTemplate(env), lbl, fn, cls);
}
cd.getMenuOption = function ($opt, lbl, fn, cls)
{
return $opt.find('div.sbc-label').text(lbl).end().on('click', fn).addClass(cls);
}
//--------------------------------------------------------------
$(function ()
{
let env = cd.env.init = { data: {}, ajax: {}, $pnl: {}, $frm: {}, $ctrl: {}, $dlg: {} };
env.$pnl.items = $('.sbc-panel.Tables');
env.$pnl.header = env.$pnl.items.find('.sbc-panel-header');
env.$pnl.bgr = env.$pnl.header.find('.sbc-burger');
env.$pnl.mnu = env.$pnl.bgr.find('ul.sbc-dropdown-menu');
env.$pnl.table = env.$pnl.items.find('.sbc-panel-item-table');
env.$pnl.msgs = env.$pnl.table.find('.sbc-panel-messages');
env.$pnl.tmpls = env.$pnl.items.find('.sbc-panel-item-template');
env.$frm.filter = env.$pnl.items.find('#frmTableFilter');
env.$frm.filter.on('input', '.FilterSearch', function () { cd.refreshItems(env, 250); }).on('change', '.FilterContext', function () { cd.refreshItems(env, 100); });
if (env.$frm.filter.length) cd.refreshItems(env, 250);
});
//--------------------------------------------------------------
}(window, window.document));
/* The End */
@@ -50,7 +50,7 @@
} }
io.populateItem = function ($item, item) io.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return $item;
$pnl.msgs.hide().empty(); $pnl.msgs.hide().empty();
$item.prop('id', io.getItemId(item)); $item.prop('id', io.getItemId(item));
$('.OwnerName', $item).text(item.name); $('.OwnerName', $item).text(item.name);
@@ -0,0 +1,92 @@
/*
* SBM - Control - Instance - Repository - Initialise.
*/
(function (win, doc, undef)
{
"use strict";
let ir = sbc.mdl.initRepository = { env: {} };
//--------------------------------------------------------------
/*
Initialise Repository.
Config:
- id Repository
- fnSuccess Callback
*/
sbc.fn.initialiseRepo = function (cfg)
{
//sbc.debug('initialiseRepo', cfg);
let env = ir.env.init;
env.cfg = cfg;
let $frm = env.$frm.itemId;
$frm.find('.RepositoryId').val(cfg.id)
env.ajax.initQuery = env.ajax.initQuery || { url: sbc.url.base + 'Instance/Repository/Ajax/GetInitInfo', formSel: $frm, callbackFn: function (response) { ir.onInitQuery(env, response); } };
sbc.doAjaxRequest(env.ajax.initQuery, 50);
}
ir.onInitQuery = function (env, response)
{
sbc.debug('onInitQuery', response);
if (!response.success) return;
let $ctrls = env.$frm.init.find('.sbc-input,.sbc-textarea,.sbc-select').val('');
let repo = response.repository
$ctrls.filter('.RepositoryId').val(repo.id);
$ctrls.filter('.OwnerName').val(repo.ownerName);
$ctrls.filter('.RepositoryContext').val(repo.context);
let orgs = repo.organisations || [];
if (orgs.length)
{
let org = orgs[0];
$ctrls.filter('.OrganisationAssociationId').val(org.associationId);
$ctrls.filter('.OrganisationAffiliateId').val(org.affiliateId);
$ctrls.filter('.OrganisationName').val(org.name);
$ctrls.filter('.OrganisationWebsite').val(org.website);
$ctrls.filter('.OrganisationCompanyNo').val(org.companyNo);
$ctrls.filter('.OrganisationVatReg').val(org.vatReg);
let usrs = org.users || [];
if (usrs.length)
{
let usr = usrs[0];
$ctrls.filter('.UserAffiliateId').val(usr.affiliateId);
$ctrls.filter('.UserSecurityItemId').val(usr.securityItemId);
}
}
sbc.openDialog(env.$dlg.init, 600, 640);
}
//--------------------------------------------------------------
ir.initRepo = function (env)
{
env.ajax.initRepo = env.ajax.initRepo || { url: sbc.url.base + 'Instance/Repository/Ajax/Initialise', formSel: env.$frm.init, callbackFn: function (response) { ir.onInitRepo(env, response); } };
sbc.doAjaxRequest(env.ajax.initRepo, 50);
}
ir.onInitRepo = function(env, response)
{
sbc.debug('onInitRepo', env, response);
sbc.refreshControlValues(response.controlValues);
if (!response.success) return;
env.$dlg.init.dialog('close');
if (env.cfg.fnSuccess) env.cfg.fnSuccess();
delete env.cfg;
}
//--------------------------------------------------------------
$(function ()
{
let env = ir.env.init = { data: {}, ajax: {}, $pnl: {}, $frm: {}, $ctrl: {}, $dlg: {} };
env.$pnl.init = $('.sbc-panel.RepositoryInit');
env.$frm.itemId = env.$pnl.init.find('.RepositoryIdForm');
let opt = sbc.dlgOpts();
opt.buttons[sbc.lbl.ok] = function () { ir.initRepo(env); };
opt.buttons[sbc.lbl.cancel] = function () { delete env.cfg; $(this).dialog('close'); };
env.$dlg.init = env.$pnl.init.find('.RepositoryInitDlg').dialog(opt);
env.$frm.init = env.$dlg.init.find('.RepositoryInitForm');
env.$frm.init.on('input', '.sbc-input, .sbc-textarea', function () { sbc.clearControlError(this); }).on('change', '.sbc-select', function () { sbc.clearControlError(this); });
});
//--------------------------------------------------------------
}(window, window.document));
/* The End */
@@ -17,7 +17,7 @@
$pnl.table.find('tbody tr').remove(); $pnl.table.find('tbody tr').remove();
$pnl.msgs.hide().empty().append($('<div class="sbc-message">' + sbc.msg.dataQuerying + '</div>')).fadeIn(200); $pnl.msgs.hide().empty().append($('<div class="sbc-message">' + sbc.msg.dataQuerying + '</div>')).fadeIn(200);
} }
ir.ajax.repositories = ir.ajax.repositories || { url: sbc.url.base + 'Instance/Repository/Ajax/GetRepositories', formId: $frm.filter.prop('id'), callbackFn: ir.handleRepositories }; ir.ajax.repositories = ir.ajax.repositories || { url: sbc.url.base + 'Instance/Repository/Ajax/GetRepositories', formSel: $frm.filter, callbackFn: ir.handleRepositories };
sbc.doAjaxRequest(ir.ajax.repositories, delay || 50); sbc.doAjaxRequest(ir.ajax.repositories, delay || 50);
ir.awaitingRefreshResponse = true; ir.awaitingRefreshResponse = true;
} }
@@ -36,21 +36,22 @@
if (response.statusCodeDefault) sbc.data.statusCodeDefault = response.statusCodeDefault; if (response.statusCodeDefault) sbc.data.statusCodeDefault = response.statusCodeDefault;
// Menu. // Menu.
var $bgr = $('.sbc-burger', $pnl.header).hide(); let $bgr = $('.sbc-burger', $pnl.header).hide();
var $mnu = $('ul.sbc-dropdown-menu', $bgr).empty(); let $mnu = $('ul.sbc-dropdown-menu', $bgr).empty();
$mnu.append(ir.getFilterMenuOption(sbc.lbl.refresh, function () { ir.refreshResults(); }, 'sbc-refresh')); $mnu.append(ir.getFilterMenuOption(sbc.lbl.refresh, function () { ir.refreshResults(); }, 'sbc-refresh'));
$mnu.append(ir.getFilterMenuOption(sbc.lbl.create, function () { ir.createItem(); }, 'sbc-add')); $mnu.append(ir.getFilterMenuOption(sbc.lbl.create, function () { ir.createItem(); }, 'sbc-add'));
$bgr.toggle(!!$('.sbc-dropdown-item', $mnu).length); $bgr.toggle(!!$('.sbc-dropdown-item', $mnu).length);
// Items. // Items.
var items = response.repositories || []; let items = response.repositories || [];
if (!items.length) if (!items.length)
return $pnl.msgs.append($('<div class="sbc-message">' + sbc.msg.dataNoneFound + '</div>')).fadeIn(500); return $pnl.msgs.append($('<div class="sbc-message">' + sbc.msg.dataNoneFound + '</div>')).fadeIn(500);
for (let itemIdx = 0; itemIdx < items.length; itemIdx++) for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
$table.append(ir.populateItem(ir.getItemRowTemplate(), items[itemIdx])); $table.append(ir.populateItem(ir.getItemRowTemplate(), items[itemIdx]));
ir.refreshRepoInfo(items[0].id, 500);
} }
ir.populateItem = function ($item, item) ir.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return $item;
$pnl.msgs.hide().empty(); $pnl.msgs.hide().empty();
$item.prop('id', ir.getItemId(item)); $item.prop('id', ir.getItemId(item));
$('.RepositoryOwnerName', $item).text(item.ownerName); $('.RepositoryOwnerName', $item).text(item.ownerName);
@@ -61,7 +62,7 @@
$('.RepositoryStatusDesc', $item).text(item.statusDesc).removeStatusClasses().addClass('sbc-status-' + item.statusCode.toLowerCase()); $('.RepositoryStatusDesc', $item).text(item.statusDesc).removeStatusClasses().addClass('sbc-status-' + item.statusCode.toLowerCase());
// Actions. // Actions.
let fnUpd = function () { ir.updateItem($item, item) }; let fnUpd = function () { ir.updateItem($item, item) };
var $bgr = $('.sbc-burger', $item).hide(); let $bgr = $('.sbc-burger', $item).hide();
let $mnu = $('ul.sbc-dropdown-menu', $bgr).empty(); let $mnu = $('ul.sbc-dropdown-menu', $bgr).empty();
if (!item.deleted) if (!item.deleted)
{ {
@@ -74,7 +75,41 @@
} }
ir.getItemId = function (item) ir.getItemId = function (item)
{ {
return 'Itm_' + (item || {}).id; return 'Repo_' + (item || {}).id;
}
//--------------------------------------------------------------
ir.refreshRepoInfo = function (id, delay)
{
$frm.itemId.find('.RepositoryId').val(id);
ir.ajax.repoInit = ir.ajax.repoInit || { url: sbc.url.base + 'Instance/Repository/Ajax/GetRepositoryInfo', formSel: $frm.itemId, callbackFn: ir.handleRepoInfo };
sbc.doAjaxRequest(ir.ajax.repoInit, delay || 50);
}
ir.handleRepoInfo = function (response)
{
//sbc.debug('handleRepoInfo', response);
if (!response.success) return;
let item = response.repository;
let $item = $pnl.table.find('#' + ir.getItemId(item));
let $bgr = $item.find('.sbc-burger').hide();
let $mnu = $bgr.find('ul.sbc-dropdown-menu');
let $repoInit = $item.find('.RepositoryInitialised').empty();
if (!!item.unavailable)
$repoInit.append($('<div>').append($('<img style="width:16px">').prop('src', '/img/icon/error-18.png').prop('title', item.unavailable)));
else if (!item.initialised)
{
$repoInit.append($('<div>').append($('<img style="width:16px">').prop('src', '/img/icon/cross-24.png').prop('title', item.uninitialised)));
$mnu.append(ir.getItemMenuOption(sbc.lbl.init, function () { sbc.fn.initialiseRepo({ id: item.id, fnSuccess: ir.onInitRepo }); }, 'sbc-process RepoInit'));
}
else $repoInit.append($('<div>').append($('<img style="width:16px">').prop('src', '/img/icon/tick-24.png')));
$bgr.toggle(!!$('.sbc-dropdown-item', $mnu).length);
let $next = $item.next();
if ($next.length) ir.refreshRepoInfo($next.prop('id').replace(/[^0-9]/g, ''), 200);
}
ir.onInitRepo = function (id)
{
sbc.debug('onInitRepo', id);
ir.refreshResults(50);
} }
//-------------------------------------------------------------- //--------------------------------------------------------------
@@ -132,8 +167,8 @@
{ {
//sbc.debug('updateItem', $item, item); //sbc.debug('updateItem', $item, item);
ir.clearItem(); ir.clearItem();
$('.RepositoryId', $frm.itemId).val(item.id); $frm.itemId.find('.RepositoryId').val(item.id);
sbc.ajax.updateItem = sbc.ajax.updateItem || { url: sbc.url.base + 'Instance/Repository/Ajax/GetItem', formId: $frm.itemId.prop('id'), callbackFn: ir.onUpdateItem }; sbc.ajax.updateItem = sbc.ajax.updateItem || { url: sbc.url.base + 'Instance/Repository/Ajax/GetItem', formSel: $frm.itemId, callbackFn: ir.onUpdateItem };
sbc.doAjaxRequest(sbc.ajax.updateItem, 50); sbc.doAjaxRequest(sbc.ajax.updateItem, 50);
} }
ir.onUpdateItem = function (response) ir.onUpdateItem = function (response)
@@ -194,8 +229,8 @@
if (!response.success) return; if (!response.success) return;
$dlg.item.dialog('close'); $dlg.item.dialog('close');
var item = response.repository; let item = response.repository;
var $item = $('#' + ir.getItemId(item), $pnl.table); let $item = $('#' + ir.getItemId(item), $pnl.table);
if (!$item.length) if (!$item.length)
{ {
$item = ir.getItemRowTemplate(); $item = ir.getItemRowTemplate();
@@ -219,7 +254,7 @@
$frm.itemId = $('#frmRepositoryId'); $frm.itemId = $('#frmRepositoryId');
$frm.owners = $('#frmOwners'); $frm.owners = $('#frmOwners');
var opt = sbc.dlgOpts(); let opt = sbc.dlgOpts();
opt.buttons[sbc.lbl.save] = function () { ir.storeItem(); }; opt.buttons[sbc.lbl.save] = function () { ir.storeItem(); };
opt.buttons[sbc.lbl.cancel] = function () { $(this).dialog('close'); }; opt.buttons[sbc.lbl.cancel] = function () { $(this).dialog('close'); };
$dlg.item = $('#dlgRepository').dialog(opt); $dlg.item = $('#dlgRepository').dialog(opt);
@@ -90,16 +90,17 @@
}; };
//-------------------------------------------------------------- //--------------------------------------------------------------
sbc.setOddDataRowClass = function (rowSel) sbc.setOddDataRowClass = function (rowSel, cName)
{ {
$(rowSel).addClass(function (index, currentClasses) $(rowSel).addClass(function (index, currentClasses)
{ {
return index % 2 == 1 ? "other" : ""; return index % 2 == 1 ? (cName || "other") : "";
}); });
} }
sbc.selectOrAdd = function ($sel, code, desc) sbc.selectOrAdd = function ($sel, code, desc)
{ {
if ($sel.val(code) == code) return; $sel = $($sel);
if ($sel.val(code).val() == code) return;
$sel.append($('<option>').prop('value', code).text(desc)); $sel.append($('<option>').prop('value', code).text(desc));
$sel.val(code); $sel.val(code);
} }
@@ -113,7 +114,7 @@
} }
sbc.populateSelectCodeDesc = function ($sel, values) sbc.populateSelectCodeDesc = function ($sel, values)
{ {
sbc.populateSelect($sel, values); sbc.populateSelect($($sel), values);
} }
sbc.checkTextAreaMaxLength = function (ctrl, len) sbc.checkTextAreaMaxLength = function (ctrl, len)
{ {
@@ -153,6 +154,41 @@
sbc.resultsPaging.fn.refreshPaging(response.paging, context, refreshFn); sbc.resultsPaging.fn.refreshPaging(response.paging, context, refreshFn);
} }
//--------------------------------------------------------------
sbc.configureItemTable = function (cfg, $sel)
{
//sbc.debug('configureItemTable', cfg, $sel);
let col = cfg.column || {};
let $cell = $('th,td', $sel).removeClass('hidden');
(col.hide || []).forEach(function (v, i, a) { $cell.filter('.' + col.prefix + v).addClass('hidden'); });
}
sbc.populateItemValues = function (cfg, $item, val)
{
//sbc.debug('populateItemValues', cfg, $item, val);
for (var name in val || []) { $item.find('.' + cfg.column.prefix + name).text(val[name]); };
}
sbc.clearItemForm = function ($frm)
{
//sbc.clearControlErrors($frm);
$('.sbc-input,.sbc-textarea,.sbc-select', $frm).val('').prop('readonly', false).prop('disabled', false);
$('.sbc-checkbox', $frm).prop('readonly', false).prop('disabled', false).removeAttr('checked');
}
sbc.configureItemControls = function (cfg, $frm)
{
//sbc.debug('configureItemControls', cfg);
let fld = cfg.field || {};
let $ctrl = $('.sbc-form-control', $frm).show();
for (var name in fld.label || {}) { /* ... */ };
(fld.hide || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).hide().find('.sbc-input,.sbc-textarea,.sbc-select,.sbc-checkbox').prop('disabled', true); });
(fld.readonly || []).forEach(function (v, i, a) { $ctrl.filter('.' + fld.prefix + v).find('.sbc-input,.sbc.textarea,.sbc-select,.sbc-checkbox').prop('readonly', true).prop('disabled', true); });
}
sbc.populateFormValues = function (cfg, $frm, val)
{
//sbc.debug('populateFormValues', cfg, $frm, val);
let $ctrl = $('.sbc-form-control', $frm);
for (var name in val || {}) { $ctrl.filter('.' + cfg.field.prefix + name).find('.sbc-input,.sbc-textarea,.sbc-select').filter('.sbc-auto-val').val(val[name]).end().find('.sbc-checkbox').prop('checked', !!val[name]); };
}
//-------------------------------------------------------------- //--------------------------------------------------------------
// Page navigation. // Page navigation.
sbc.navigateTo = function (action) sbc.navigateTo = function (action)
@@ -189,10 +225,11 @@
// Dialogs. // Dialogs.
sbc.openDialog = function ($dlg, width, height) sbc.openDialog = function ($dlg, width, height)
{ {
let $win = $(win);
$dlg.dialog( $dlg.dialog(
{ {
minWidth: null, maxWidth: null, width: Math.min(width || 400, $(win).width() * .98), minWidth: null, maxWidth: null, width: Math.min(width || 400, $win.width() * .98),
minHeight: null, maxHeight: null, height: Math.min(height || 320, $(win).innerHeight() * .98) minHeight: null, maxHeight: null, height: Math.min(height || 320, $win.innerHeight() * .98)
}).dialog('open'); }).dialog('open');
return $dlg; return $dlg;
} }
@@ -324,7 +361,7 @@
type: 'POST', type: 'POST',
cache: false, cache: false,
//enctype: 'multipart/form-data', //enctype: 'multipart/form-data',
data: ajax.formData || $("#" + ajax.formId).serialize(), data: ajax.formData || $(ajax.formSel || "#" + ajax.formId).serialize(),
dataType: 'json', dataType: 'json',
success: function (response, status, jqXHR) success: function (response, status, jqXHR)
{ {
@@ -56,7 +56,7 @@
} }
ip.populateItem = function ($item, item) ip.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return $item;
$pnl.msgs.hide().empty(); $pnl.msgs.hide().empty();
$item.prop('id', ip.getItemId(item)); $item.prop('id', ip.getItemId(item));
$('.ParamItem', $item).text(item.itemCaption); $('.ParamItem', $item).text(item.itemCaption);
@@ -50,7 +50,7 @@
} }
ua.populateItem = function ($item, item) ua.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return $item;
$pnl.msgs.hide().empty(); $pnl.msgs.hide().empty();
$item.prop('id', ua.getItemId(item)); $item.prop('id', ua.getItemId(item));
$('.UserEmailAddress', $item).text(item.emailAddress); $('.UserEmailAddress', $item).text(item.emailAddress);
@@ -678,4 +678,43 @@
<data name="label.box.quantity" xml:space="preserve"> <data name="label.box.quantity" xml:space="preserve">
<value>Box quantity</value> <value>Box quantity</value>
</data> </data>
<data name="label.narrative" xml:space="preserve">
<value>Narrative</value>
</data>
<data name="label.delivery.courier" xml:space="preserve">
<value>Delivery courier</value>
</data>
<data name="label.delivery.method" xml:space="preserve">
<value>Delivery method</value>
</data>
<data name="label.delivery.type" xml:space="preserve">
<value>Delivery type</value>
</data>
<data name="label.delivery.status" xml:space="preserve">
<value>Delivery status</value>
</data>
<data name="label.contact.area" xml:space="preserve">
<value>Contact area</value>
</data>
<data name="label.account.handler" xml:space="preserve">
<value>Account handler</value>
</data>
<data name="label.account.manager" xml:space="preserve">
<value>Account manager</value>
</data>
<data name="label.transactions" xml:space="preserve">
<value>Transactions</value>
</data>
<data name="label.transaction" xml:space="preserve">
<value>Transaction</value>
</data>
<data name="caption.transaction.create" xml:space="preserve">
<value>Create Transaction</value>
</data>
<data name="caption.transaction.update" xml:space="preserve">
<value>Update Transaction</value>
</data>
<data name="msg.validation.minimum.length" xml:space="preserve">
<value>Value must be at least {0} characters</value>
</data>
</root> </root>
@@ -85,7 +85,7 @@ namespace Sarand.BusinessMgr.Web.Portal.App
get get
{ {
if (instanceConfig == null) if (instanceConfig == null)
instanceConfig = new SbmInstanceConfig_Portal(ControlOwnerId, ControlRepositoryId); instanceConfig = new SbmInstanceConfig_Control(ControlOwnerId, ControlRepositoryId);
return instanceConfig; return instanceConfig;
} }
} }
@@ -227,9 +227,9 @@ namespace Sarand.BusinessMgr.Web.Portal.App
// Control database connection. // Control database connection.
SacsDatabaseConsole.OdbcConfig odbcConfig = new SacsDatabaseConsole.OdbcConfig(); SacsDatabaseConsole.OdbcConfig odbcConfig = new SacsDatabaseConsole.OdbcConfig();
odbcConfig.location = AppConfig.ControlDatabase.Location; odbcConfig.Location = AppConfig.ControlDatabase.Location;
odbcConfig.user = AppConfig.ControlDatabase.User; odbcConfig.User = AppConfig.ControlDatabase.User;
odbcConfig.pword = AppConfig.ControlDatabase.Password; odbcConfig.Password = AppConfig.ControlDatabase.Password;
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);
@@ -238,9 +238,9 @@ namespace Sarand.BusinessMgr.Web.Portal.App
foreach (Net.Core.Web.App.SbmAppConfig.DatabaseConfig dbConfig in AppConfig.BusMgrDatabases) foreach (Net.Core.Web.App.SbmAppConfig.DatabaseConfig dbConfig in AppConfig.BusMgrDatabases)
{ {
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
config.location = dbConfig.Location; config.Location = dbConfig.Location;
config.user = dbConfig.User; config.User = dbConfig.User;
config.pword = dbConfig.Password; config.Password = dbConfig.Password;
SacsDatabase coreDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config); SacsDatabase coreDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config);
if (!coreDatabase.HasErrorState()) if (!coreDatabase.HasErrorState())
{ {
@@ -290,9 +290,9 @@ namespace Sarand.BusinessMgr.Web.Portal.App
{ {
// Configure Core database. // Configure Core database.
SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig();
config.location = $"MsSql:{repository.ServerName}\\{repository.InstanceName}.{repository.DatabaseName}"; config.Location = $"MsSql:{repository.ServerName}\\{repository.InstanceName}.{repository.DatabaseName}";
config.user = repository.UserName; config.User = repository.UserName;
config.pword = repository.Password; config.Password = repository.Password;
SacsDatabase coreDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config); SacsDatabase coreDatabase = SacsDatabaseConsole.OpenOdbcDatabase(config);
if (!coreDatabase.HasErrorState()) if (!coreDatabase.HasErrorState())
@@ -229,8 +229,8 @@ namespace Sarand.BusinessMgr.Web.Portal.App
/// </summary> /// </summary>
public FilterData Filter { get; private set; } = new FilterData(); public FilterData Filter { get; private set; } = new FilterData();
// Contacts filter. // Contact filter.
public class ContactsData public class ContactData
{ {
public class FilterData public class FilterData
{ {
@@ -240,10 +240,10 @@ namespace Sarand.BusinessMgr.Web.Portal.App
public FilterData Filter { get; } = new FilterData(); public FilterData Filter { get; } = new FilterData();
} }
/// <summary>Contacts filter properties.</summary> /// <summary>Contacts filter properties.</summary>
public ContactsData Contacts { get; } = new ContactsData(); public ContactData Contact { get; } = new ContactData();
// Associations filter. // Association filter.
public class AssociationsData public class AssociationData
{ {
public class FilterData public class FilterData
{ {
@@ -253,10 +253,10 @@ namespace Sarand.BusinessMgr.Web.Portal.App
public FilterData Filter { get; } = new FilterData(); public FilterData Filter { get; } = new FilterData();
} }
/// <summary>Associations filter properties.</summary> /// <summary>Associations filter properties.</summary>
public AssociationsData Associations { get; } = new AssociationsData(); public AssociationData Association { get; } = new AssociationData();
// Commodities filter. // Commodity filter.
public class CommoditiesData public class CommodityData
{ {
public class FilterData public class FilterData
{ {
@@ -266,7 +266,20 @@ namespace Sarand.BusinessMgr.Web.Portal.App
public FilterData Filter { get; } = new FilterData(); public FilterData Filter { get; } = new FilterData();
} }
/// <summary>Commodities filter properties.</summary> /// <summary>Commodities filter properties.</summary>
public CommoditiesData Commodities { get; } = new CommoditiesData(); public CommodityData Commodity { get; } = new CommodityData();
// Transaction filter.
public class TransactionData
{
public class FilterData
{
public uint PageNo { get; set; } = 1;
public ushort PageLength { get; set; } = 200;
}
public FilterData Filter { get; } = new FilterData();
}
/// <summary>Transaction filter properties.</summary>
public TransactionData Transaction { get; } = new TransactionData();
} }
public UserProfileData Profile { get; protected set; } = new UserProfileData(); public UserProfileData Profile { get; protected set; } = new UserProfileData();
@@ -166,7 +166,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
{ {
// Identify item. // Identify item.
SysId assetCategoryId = model.AssetCategory.Id.ToSysId(); SysId assetCategoryId = SysId.ToSysId(model.AssetCategory.Id);
if (!SysId.IsValid(assetCategoryId)) if (!SysId.IsValid(assetCategoryId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -203,7 +203,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId assetCategoryId = model.AssetCategory.Id.ToSysId(); SysId assetCategoryId = SysId.ToSysId(model.AssetCategory.Id);
if (StringUtil.ToBool(model.AssetCategory.Exists) && !SysId.IsValid(assetCategoryId)) if (StringUtil.ToBool(model.AssetCategory.Exists) && !SysId.IsValid(assetCategoryId))
{ {
SaLogger.Warn($"{SysUtil.Fn} AssetCategory Id not supplied for existing item."); SaLogger.Warn($"{SysUtil.Fn} AssetCategory Id not supplied for existing item.");
@@ -172,7 +172,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
{ {
// Identify item. // Identify item.
SysId assetId = model.Asset.Id.ToSysId(); SysId assetId = SysId.ToSysId(model.Asset.Id);
if (!SysId.IsValid(assetId)) if (!SysId.IsValid(assetId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -218,7 +218,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId assetId = model.Asset.Id.ToSysId(); SysId assetId = SysId.ToSysId(model.Asset.Id);
if (StringUtil.ToBool(model.Asset.Exists) && !SysId.IsValid(assetId)) if (StringUtil.ToBool(model.Asset.Exists) && !SysId.IsValid(assetId))
{ {
SaLogger.Warn($"{SysUtil.Fn} Asset Id not supplied for existing item."); SaLogger.Warn($"{SysUtil.Fn} Asset Id not supplied for existing item.");
@@ -262,7 +262,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
} }
else else
{ {
assetCategory = AssetMgr.GetAssetCategoryById(model.Asset.CategoryId.ToSysId()); assetCategory = AssetMgr.GetAssetCategoryById(SysId.ToSysId(model.Asset.CategoryId));
disposables.Add(assetCategory); disposables.Add(assetCategory);
if (assetCategory == null) if (assetCategory == null)
{ {
@@ -174,7 +174,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
{ {
// Identify item. // Identify item.
SysId vehicleClassId = model.VehicleClass.Id.ToSysId(); SysId vehicleClassId = SysId.ToSysId(model.VehicleClass.Id);
if (!SysId.IsValid(vehicleClassId)) if (!SysId.IsValid(vehicleClassId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -211,7 +211,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId vehicleClassId = model.VehicleClass.Id.ToSysId(); SysId vehicleClassId = SysId.ToSysId(model.VehicleClass.Id);
if (StringUtil.ToBool(model.VehicleClass.Exists) && !SysId.IsValid(vehicleClassId)) if (StringUtil.ToBool(model.VehicleClass.Exists) && !SysId.IsValid(vehicleClassId))
{ {
SaLogger.Warn($"{SysUtil.Fn} VehicleClass Id not supplied for existing item."); SaLogger.Warn($"{SysUtil.Fn} VehicleClass Id not supplied for existing item.");
@@ -175,7 +175,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Codes
{ {
// Identify item. // Identify item.
SysId codeId = model.Code.Id.ToSysId(); SysId codeId = SysId.ToSysId(model.Code.Id);
if (!SysId.IsValid(codeId)) if (!SysId.IsValid(codeId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -221,7 +221,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Codes
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId codeId = model.Code.Id.ToSysId(); SysId codeId = SysId.ToSysId(model.Code.Id);
if (StringUtil.ToBool(model.Code.Exists) && !SysId.IsValid(codeId)) if (StringUtil.ToBool(model.Code.Exists) && !SysId.IsValid(codeId))
{ {
SaLogger.Warn($"{SysUtil.Fn} Code Id not supplied for existing item."); SaLogger.Warn($"{SysUtil.Fn} Code Id not supplied for existing item.");
@@ -265,7 +265,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Codes
} }
else else
{ {
codeType = CodeTypeConsole.GetCodeTypeById(model.Code.CodeTypeId.ToSysId()); codeType = CodeTypeConsole.GetCodeTypeById(SysId.ToSysId(model.Code.CodeTypeId));
disposables.Add(codeType); disposables.Add(codeType);
if (codeType == null) if (codeType == null)
{ {
@@ -167,7 +167,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Codes
{ {
// Identify item. // Identify item.
SysId codeTypeId = model.CodeType.Id.ToSysId(); SysId codeTypeId = SysId.ToSysId(model.CodeType.Id);
if (!SysId.IsValid(codeTypeId)) if (!SysId.IsValid(codeTypeId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -204,7 +204,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Codes
RefreshModel(model); RefreshModel(model);
// Validate item Id. // Validate item Id.
SysId codeTypeId = model.CodeType.Id.ToSysId(); SysId codeTypeId = SysId.ToSysId(model.CodeType.Id);
if (StringUtil.ToBool(model.CodeType.Exists) && !SysId.IsValid(codeTypeId)) if (StringUtil.ToBool(model.CodeType.Exists) && !SysId.IsValid(codeTypeId))
{ {
SaLogger.Warn($"{SysUtil.Fn} CodeType Id not supplied for existing item."); SaLogger.Warn($"{SysUtil.Fn} CodeType Id not supplied for existing item.");
@@ -268,8 +268,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
// Refresh paging info. // Refresh paging info.
if (model.Paging.IsPaged) if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Commodities.Count; model.Paging.ItemCount = (ushort)responseData.Commodities.Count;
SessionData_Portal.Profile.Commodities.Filter.PageNo = model.Paging.PageNo; SessionData_Portal.Profile.Commodity.Filter.PageNo = model.Paging.PageNo;
SessionData_Portal.Profile.Commodities.Filter.PageLength = model.Paging.PageLength; SessionData_Portal.Profile.Commodity.Filter.PageLength = model.Paging.PageLength;
responseData.SetPaging(model); responseData.SetPaging(model);
// Complete response. // Complete response.
@@ -304,7 +304,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
RefreshModel(model); RefreshModel(model);
// Identify item. // Identify item.
SysId commodityId = model.Commodity.Id.ToSysId(); SysId commodityId = SysId.ToSysId(model.Commodity.Id);
if (!SysId.IsValid(commodityId)) if (!SysId.IsValid(commodityId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -348,7 +348,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
return Json(responseData); return Json(responseData);
// Validate item Id against 'Exists' flag. // Validate item Id against 'Exists' flag.
SysId commodityId = model.Commodity.Id.ToSysId(); SysId commodityId = SysId.ToSysId(model.Commodity.Id);
bool commodityExists = StringUtil.ToBool(model.Commodity.Exists); bool commodityExists = StringUtil.ToBool(model.Commodity.Exists);
if (commodityExists && !SysId.IsValid(commodityId)) if (commodityExists && !SysId.IsValid(commodityId))
{ {
@@ -48,8 +48,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
// Commodity page. // Commodity page.
RefreshModel(model); RefreshModel(model);
model.PopulateListConfig(); model.PopulateListConfig();
model.Paging.PageNo = SessionData_Portal.Profile.Commodities.Filter.PageNo; model.Paging.PageNo = SessionData_Portal.Profile.Commodity.Filter.PageNo;
model.Paging.PageLength = SessionData_Portal.Profile.Commodities.Filter.PageLength; model.Paging.PageLength = SessionData_Portal.Profile.Commodity.Filter.PageLength;
return View(model); return View(model);
} }
@@ -211,11 +211,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
// Item filter. // Item filter.
SbmAssociation.Params prmAssociation = new SbmAssociation.Params(); SbmAssociation.Params prmAssociation = new SbmAssociation.Params();
if (SysId.IsValid(StringUtil.ToSysId(model.Filter.OwnerId))) if (SysId.IsValid(SysId.ToSysId(model.Filter.OwnerId)))
prmAssociation.AffiliateIdOwner = StringUtil.ToSysId(model.Filter.OwnerId); prmAssociation.AffiliateIdOwner = SysId.ToSysId(model.Filter.OwnerId);
else prmAssociation.AffiliateIdOwner = SessionData_Portal.Organisation.AffiliateId; else prmAssociation.AffiliateIdOwner = SessionData_Portal.Organisation.AffiliateId;
if (SysId.IsValid(StringUtil.ToSysId(model.Filter.TargetId))) if (SysId.IsValid(SysId.ToSysId(model.Filter.TargetId)))
prmAssociation.AffiliateIdTarget = StringUtil.ToSysId(model.Filter.TargetId); prmAssociation.AffiliateIdTarget = SysId.ToSysId(model.Filter.TargetId);
prmAssociation.AssociationType = model.GetFilterAssociationType(); prmAssociation.AssociationType = model.GetFilterAssociationType();
if (prmAssociation.AssociationType <= 0) if (prmAssociation.AssociationType <= 0)
prmAssociation.AssociationType = Sbm.AssociationType.NotInternal; prmAssociation.AssociationType = Sbm.AssociationType.NotInternal;
@@ -270,8 +270,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
// Refresh paging info. // Refresh paging info.
if (model.Paging.IsPaged) if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Associations.Count; model.Paging.ItemCount = (ushort)responseData.Associations.Count;
SessionData_Portal.Profile.Associations.Filter.PageNo = model.Paging.PageNo; SessionData_Portal.Profile.Association.Filter.PageNo = model.Paging.PageNo;
SessionData_Portal.Profile.Associations.Filter.PageLength = model.Paging.PageLength; SessionData_Portal.Profile.Association.Filter.PageLength = model.Paging.PageLength;
responseData.SetPaging(model); responseData.SetPaging(model);
// Complete response. // Complete response.
@@ -310,7 +310,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
{ {
// Identify item. // Identify item.
SysId associationId = model.Association.Id.ToSysId(); SysId associationId = SysId.ToSysId(model.Association.Id);
if (!SysId.IsValid(associationId)) if (!SysId.IsValid(associationId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -363,7 +363,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
{ {
// Validate item Id against 'Exists' flag. // Validate item Id against 'Exists' flag.
SysId associationId = model.Association.Id.ToSysId(); SysId associationId = SysId.ToSysId(model.Association.Id);
bool associationExists = StringUtil.ToBool(model.Association.Exists); bool associationExists = StringUtil.ToBool(model.Association.Exists);
if (associationExists && !SysId.IsValid(associationId)) if (associationExists && !SysId.IsValid(associationId))
{ {
@@ -395,7 +395,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"])); return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
} }
// New item. // New item.
association = AccountMgr.CreateAssociation(SessionData_Portal.Organisation.AffiliateId, associationType, model.Association.ContactIdTarget.ToSysId()); association = AccountMgr.CreateAssociation(SessionData_Portal.Organisation.AffiliateId, associationType, SysId.ToSysId(model.Association.ContactIdTarget));
disposables.Add(association); disposables.Add(association);
} }
@@ -442,7 +442,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
association.LastCall = model.ParseDateFromForm(model.Association.LastCallDate); association.LastCall = model.ParseDateFromForm(model.Association.LastCallDate);
// Customer. // Customer.
if (model.Association.CommodityIdSalesDefault != null) if (model.Association.CommodityIdSalesDefault != null)
association.CommodityIdSalesDefault = model.Association.CommodityIdSalesDefault.ToSysId(); association.CommodityIdSalesDefault = SysId.ToSysId(model.Association.CommodityIdSalesDefault);
if (model.Association.OrderLeadTimeCode != null) if (model.Association.OrderLeadTimeCode != null)
association.OrderLeadTimeCode = model.Association.OrderLeadTimeCode; association.OrderLeadTimeCode = model.Association.OrderLeadTimeCode;
if (model.Association.DeliveryTypeCode != null) if (model.Association.DeliveryTypeCode != null)
@@ -467,9 +467,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
if (model.Association.DiscountRate != null) if (model.Association.DiscountRate != null)
association.DiscountRate = StringUtil.ToDecimal(model.Association.DiscountRate); association.DiscountRate = StringUtil.ToDecimal(model.Association.DiscountRate);
if (model.Association.PriceSetId != null) if (model.Association.PriceSetId != null)
association.PriceSetId = model.Association.PriceSetId.ToSysId(); association.PriceSetId = SysId.ToSysId(model.Association.PriceSetId);
if (model.Association.TaxCodeId != null) if (model.Association.TaxCodeId != null)
association.TaxCodeId = model.Association.TaxCodeId.ToSysId(); association.TaxCodeId = SysId.ToSysId(model.Association.TaxCodeId);
if (model.Association.PaymentTerms != null) if (model.Association.PaymentTerms != null)
association.PaymentTerms = StringUtil.ToShort(model.Association.PaymentTerms); association.PaymentTerms = StringUtil.ToShort(model.Association.PaymentTerms);
if (model.Association.InvoiceDesc != null) if (model.Association.InvoiceDesc != null)
@@ -58,8 +58,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
else if (Request.Path.Value.MatchCI("/Suppliers/?$")) else if (Request.Path.Value.MatchCI("/Suppliers/?$"))
model.Filter.AssociationType = Internals.AssociationTypeCodes.GetCodeForType(Sbm.AssociationType.Supplier); model.Filter.AssociationType = Internals.AssociationTypeCodes.GetCodeForType(Sbm.AssociationType.Supplier);
model.PopulateListConfig(); model.PopulateListConfig();
model.Paging.PageNo = SessionData_Portal.Profile.Associations.Filter.PageNo; model.Paging.PageNo = SessionData_Portal.Profile.Association.Filter.PageNo;
model.Paging.PageLength = SessionData_Portal.Profile.Associations.Filter.PageLength; model.Paging.PageLength = SessionData_Portal.Profile.Association.Filter.PageLength;
return View(model); return View(model);
} }
@@ -291,8 +291,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
// Refresh paging info. // Refresh paging info.
if (model.Paging.IsPaged) if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Contacts.Count; model.Paging.ItemCount = (ushort)responseData.Contacts.Count;
SessionData_Portal.Profile.Contacts.Filter.PageNo = model.Paging.PageNo; SessionData_Portal.Profile.Contact.Filter.PageNo = model.Paging.PageNo;
SessionData_Portal.Profile.Contacts.Filter.PageLength = model.Paging.PageLength; SessionData_Portal.Profile.Contact.Filter.PageLength = model.Paging.PageLength;
responseData.SetPaging(model); responseData.SetPaging(model);
// Complete response. // Complete response.
@@ -327,7 +327,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
RefreshModel(model); RefreshModel(model);
// Identify item. // Identify item.
SysId affiliateId = model.Contact.Id.ToSysId(); SysId affiliateId = SysId.ToSysId(model.Contact.Id);
if (!SysId.IsValid(affiliateId)) if (!SysId.IsValid(affiliateId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
@@ -371,7 +371,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
return Json(responseData); return Json(responseData);
// Validate item Id against 'Exists' flag. // Validate item Id against 'Exists' flag.
SysId affiliateId = model.Contact.Id.ToSysId(); SysId affiliateId = SysId.ToSysId(model.Contact.Id);
bool contactExists = StringUtil.ToBool(model.Contact.Exists); bool contactExists = StringUtil.ToBool(model.Contact.Exists);
if (contactExists && !SysId.IsValid(affiliateId)) if (contactExists && !SysId.IsValid(affiliateId))
{ {
@@ -48,8 +48,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
// Contact page. // Contact page.
RefreshModel(model); RefreshModel(model);
model.PopulateListConfig(); model.PopulateListConfig();
model.Paging.PageNo = SessionData_Portal.Profile.Contacts.Filter.PageNo; model.Paging.PageNo = SessionData_Portal.Profile.Contact.Filter.PageNo;
model.Paging.PageLength = SessionData_Portal.Profile.Contacts.Filter.PageLength; model.Paging.PageLength = SessionData_Portal.Profile.Contact.Filter.PageLength;
return View(model); return View(model);
} }
@@ -384,9 +384,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
NameValueCollection linkParams = DecryptParameters(encryptedParams, KeepLoggedIn.Base64IV, KeepLoggedIn.Base64Key); NameValueCollection linkParams = DecryptParameters(encryptedParams, KeepLoggedIn.Base64IV, KeepLoggedIn.Base64Key);
keepLoggedInParams.RepositoryContext = linkParams.Get(ParamName_KeepLoggedIn_RepositoryContext); keepLoggedInParams.RepositoryContext = linkParams.Get(ParamName_KeepLoggedIn_RepositoryContext);
keepLoggedInParams.EmailAddress = linkParams.Get(ParamName_KeepLoggedIn_EmailAddress); keepLoggedInParams.EmailAddress = linkParams.Get(ParamName_KeepLoggedIn_EmailAddress);
keepLoggedInParams.SecurityItemId = linkParams.Get(ParamName_KeepLoggedIn_SecurityItemId).ToSysId(); keepLoggedInParams.SecurityItemId = SysId.ToSysId(linkParams.Get(ParamName_KeepLoggedIn_SecurityItemId));
keepLoggedInParams.AffiliateIdUser = linkParams.Get(ParamName_KeepLoggedIn_AffiliateIdUser).ToSysId(); keepLoggedInParams.AffiliateIdUser = SysId.ToSysId(linkParams.Get(ParamName_KeepLoggedIn_AffiliateIdUser));
keepLoggedInParams.AssociationIdOrganisation = linkParams.Get(ParamName_KeepLoggedIn_AssociationIdOrganisation).ToSysId(); keepLoggedInParams.AssociationIdOrganisation = SysId.ToSysId(linkParams.Get(ParamName_KeepLoggedIn_AssociationIdOrganisation));
} }
if (DebugMode) SaLogger.Info($"{SysUtil.Fn} UserAccountId: {SysId.ToString(keepLoggedInParams.AffiliateIdUser)}"); if (DebugMode) SaLogger.Info($"{SysUtil.Fn} UserAccountId: {SysId.ToString(keepLoggedInParams.AffiliateIdUser)}");
return keepLoggedInParams; return keepLoggedInParams;
@@ -132,7 +132,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
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 (!securityItemUser.PasswordMatches(model.Password)) if (!securityConsoleForUser.PasswordMatches(securityItemUser, model.Password))
{ {
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;
@@ -242,7 +242,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
{ {
// Previously selected organisation is stored in user params (SysParam table). // Previously selected organisation is stored in user params (SysParam table).
SbmSysParamCache sysParamCache = new SbmSysParamCache(userContext, userContext.UserAffiliateId); SbmSysParamCache sysParamCache = new SbmSysParamCache(userContext, userContext.UserAffiliateId);
SysId affiliateIdOrganisation = StringUtil.ToSysId(sysParamCache.GetUserParamValue(SbmSysParamCache.ParamName_SelectedCompany)); SysId affiliateIdOrganisation = SysId.ToSysId(sysParamCache.GetUserParamValue(SbmSysParamCache.ParamName_SelectedCompany));
SbmAssociation associationOrganisation = null; SbmAssociation associationOrganisation = null;
foreach (SysIdString supervisedOrganisation in userContext.SupervisedOrganisations) foreach (SysIdString supervisedOrganisation in userContext.SupervisedOrganisations)
{ {
@@ -0,0 +1,436 @@
using Microsoft.AspNetCore.Mvc;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Web.Portal.Models;
using Sarand.BusinessMgr.Web.Portal.Models.Transactions;
using Sarand.BusinessMgr.Web.Portal.Models.Contacts;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Security;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm;
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
{
//=======================================================================
// Portal Transaction Controller - Ajax actions.
//=======================================================================
partial class TransactionController
{
//-------------------------------------------------------------------
// Item data.
private class TransactionListData : AjaxResponse_Data.ItemData_Base
{
// Item properties with specific handling.
public String Reference { get; set; }
public String Narrative { get; set; }
// Fields.
public class FieldData
{
// Item property values keyed to match field name.
public Dictionary<string, string> Value { get; } = new Dictionary<string, string>();
}
public FieldData Field { get; } = new FieldData();
}
private enum TransactionDataGroup
{
Core, Delivery
}
private class TransactionItemData : TransactionListData
{
// Affiliate properties with specific handling.
public String TypeCode { get; set; }
public String TypeDesc { get; set; }
}
private void PopulateTransactionResponseListData(SbmTransaction transaction, TransactionListData data)
{
data.Id = SysId.ToString(transaction.Id);
}
private void PopulateTransactionResponseItemData(SbmTransaction transaction, TransactionItemData data, HashSet<TransactionDataGroup> dataGroups = null)
{
PopulateTransactionResponseListData(transaction, data as TransactionListData);
// Prominent properties for selecting and editing.
data.Reference = transaction.Ref;
data.Narrative = transaction.DescBrief;
// Affiliate type - populate for list ('Type' property populated with desc) and form (Type Code & Desc).
data.TypeCode = Internals.TransactionTypeCodes.GetCodeForType(transaction.TransactionType);
data.TypeDesc = Internals.TransactionTypeCodes.GetDescForType(transaction.TransactionType);
data.Field.Value.Add($"{Model_Transaction.ItemField.Type}", Internals.TransactionTypeCodes.GetDescForType(transaction.TransactionType));
// Transaction properties.
data.Field.Value.Add($"{Model_Transaction.ItemField.Reference}", transaction.Ref);
data.Field.Value.Add($"{Model_Transaction.ItemField.ReferenceExt}", transaction.RefExt);
data.Field.Value.Add($"{Model_Transaction.ItemField.DescBrief}", transaction.DescBrief);
if (dataGroups != null && dataGroups.Contains(TransactionDataGroup.Core))
{
// Core.
}
if (dataGroups != null && dataGroups.Contains(TransactionDataGroup.Delivery))
{
// Delivery.
data.Field.Value.Add($"{Model_Transaction.ItemField.DeliveryStatus}", transaction.DeliveryStatusCode);
data.Field.Value.Add($"{Model_Transaction.ItemField.DeliveryType}", transaction.DeliveryTypeCode);
data.Field.Value.Add($"{Model_Transaction.ItemField.DeliveryMethod}", transaction.DeliveryMethodCode);
data.Field.Value.Add($"{Model_Transaction.ItemField.DeliveryCourier}", transaction.DeliveryCourierCode);
}
// Common properties.
data.StatusCode = transaction.StatusCode;
data.StatusDesc = transaction.StatusDesc;
data.Field.Value.Add($"{Model_Contact.ItemField.Status}", transaction.StatusDesc);
// Cleanse field values.
data.Field.Value.RemoveAll(item => StringUtil.IsBlank(item.Value));
// Populate item list values that might be cleared during update after removing blank values to ensure that blank values are published.
data.Field.Value.Add($"{Model_Transaction.ItemField.Notes}", transaction.Notes);
data.Field.Value.Add($"{Model_Transaction.ItemField.UpdatedOn}", Localiser.FormatDate(transaction.UpdateStamp.On));
}
//-------------------------------------------------------------------
// Transaction configuration.
//-------------------------------------------------------------------
private class AjaxResponse_TransactionConfig : AjaxResponse_Data
{
// Construction.
public AjaxResponse_TransactionConfig(SbmModel_Portal model) : base(model) { }
// Configuration.
public Model_Transaction.ListConfigData Config { get; } = new Model_Transaction.ListConfigData();
public Model_Transaction.ItemConfigData ConfigCmd { get; } = new Model_Transaction.ItemConfigData();
// Reference data.
public List<CodeDesc> TransactionTypes { get; } = new List<CodeDesc>();
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
public String DefaultStatusCode { get; set; }
}
// Ajax request.
[HttpPost]
[Route("Transaction/Ajax/Config")]
[Route("Transaction/Ajax/GetConfig")]
public IActionResult Ajax_TransactionConfig(Model_Transaction model)
{
AjaxResponse_TransactionConfig responseData = new AjaxResponse_TransactionConfig(model);
String messageTitle = Localiser["caption.transactions"];
// Validate session and referrer.
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
if (!ValidReferer) return Forbid();
RefreshModel(model);
// Populate configuration data.
PopulateTransactionConfig(model, responseData);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
private void PopulateTransactionConfig(Model_Transaction model, AjaxResponse_TransactionConfig responseData)
{
// Configuration.
model.PopulateListConfig(responseData.Config);
model.PopulateItemConfig(responseData.ConfigCmd, null, Sbm.TransactionType.Unknown);
// Reference data - transaction types.
foreach (TypeCodeDesc transactionType in GetCodesOfType(Sbm.SystemCode.TransactionType))
responseData.TransactionTypes.Add(transactionType.Code, transactionType.Desc);
// Reference data - statuses.
foreach (SaStatus status in SbmTransaction.ValidStatuses().FindAll(item => item != SaStatus.Deleted))
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SbmTransaction.DefaultStatus);
}
//-------------------------------------------------------------------
// Transaction list.
//-------------------------------------------------------------------
private class AjaxResponse_TransactionList : AjaxResponse_TransactionConfig
{
// Construction.
public AjaxResponse_TransactionList(SbmModel_Portal model) : base(model) { }
// View mode.
public class ModeData
{
public bool? Search { get; set; }
public bool? Maintain { get; set; }
public bool? SearchRequirement { get; set; }
public bool? DeliveryPlanning { get; set; }
public bool? TransactionsForSourceTrans { get; set; }
public bool? TransactionsForAssociation { get; set; }
}
public ModeData Mode { get; set; }
// Transaction list.
public List<TransactionListData> Transactions { get; } = new List<TransactionListData>();
}
// Ajax request.
[HttpPost]
[Route("Transaction/Ajax/List")]
[Route("Transaction/Ajax/GetList")]
public IActionResult Ajax_TransactionList(Model_Transaction model)
{
AjaxResponse_TransactionList responseData = new AjaxResponse_TransactionList(model);
String messageTitle = Localiser["caption.transactions"];
// Validate session and referrer.
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
if (!ValidReferer) return Forbid();
RefreshModel(model);
// Populate configuration data.
PopulateTransactionConfig(model, responseData);
// View mode.
responseData.Mode = new AjaxResponse_TransactionList.ModeData();
Model_Transaction.TransactionViewMode viewMode = model.GetFilterMode();
if (viewMode == Model_Transaction.TransactionViewMode.Maintain)
responseData.Mode.Maintain = true;
else if (viewMode == Model_Transaction.TransactionViewMode.SearchRequirement)
responseData.Mode.SearchRequirement = true;
else if (viewMode == Model_Transaction.TransactionViewMode.DeliveryPlanning)
responseData.Mode.DeliveryPlanning = true;
else if (viewMode == Model_Transaction.TransactionViewMode.TransactionsForSourceTrans)
responseData.Mode.TransactionsForSourceTrans = true;
else if (viewMode == Model_Transaction.TransactionViewMode.TransactionsForAssociation)
responseData.Mode.TransactionsForAssociation = true;
else
responseData.Mode.Search = true;
// Item filter.
SbmTransaction.Params prmTransaction = new SbmTransaction.Params();
prmTransaction.Search = model.Filter.Search;
prmTransaction.TransactionType = model.GetFilterTransactionType();
prmTransaction.StatusCat = SbmTransaction.StatusCat.NotDeleted;
if (model.GetFilterTransactionType() <= 0)
prmTransaction.SortColumns.Add(TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Type_Desc));
prmTransaction.SortColumns.Add(TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Ref));
model.Paging.ItemTotal = (ulong)TransactionMgr.GetTransactionCount(prmTransaction);
model.PopulatePagingTo(prmTransaction.ResultsPaging);
// Item columns.
ColumnDfn colId = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Id);
ColumnDfn colType = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Type_Desc);
ColumnDfn colRef = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Ref);
ColumnDfn colRefExt = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.RefExt);
ColumnDfn colDescBrief = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.DescBrief);
ColumnDfn colAmountNet = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.AmountNet);
ColumnDfn colAmountTax = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.AmountTax);
ColumnDfn colAmountTot = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.AmountTot);
ColumnDfn colNotes = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Notes);
ColumnDfn colStatus = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.Status);
ColumnDfn colCreatedOn = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.CreateOn_Date);
ColumnDfn colUpdatedOn = TransactionMgr.GetTransactionColumnDfn(SbmTransaction.Column.UpdateOn_Date);
List<ColumnDfn> columns = new List<ColumnDfn>()
{
colId, colType, colRef, colRefExt, colDescBrief,
colNotes, colStatus, colCreatedOn, colUpdatedOn
};
if (model.UserCanViewFinancials())
columns.AddRange(new[] { colAmountNet, colAmountTax, colAmountTot });
// Query items.
using (DbResultSet resultSet = TransactionMgr.ExecuteTransactionQuery(columns, prmTransaction))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
Sbm.TransactionType transactionType = (Sbm.TransactionType)values.GetLong(colType.DataName);
TransactionListData transactionData = new TransactionListData()
{
Id = values.GetString(colId.DataName),
Reference = values.GetString(colRef.DataName),
Narrative = values.GetString(colDescBrief.DataName),
StatusCode = values.GetString(colStatus.DataName),
};
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.Type}", Internals.TransactionTypeCodes.GetDescForType(transactionType));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.Reference}", values.GetString(colRef.DataName));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.ReferenceExt}", values.GetString(colRefExt.DataName));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.DescBrief}", values.GetString(colDescBrief.DataName));
if (model.UserCanViewFinancials())
{
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.AmountNet}", colAmountNet.FormatValue(values));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.AmountTax}", colAmountTax.FormatValue(values));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.AmountTotal}", colAmountTot.FormatValue(values));
}
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.Notes}", TransactionMgr.GetTransactionDataValue(colNotes, values).ToString());
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.Status}", SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.CreatedOn}", Localiser.FormatDate(values.GetDate(colCreatedOn.DataName)));
transactionData.Field.Value.Add($"{Model_Transaction.ItemField.UpdatedOn}", Localiser.FormatDate(values.GetDate(colUpdatedOn.DataName)));
// Cleanse item values.
transactionData.Field.Value.RemoveAll(item => StringUtil.IsBlank(item.Value));
responseData.Transactions.Add(transactionData);
}
}
// Refresh paging info.
if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Transactions.Count;
SessionData_Portal.Profile.Transaction.Filter.PageNo = model.Paging.PageNo;
SessionData_Portal.Profile.Transaction.Filter.PageLength = model.Paging.PageLength;
responseData.SetPaging(model);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
// Get Transaction ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_Transaction : AjaxResponse_Data
{
// Construction.
public AjaxResponse_Transaction(SbmModel_Portal model) : base(model) { }
// Configuration.
public Model_Transaction.ItemConfigData Config { get; } = new Model_Transaction.ItemConfigData();
// Transaction details.
public TransactionItemData transaction { get; } = new TransactionItemData();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Transaction/Ajax/Item")]
[Route("Transaction/Ajax/GetItem")]
public IActionResult Ajax_GetItem(Model_Transaction model)
{
String messageTitle = Localiser["caption.transaction"];
AjaxResponse_Transaction responseData = new AjaxResponse_Transaction(model);
// Validate session and referrer.
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
if (!ValidReferer) return Forbid();
RefreshModel(model);
// Identify item.
SysId transactionId = SysId.ToSysId(model.Transaction.Id);
if (!SysId.IsValid(transactionId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
// Retrieve item.
SbmTransaction transaction = TransactionMgr.GetTransactionById(transactionId);
if (transaction == null)
{
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve transaction for Id: '{model.Transaction.Id}'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Construct response.
model.PopulateItemConfig(responseData.Config, transaction);
PopulateTransactionResponseItemData(transaction, responseData.transaction);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
// Store Transaction ajax request.
//-------------------------------------------------------------------
[HttpPost]
[Route("Transaction/Ajax/Store")]
[Route("Transaction/Ajax/StoreItem")]
public IActionResult Ajax_StoreItem(Model_Transaction model)
{
String messageTitle = Localiser["caption.transaction"];
AjaxResponse_Transaction responseData = new AjaxResponse_Transaction(model);
// Validate session and referrer.
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
if (!ValidReferer) return Forbid();
RefreshModel(model);
// Validate item properties.
model.ValidateTransactionData(responseData);
if (responseData.HasControlErrors())
return Json(responseData);
// Validate item Id against 'Exists' flag.
SysId transactionId = SysId.ToSysId(model.Transaction.Id);
bool transactionExists = StringUtil.ToBool(model.Transaction.Exists);
if (transactionExists && !SysId.IsValid(transactionId))
{
SaLogger.Warn($"{SysUtil.Fn} Id not specified for existing Transaction.");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
if (!transactionExists && SysId.IsValid(transactionId))
{
SaLogger.Warn($"{SysUtil.Fn} Id specified for new Transaction: '{model.Transaction.Id}'");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
// Retrieve existing item.
SbmTransaction transaction = TransactionMgr.GetTransactionById(transactionId);
if (transaction == null && SysId.IsValid(transactionId))
{
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve transaction for Id: '{model.Transaction.Id}'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Create new item if required.
if (transaction == null)
{
SysId associationId = SysId.ToSysId(model.Transaction.AssociationId);
if (!SysId.IsValid(associationId))
{
SaLogger.Warn($"{SysUtil.Fn} Association not specified for new Transaction.");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
transaction = TransactionMgr.CreateTransaction(associationId, model.GetTransactionType());
}
// Populate item properties.
if (model.Transaction.Type != null)
transaction.TransactionType = model.GetTransactionType();
if (model.Transaction.ReferenceExt != null)
transaction.RefExt = model.Transaction.ReferenceExt;
if (model.Transaction.DescBrief != null)
transaction.DescBrief = model.Transaction.DescBrief;
// Common properties.
if (model.Transaction.Notes != null)
transaction.Notes = model.Transaction.Notes;
if (model.Transaction.StatusCode != null)
transaction.Status = model.GetTransactionStatus();
// Store item.
if (!SysId.IsValid(transaction.Id))
{
if (!TransactionMgr.InsertTransaction(transaction, DbUpdateInfo))
{
SaLogger.Warn($"{SysUtil.Fn} Failed to insert transaction: {TransactionMgr.ErrorStateMessage}");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"]));
}
responseData.SetNotification(messageTitle, Localiser["msg.item.created"]);
}
else
{
if (!TransactionMgr.UpdateTransaction(transaction, DbUpdateInfo))
{
SaLogger.Warn($"{SysUtil.Fn} Failed to update transaction [Id:{SysId.ToLong(transaction.Id)}]: {TransactionMgr.ErrorStateMessage}");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"]));
}
responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]);
}
UpdateAssociatedData(transaction);
// Construct response.
model.PopulateItemConfig(responseData.Config, transaction);
PopulateTransactionResponseItemData(transaction, responseData.transaction);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
/// <summary>
/// Bring associated data into line with the transaction.
/// </summary>
/// <param name="transaction"></param>
/// <returns></returns>
private bool UpdateAssociatedData(SbmTransaction transaction)
{
return true;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,59 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Security;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Sarand.BusinessMgr.Web.Portal.Models.Transactions;
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
{
//=======================================================================
public partial class TransactionController : SbmController_Portal
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
public TransactionController(SbmLocaliser localiser, ILogger<TransactionController> logger) :
base(localiser, logger)
{
}
//-------------------------------------------------------------------
[HttpGet]
public IActionResult Index(Model_Transaction model)
{
if (!ValidUserSession)
AutoLoginUser();
// Redirect to sign-in if not signed-in.
if (!ValidUserSession)
{
ClearKeepLoggedInCookie();
return RedirectToAction("", "Security");
}
// Transaction page.
RefreshModel(model);
model.PopulateListConfig();
model.Paging.PageNo = SessionData_Portal.Profile.Transaction.Filter.PageNo;
model.Paging.PageLength = SessionData_Portal.Profile.Transaction.Filter.PageLength;
return View(model);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -68,7 +68,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
String controlName = "AssetCategory"; String controlName = "AssetCategory";
if (StringUtil.IsBlank(Asset.CategoryId)) if (StringUtil.IsBlank(Asset.CategoryId))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (!AssetMgr.AssetCategoryExistsById(Asset.CategoryId.ToSysId())) else if (!AssetMgr.AssetCategoryExistsById(SysId.ToSysId(Asset.CategoryId)))
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
} }
@@ -84,7 +84,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Codes
String controlName = "CodeType"; String controlName = "CodeType";
if (StringUtil.IsBlank(Code.CodeTypeId)) if (StringUtil.IsBlank(Code.CodeTypeId))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]); responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (!CodeTypeConsole.CodeTypeExistsById(Code.CodeTypeId.ToSysId())) else if (!CodeTypeConsole.CodeTypeExistsById(SysId.ToSysId(Code.CodeTypeId)))
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]); responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
} }
@@ -76,8 +76,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Codes
else else
{ {
SaCodeType.Params prmCodeType = new SaCodeType.Params(); SaCodeType.Params prmCodeType = new SaCodeType.Params();
if (StringUtil.ToBool(CodeType.Exists) && SysId.IsValid(CodeType.Id.ToSysId())) if (StringUtil.ToBool(CodeType.Exists) && SysId.IsValid(SysId.ToSysId(CodeType.Id)))
prmCodeType.IdsExcluded.Add(CodeType.Id.ToSysId()); prmCodeType.IdsExcluded.Add(SysId.ToSysId(CodeType.Id));
prmCodeType.Code = CodeType.Code; prmCodeType.Code = CodeType.Code;
if (CodeTypeConsole.GetCodeTypeCount(prmCodeType) > 0) if (CodeTypeConsole.GetCodeTypeCount(prmCodeType) > 0)
responseData.SetControlError(controlName, Localiser["msg.validation.duplicate.value"]); responseData.SetControlError(controlName, Localiser["msg.validation.duplicate.value"]);
@@ -141,7 +141,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
HandlingCode, HandlingCode,
DeliveryCode, DeliveryCode,
//--------------------------------------------------------------- //---------------------------------------------------------------
// Inages. // Images.
ImagePath, ImagePath,
Image, Image,
//--------------------------------------------------------------- //---------------------------------------------------------------
@@ -168,7 +168,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
// Projected sales. // Projected sales.
ProjectedSales, ProjectedSales,
//--------------------------------------------------------------- //---------------------------------------------------------------
// Common properties. // Common.
Notes, Notes,
Status, Status,
CreatedOn, CreatedOn,
@@ -150,9 +150,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
{ {
// Retrieve existing commodity. // Retrieve existing commodity.
SbmCommodity commodity = null; SbmCommodity commodity = null;
if (StringUtil.ToBool(Commodity.Exists) && SysId.IsValid(Commodity.Id.ToSysId())) if (StringUtil.ToBool(Commodity.Exists) && SysId.IsValid(SysId.ToSysId(Commodity.Id)))
{ {
commodity = CommodityMgr.GetCommodityById(Commodity.Id.ToSysId()); commodity = CommodityMgr.GetCommodityById(SysId.ToSysId(Commodity.Id));
disposables.Add(commodity); disposables.Add(commodity);
if (commodity == null) if (commodity == null)
responseData.SetMessage(Localiser["caption.commodity"], Localiser["msg.something.gone.wrong"]); responseData.SetMessage(Localiser["caption.commodity"], Localiser["msg.something.gone.wrong"]);
@@ -167,16 +167,16 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
// Check that no other current commodity exists with this code. // Check that no other current commodity exists with this code.
SbmCommodity.Params prmCommodity = new SbmCommodity.Params(); SbmCommodity.Params prmCommodity = new SbmCommodity.Params();
// Ignore this commodity if it already exists. // Ignore this commodity if it already exists.
if (StringUtil.ToBool(Commodity.Exists) && SysId.IsValid(Commodity.Id.ToSysId())) if (StringUtil.ToBool(Commodity.Exists) && SysId.IsValid(SysId.ToSysId(Commodity.Id)))
prmCommodity.PriceSetIdsExcluded.Add(Commodity.Id.ToSysId()); prmCommodity.PriceSetIdsExcluded.Add(SysId.ToSysId(Commodity.Id));
// Ignore the commodity being superseded, if any. // Ignore the commodity being superseded, if any.
if (SysId.IsValid(Commodity.IdSupersede.ToSysId())) if (SysId.IsValid(SysId.ToSysId(Commodity.IdSupersede)))
prmCommodity.PriceSetIdsExcluded.Add(Commodity.IdSupersede.ToSysId()); prmCommodity.PriceSetIdsExcluded.Add(SysId.ToSysId(Commodity.IdSupersede));
// Same code and issue. // Same code and issue.
prmCommodity.CodeFull = Commodity.Code; prmCommodity.CodeFull = Commodity.Code;
prmCommodity.DrawingIssueFull = Commodity.DrawingIssue; prmCommodity.DrawingIssueFull = Commodity.DrawingIssue;
// Restrict to same customer. // Restrict to same customer.
prmCommodity.AssociationIdCustomer = Commodity.AssocIdCustomer != null ? Commodity.AssocIdCustomer.ToSysId() : commodity.AssociationIdCustomer; prmCommodity.AssociationIdCustomer = Commodity.AssocIdCustomer != null ? SysId.ToSysId(Commodity.AssocIdCustomer) : commodity.AssociationIdCustomer;
prmCommodity.StatusCat = SbmCommodity.StatusCat.Current; prmCommodity.StatusCat = SbmCommodity.StatusCat.Current;
List<SbmCommodity> commodities = CommodityMgr.GetCommodityList(prmCommodity); List<SbmCommodity> commodities = CommodityMgr.GetCommodityList(prmCommodity);
disposables.AddRange(commodities); disposables.AddRange(commodities);
@@ -204,8 +204,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
// Check that a current commodity exists with this code. // Check that a current commodity exists with this code.
SbmCommodity.Params prmCommodity = new SbmCommodity.Params(); SbmCommodity.Params prmCommodity = new SbmCommodity.Params();
// Ignore this commodity if it already exists. // Ignore this commodity if it already exists.
if (StringUtil.ToBool(Commodity.Exists) && SysId.IsValid(Commodity.Id.ToSysId())) if (StringUtil.ToBool(Commodity.Exists) && SysId.IsValid(SysId.ToSysId(Commodity.Id)))
prmCommodity.PriceSetIdsExcluded.Add(Commodity.Id.ToSysId()); prmCommodity.PriceSetIdsExcluded.Add(SysId.ToSysId(Commodity.Id));
// Same code. // Same code.
prmCommodity.CodeFull = Commodity.Code; prmCommodity.CodeFull = Commodity.Code;
prmCommodity.StatusCat = SbmCommodity.StatusCat.Current; prmCommodity.StatusCat = SbmCommodity.StatusCat.Current;
@@ -213,7 +213,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
config.Column.Hide.Add($"{ItemField.CommodityCount}"); config.Column.Hide.Add($"{ItemField.CommodityCount}");
// Members. // Members.
if (!typeIsMember || !StringUtil.ToSysId(Filter.OwnerId).Equals(SessionData_Portal.Organisation.AffiliateId)) if (!typeIsMember || !SysId.ToSysId(Filter.OwnerId).Equals(SessionData_Portal.Organisation.AffiliateId))
config.Column.Hide.Add($"{ItemField.Technician}"); config.Column.Hide.Add($"{ItemField.Technician}");
if (!typeIsMember) if (!typeIsMember)
config.Column.Hide.Add($"{ItemField.Terminated}"); config.Column.Hide.Add($"{ItemField.Terminated}");
@@ -101,7 +101,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
public String StatusCode { get; set; } public String StatusCode { get; set; }
} }
public ContactData Contact { get; } = new ContactData(); public ContactData Contact { get; } = new ContactData();
public SysId GetAffiliateId() { return StringUtil.ToSysId(Contact.Id); } public SysId GetAffiliateId() { return SysId.ToSysId(Contact.Id); }
public Sbm.AffiliateType GetAffiliateType() public Sbm.AffiliateType GetAffiliateType()
{ {
if (StringUtil.ToBool(Contact.IsIndividual)) if (StringUtil.ToBool(Contact.IsIndividual))
@@ -0,0 +1,604 @@
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Drawing;
namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
{
//=======================================================================
// Transaction model - Configuration.
//=======================================================================
partial class Model_Transaction
{
//-------------------------------------------------------------------
// Transaction fields.
//-------------------------------------------------------------------
/// <summary>Prefix for field names.</summary>
public const String FieldNamePrefix = "Transaction";
//-------------------------------------------------------------------
// Legacy Transaction dialog tabs and panels.
// - Transaction.
// - Tab 1:
// - Tab 2:
// - Tab 3:
// - Tab 4:
// - Tab 5:
// - Tab 6:
// - Tab 7:
// - Other.
//-------------------------------------------------------------------
/// <summary>Item fields.</summary>
public enum ItemField
{
//---------------------------------------------------------------
// Transaction.
Pos,
Id,
AssociationTarget,
AssociationIdTarget,
Type,
Reference,
ReferenceExt,
RaisedBy,
AffiliateIdRaise,
AssociationIdOffice,
ContactName,
Likelihood,
TransactionIdSource,
ReferCode,
ReferSource,
AffiliateIdRefer,
AssociationIdContract,
AssociationIdDelivery,
//---------------------------------------------------------------
// Addresses and contact.
TargetAddress,
TargetPostcode,
DeliveryAddress,
DeliveryPostcode,
TargetPhone,
//---------------------------------------------------------------
// Requirements.
ItemCount,
//---------------------------------------------------------------
// Status dates.
Raised,
Required,
InProgress,
DeliveredEst,
DeliveredAct,
Closed,
Department,
DescBrief,
DescIntro,
DescOutline,
DescDetail,
ResponseCode,
ContactAreaCode,
Postcode,
CurrencyId,
//---------------------------------------------------------------
// Costing.
TaxCodeId,
AmountEst,
AmountMax,
AmountNet,
AmountTax,
AmountTotal,
//---------------------------------------------------------------
// Time recording.
TimeCount,
TimeEstimate,
TimeActual,
TimeTotal,
//---------------------------------------------------------------
// Job costing.
CostLabourRateHour,
CostTotal,
PercentMargin,
//---------------------------------------------------------------
// Stock.
AllocationInd,
//---------------------------------------------------------------
// Specification.
LocationIdStock,
Weight,
UomIdWeight,
//---------------------------------------------------------------
// Codes.
/// <summary>Account Manager - determined by association or address. List only.</summary>
AccountManager,
/// <summary>Account Handler - determined by association or address. List only.</summary>
AccountHandler,
/// <summary>Account Handler - determined by transaction, association or address.</summary>
ContactArea,
//---------------------------------------------------------------
// Delivery.
DeliveryStatus,
/// <summary>Delivery Type - determined by transaction, association or address.</summary>
DeliveryType,
/// <summary>Delivery Method - determined by transaction, association or address.</summary>
DeliveryMethod,
/// <summary>Delivery Courier - determined by transaction or association.</summary>
DeliveryCourier,
DeliveryBookIn,
StockPicker,
DeliveryRef,
DeliveryComment,
DeliveryAmountNet,
TaxCodeIdDelivery,
DeliveryAmountTax,
DeliveryAmountTot,
DeliveryDepartment,
DeliveryNominalCode,
BoxCount,
//---------------------------------------------------------------
// Common.
Notes,
Status,
OnHold,
CreatedOn,
UpdatedOn,
Actions,
}
/// <summary>
/// Identifier used by form fields to show control specific messages generated by model validation etc.
/// <para>- Both page and model should use this method to consistently generate the field name.</para>
/// </summary>
public static String GetFieldName(ItemField field)
{
return $"{FieldNamePrefix}{field}";
}
//-------------------------------------------------------------------
// List configuration.
public class ListConfigData
{
// List columns.
public class ColumnData
{
// Column name prefix.
public String Prefix { get; } = Model_Transaction.FieldNamePrefix;
// Hide column.
public HashSet<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Column labels.
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
}
public ColumnData Column { get; } = new ColumnData();
}
public ListConfigData ListConfig { get; private set; }
//-------------------------------------------------------------------
/// <summary>
/// Populate Transaction list configuration data in this model - only required on initial page construction.
/// </summary>
public void PopulateListConfig()
{
ListConfig = new ListConfigData();
PopulateListConfig(ListConfig);
}
/// <summary>
/// Populate Transaction list configuration data.
/// </summary>
public void PopulateListConfig(ListConfigData config)
{
// View properties.
TransactionViewMode viewMode = GetFilterMode();
bool modeIsSearch = viewMode == TransactionViewMode.Search;
bool modeIsMaintain = viewMode == TransactionViewMode.Maintain;
bool modeIsRequirementSearch = viewMode == TransactionViewMode.SearchRequirement;
bool modeIsDeliveryPlanning = viewMode == TransactionViewMode.DeliveryPlanning;
bool modeIsTransactionsForSourceTrans = viewMode == TransactionViewMode.TransactionsForSourceTrans;
bool modeIsTransactionsForAssociation = viewMode == TransactionViewMode.TransactionsForAssociation;
// Item type.
Sbm.TransactionType transactionType = GetFilterTransactionType();
bool isProject = transactionType == Sbm.TransactionType.Project;
bool isSales = SbmTransaction.IsSalesType(transactionType);
bool isSalesLead = transactionType == Sbm.TransactionType.SalesLead;
bool isSalesQuote = transactionType == Sbm.TransactionType.SalesQuote;
bool isSalesOrder = transactionType == Sbm.TransactionType.SalesOrder || transactionType == Sbm.TransactionType.ProformaSalesOrder;
bool isSalesPO = transactionType == Sbm.TransactionType.SalesPO;
bool isSalesDispatch = transactionType == Sbm.TransactionType.SalesDispatch;
bool isSalesInvoice = transactionType == Sbm.TransactionType.SalesInvoice || transactionType == Sbm.TransactionType.ProformaSalesInvoice;
bool isPurchase = SbmTransaction.IsPurchaseType(transactionType);
bool isPurchaseQuote = transactionType == Sbm.TransactionType.PurchaseQuote;
bool isPurchaseOrder = transactionType == Sbm.TransactionType.PurchaseOrder || transactionType == Sbm.TransactionType.ProformaPurchaseOrder;
bool isPurchaseSO = transactionType == Sbm.TransactionType.PurchaseSO;
bool isPurchaseDelivery = transactionType == Sbm.TransactionType.PurchaseDelivery;
bool isPurchaseInvoice = transactionType == Sbm.TransactionType.PurchaseInvoice || transactionType == Sbm.TransactionType.ProformaPurchaseInvoice;
// Status.
SbmTransaction.StatusCat transactionStatusCat = GetFilterTransactionStatusCat();
// Options.
bool allowTimeRecording = SessionConsole.AllowOption(Sbm.ConfigOption.TimeRecording);
bool allowJobCosting = SessionConsole.GetRequirementCostingConfig().AllowRequirementCosting(transactionType) && TransactionMgr.CostColumnsAreAvailable() && UserCanViewFinancials();
//---------------------------------------------------------------
// Transaction list columns.
// Position.
// Id
if (!SbmSystem.DebugMode)
config.Column.Hide.Add($"{ItemField.Id}");
// Reference.
config.Column.Label.Add($"{ItemField.Reference}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_Ref, Localiser["label.reference"]));
// External Reference.
if (!isSalesLead)
{
config.Column.Label.Add($"{ItemField.ReferenceExt}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_RefExt, Localiser["label.reference.ext"]));
}
else
config.Column.Hide.Add($"{ItemField.ReferenceExt}");
// Transaction type.
if (transactionType <= 0)
config.Column.Label.Add($"{ItemField.Type}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_Type, Localiser["label.type"]));
else
config.Column.Hide.Add($"{ItemField.Type}");
// Association.
if (!modeIsTransactionsForAssociation)
{
String associationLabel = Localiser["label.target"];
if (isSales) associationLabel = Localiser["label.customer"];
else if (isPurchase) associationLabel = Localiser["label.supplier"];
config.Column.Label.Add($"{ItemField.AssociationTarget}", associationLabel);
}
config.Column.Hide.Add($"{ItemField.AssociationTarget}");
// Narrative.
config.Column.Label.Add($"{ItemField.DescBrief}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_DescBrief, Localiser["label.narrative"]));
//---------------------------------------------------------------
// Addresses and contact.
// Delivery address.
if (modeIsDeliveryPlanning || (isSalesOrder && SessionConsole.AllowOption(Sbm.ConfigOption.ShowSiteAddrOnTransView)))
{
config.Column.Label.Add($"{ItemField.DeliveryAddress}", Localiser["label.delivery.address"]);
config.Column.Label.Add($"{ItemField.DeliveryPostcode}", Localiser["label.delivery.postcode"]);
}
else
{
config.Column.Hide.Add($"{ItemField.DeliveryAddress}");
config.Column.Hide.Add($"{ItemField.DeliveryPostcode}");
}
// Target address.
if (modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.TargetAddress}", Localiser["label.target.address"]);
config.Column.Label.Add($"{ItemField.TargetPostcode}", Localiser["label.target.postcode"]);
}
else
{
config.Column.Hide.Add($"{ItemField.TargetAddress}");
config.Column.Hide.Add($"{ItemField.TargetPostcode}");
}
// Target phone.
if (isSalesLead)
{
config.Column.Label.Add($"{ItemField.TargetPhone}", Localiser["label.phone"]);
}
else
config.Column.Hide.Add($"{ItemField.TargetPhone}");
//---------------------------------------------------------------
// Requirements.
// Item count.
if (modeIsDeliveryPlanning || (transactionType > 0 && !isSalesLead))
{
config.Column.Label.Add($"{ItemField.ItemCount}", Localiser["label.items"]);
}
else
config.Column.Hide.Add($"{ItemField.ItemCount}");
//---------------------------------------------------------------
// Status dates.
// Raised date.
if (!modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.Raised}", Localiser["label.raised"]);
}
else
config.Column.Hide.Add($"{ItemField.Raised}");
// In Progress date.
if (!modeIsDeliveryPlanning && !isSalesLead && !isSalesDispatch && transactionStatusCat != SbmTransaction.StatusCat.Pending)
{
config.Column.Label.Add($"{ItemField.InProgress}", Localiser["label.in.progress"]);
}
else
config.Column.Hide.Add($"{ItemField.InProgress}");
// Required date.
if (modeIsDeliveryPlanning && !isSalesLead && !isSalesDispatch || transactionStatusCat != SbmTransaction.StatusCat.Closed)
{
String requiredLabel = Localiser["label.required"];
if (isSalesLead) requiredLabel = Localiser["label.expected"];
config.Column.Label.Add($"{ItemField.Required}", requiredLabel);
}
else
config.Column.Hide.Add($"{ItemField.Required}");
// Closed date.
if (modeIsDeliveryPlanning || transactionStatusCat != SbmTransaction.StatusCat.Open)
{
config.Column.Label.Add($"{ItemField.Closed}", Localiser["label.closed"]);
}
else
config.Column.Hide.Add($"{ItemField.Closed}");
//---------------------------------------------------------------
// Amounts.
// Amount net.
if (UserCanViewFinancials() && (isSales || modeIsDeliveryPlanning))
{
config.Column.Label.Add($"{ItemField.AmountNet}", Localiser["label.amount.net"]);
}
else
config.Column.Hide.Add($"{ItemField.AmountNet}");
// Amount tax.
if (UserCanViewFinancials() && (transactionType > 0 && (isSalesQuote || isSalesOrder)))
{
config.Column.Label.Add($"{ItemField.AmountTax}", Localiser["label.amount.tax"]);
}
else
config.Column.Hide.Add($"{ItemField.AmountTax}");
// Amount total.
if (UserCanViewFinancials() && (transactionType > 0 && (isSalesQuote || isSalesOrder)))
{
config.Column.Label.Add($"{ItemField.AmountTotal}", Localiser["label.amount.total"]);
}
else
config.Column.Hide.Add($"{ItemField.AmountTotal}");
//---------------------------------------------------------------
// Codes.
// Account Manager.
if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.AccountManager)) &&
modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.AccountManager}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Association_AccountManagerCode, Localiser["label.account.manager"]));
}
else
config.Column.Hide.Add($"{ItemField.AccountManager}");
// Account Handler.
if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.AccountHandler)) &&
modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.AccountHandler}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Association_AccountHandlerCode, Localiser["label.account.handler"]));
}
else
config.Column.Hide.Add($"{ItemField.AccountHandler}");
// Contact Area.
if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.ContactArea)) &&
SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Transaction_ContactArea) &&
(modeIsDeliveryPlanning || isSalesOrder))
{
config.Column.Label.Add($"{ItemField.ContactArea}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_ContactAreaCode, Localiser["label.contact.area"]));
}
else
config.Column.Hide.Add($"{ItemField.ContactArea}");
//---------------------------------------------------------------
// Delivery.
// Delivery Status.
if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.DeliveryStatus)) &&
modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.DeliveryStatus}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_DeliveryStatusCode, Localiser["label.delivery.status"]));
}
else
config.Column.Hide.Add($"{ItemField.DeliveryStatus}");
// Delivery Type.
if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.DeliveryType)) &&
modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.DeliveryType}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_DeliveryTypeCode, Localiser["label.delivery.type"]));
}
else
config.Column.Hide.Add($"{ItemField.DeliveryType}");
// Delivery Method.
if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.DeliveryMethod)) &&
modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.DeliveryMethod}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_DeliveryMethodCode, Localiser["label.delivery.method"]));
}
else
config.Column.Hide.Add($"{ItemField.DeliveryMethod}");
// Delivery Courier.
if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.DeliveryCourier)) &&
(modeIsDeliveryPlanning || isSalesOrder))
{
config.Column.Label.Add($"{ItemField.DeliveryCourier}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_DeliveryCourierCode, Localiser["label.delivery.courier"]));
}
else
config.Column.Hide.Add($"{ItemField.DeliveryCourier}");
// Box Count.
if (modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.BoxCount}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_BoxCount, Localiser["label.box.count"]));
}
else
config.Column.Hide.Add($"{ItemField.BoxCount}");
//---------------------------------------------------------------
// Stock.
//---------------------------------------------------------------
// Time recording.
if (allowTimeRecording && (isProject || isSalesQuote || isSalesOrder))
{
config.Column.Label.Add($"{ItemField.TimeCount}", Localiser["label.time.count"]);
config.Column.Label.Add($"{ItemField.TimeTotal}", Localiser["label.time.total"]);
}
else
{
config.Column.Hide.Add($"{ItemField.TimeCount}");
config.Column.Hide.Add($"{ItemField.TimeTotal}");
}
//---------------------------------------------------------------
// Job costing.
if (allowJobCosting)
{
config.Column.Label.Add($"{ItemField.CostLabourRateHour}", Localiser["label.cost.rate.hour"]);
config.Column.Label.Add($"{ItemField.CostTotal}", Localiser["label.cost.total"]);
config.Column.Label.Add($"{ItemField.PercentMargin}", Localiser["label.cost.percent.margin"]);
}
else
{
config.Column.Hide.Add($"{ItemField.CostLabourRateHour}");
config.Column.Hide.Add($"{ItemField.CostTotal}");
config.Column.Hide.Add($"{ItemField.PercentMargin}");
}
//---------------------------------------------------------------
// Common.
// Allocation.
if (modeIsDeliveryPlanning)
{
config.Column.Label.Add($"{ItemField.AllocationInd}", Localiser["label.allocation"]);
}
else
config.Column.Hide.Add($"{ItemField.AllocationInd}");
// Status.
if (modeIsSearch)
config.Column.Hide.Add($"{ItemField.Status}");
// Actions.
if (!modeIsMaintain)
config.Column.Hide.Add($"{ItemField.Actions}");
}
//-------------------------------------------------------------------
// Item configuration.
//-------------------------------------------------------------------
// Contact item configuration.
public class ItemConfigData
{
// Item type.
public bool? IsOrganisation { get; set; }
public bool? IsIndividual { get; set; }
public bool? IsGroup { get; set; }
// Item fields.
public class FieldData
{
// Field name prefix.
public String Prefix { get; } = Model_Transaction.FieldNamePrefix;
// Hide field.
public HashSet<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Read-only field.
public HashSet<string> Readonly { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
// Field labels.
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
}
public FieldData Field { get; } = new FieldData();
}
//-------------------------------------------------------------------
/// <summary>
/// Populate item configuration for existing association.
/// </summary>
public void PopulateItemConfig(ItemConfigData config, SbmTransaction transaction)
{
PopulateItemConfig(config, transaction.GetItemId(), transaction.TransactionType);
}
/// <summary>
/// Populate item configuration for new or existing association.
/// </summary>
public void PopulateItemConfig(ItemConfigData config, ItemId transactionItemId, Sbm.TransactionType transactionType)
{
// Item type.
bool isSales = SbmTransaction.IsSalesType(transactionType);
bool isPurchase = SbmTransaction.IsPurchaseType(transactionType);
bool importedFromAccounts = Internals.AccountsDfn.ItemIsImportedFromAccounts(transactionItemId);
bool managedByAccounts = Internals.AccountsDfn.IsItemTypeManagedByAccounts(Sbm.ItemType.Transaction);
bool showNotes = true;
//---------------------------------------------------------------
// Transaction.
// Id.
if (SbmSystem.DebugMode)
config.Field.Readonly.Add($"{ItemField.Id}");
else
config.Field.Hide.Add($"{ItemField.Id}");
// Transaction type.
config.Field.Label.Add($"{ItemField.Type}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_Type, Localiser["label.type"]));
config.Field.Readonly.Add($"{ItemField.Type}");
// Reference.
config.Field.Label.Add($"{ItemField.Reference}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_Ref, Localiser["label.reference"]));
// External Reference.
if (transactionType != Sbm.TransactionType.SalesLead)
{
config.Field.Label.Add($"{ItemField.ReferenceExt}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_RefExt, Localiser["label.reference.ext"]));
}
else
config.Field.Hide.Add($"{ItemField.ReferenceExt}");
// Narrative.
config.Field.Label.Add($"{ItemField.DescBrief}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_DescBrief, Localiser["label.narrative"]));
if (managedByAccounts)
config.Field.Readonly.Add($"{ItemField.DescBrief}");
//---------------------------------------------------------------
// Sales order.
//---------------------------------------------------------------
// Purchase order.
//---------------------------------------------------------------
// Common.
// Notes.
if (!showNotes)
config.Field.Hide.Add($"{ItemField.Notes}");
// Status.
// Read-only if transaction being superceded.
if (managedByAccounts)
config.Field.Readonly.Add($"{ItemField.Status}");
}
//-------------------------------------------------------------------
}
}
@@ -0,0 +1,418 @@
using Microsoft.AspNetCore.Http;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm;
using static Sarand.BusinessMgr.Web.Portal.Models.Contacts.Model_Contact;
namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
{
//=======================================================================
// Transaction model.
//=======================================================================
/// <summary>
/// Transaction model - Filter, Form, validation and configuration.
/// </summary>
public partial class Model_Transaction : SbmModel_Portal
{
//-------------------------------------------------------------------
// Definitions.
public enum TransactionViewMode
{
Search, Maintain, SearchRequirement, DeliveryPlanning, TransactionsForSourceTrans, TransactionsForAssociation
}
//-------------------------------------------------------------------
// Construction.
public Model_Transaction(SbmLocaliser localiser) :
base(localiser)
{
}
//-------------------------------------------------------------------
// Filter properties.
public class FilterData
{
public String Mode { get; set; }
public String TransactionType { get; set; }
public String Search { get; set; }
public String StatusCat { get; set; }
}
public FilterData Filter { get; } = new FilterData();
public TransactionViewMode GetFilterMode()
{
return EnumUtil.ParseEnum(Filter.Mode, TransactionViewMode.Search);
}
public Sbm.TransactionType GetFilterTransactionType()
{
Sbm.TransactionType transactionType = (Sbm.TransactionType)Internals.TransactionTypeCodes.GetTypeForCode(Filter.TransactionType);
if (transactionType == 0 && !StringUtil.IsBlank(Filter.TransactionType) && StringUtil.IsNumeric(Filter.TransactionType, true))
transactionType = (Sbm.TransactionType)StringUtil.ToInt(Filter.TransactionType);
return transactionType;
}
public SbmTransaction.StatusCat GetFilterTransactionStatusCat()
{
return (SbmTransaction.StatusCat)StringUtil.ToInt(Filter.StatusCat);
}
//-------------------------------------------------------------------
// Transaction properties.
public class TransactionData
{
public String Exists { get; set; }
public String Id { get; set; }
public String AssociationId { get; set; }
public String Type { get; set; }
public String Reference { get; set; }
public String ReferenceExt { get; set; }
public String RaisedBy { get; set; }
public String AffiliateIdRaise { get; set; }
public String AssociationIdOffice { get; set; }
public String ContactName { get; set; }
public String Likelihood { get; set; }
public String TransactionIdSource { get; set; }
public String ReferCode { get; set; }
public String ReferSource { get; set; }
public String AffiliateIdRefer { get; set; }
public String AssociationIdContract { get; set; }
public String AssociationIdDelivery { get; set; }
// Status dates.
public String Raised { get; set; }
public String Required { get; set; }
public String InProgress { get; set; }
public String DeliveredEst { get; set; }
public String DeliveredAct { get; set; }
public String Closed { get; set; }
public String Department { get; set; }
public String DescBrief { get; set; }
public String DescIntro { get; set; }
public String DescOutline { get; set; }
public String DescDetail { get; set; }
public String ResponseCode { get; set; }
public String ContactAreaCode { get; set; }
public String Postcode { get; set; }
public String CurrencyId { get; set; }
// Costing.
public String TaxCodeId { get; set; }
public String AmountEst { get; set; }
public String AmountMax { get; set; }
public String AmountNet { get; set; }
public String AmountTax { get; set; }
public String AmountTot { get; set; }
public String TimeEst { get; set; }
public String TimeAct { get; set; }
public String TimeTot { get; set; }
// Specification.
public String LocationIdStock { get; set; }
public String Weight { get; set; }
public String UomIdWeight { get; set; }
public String BoxCount { get; set; }
// Delivery.
public String DeliveryStatusCode { get; set; }
public String DeliveryTypeCode { get; set; }
public String DeliveryMethodCode { get; set; }
public String DeliveryCourierCode { get; set; }
public String DeliveryBookInCode { get; set; }
public String StockPickerCode { get; set; }
public String DeliveryRef { get; set; }
public String DeliveryComment { get; set; }
public String DeliveryAmountNet { get; set; }
public String TaxCodeIdDelivery { get; set; }
public String DeliveryAmountTax { get; set; }
public String DeliveryAmountTot { get; set; }
public String CostLabourRateHour { get; set; }
public String DeliveryDepartment { get; set; }
public String DeliveryNominalCode { get; set; }
// Common properties.
public String Notes { get; set; }
public String StatusCode { get; set; }
}
public TransactionData Transaction { get; } = new TransactionData();
public Sbm.TransactionType GetTransactionType()
{
return (Sbm.TransactionType)Internals.TransactionTypeCodes.GetTypeForCode(Transaction.Type);
}
public SaStatus GetTransactionStatus()
{
return SacsSystem.GetStatusForCode(Transaction.StatusCode);
}
//-------------------------------------------------------------------
// Validation.
//-------------------------------------------------------------------
// Transaction validation.
public bool ValidateTransactionData(Sacs.Web.Components.SaController.AjaxResponse_Data responseData)
{
// Transaction Type.
Sbm.TransactionType transactionType = GetTransactionType();
if (Transaction.Type != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.Type);
if (Transaction.Type.IsEmpty() || GetTransactionType() <= 0)
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (!SessionConsole.AllowTransactionType(transactionType))
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
}
// Association.
if (Transaction.AssociationId != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.AssociationTarget);
SysId associationId = SysId.ToSysId(Transaction.AssociationId);
if (!SysId.IsValid(associationId))
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
}
// Reference.
if (Transaction.Reference != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.Reference);
responseData.SetControlValue(controlName, Transaction.Reference);
if (StringUtil.GetLength(Transaction.Reference) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Ref))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Ref)]);
}
// Ext Reference.
if (Transaction.ReferenceExt != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.ReferenceExt);
responseData.SetControlValue(controlName, Transaction.ReferenceExt);
if (StringUtil.GetLength(Transaction.ReferenceExt) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_RefExt))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_RefExt)]);
}
// Narrative.
if (Transaction.DescBrief != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DescBrief);
responseData.SetControlValue(controlName, Transaction.DescBrief);
if (StringUtil.GetLength(Transaction.DescBrief) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescBrief))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescBrief)]);
}
// Contact Name.
if (Transaction.ContactName != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.ContactName);
responseData.SetControlValue(controlName, Transaction.ContactName);
if (StringUtil.GetLength(Transaction.ContactName) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ContactName))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ContactName)]);
}
// Likelihood.
if (Transaction.Likelihood != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.Likelihood);
responseData.SetControlValue(controlName, Transaction.Likelihood);
if (StringUtil.GetLength(Transaction.Likelihood) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Likelihood))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Likelihood)]);
}
// Referral code.
if (Transaction.ReferCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.ReferCode);
responseData.SetControlValue(controlName, Transaction.ReferCode);
if (StringUtil.GetLength(Transaction.ReferCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ReferCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ReferCode)]);
}
// Refer source.
if (Transaction.ReferSource != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.ReferSource);
responseData.SetControlValue(controlName, Transaction.ReferSource);
if (StringUtil.GetLength(Transaction.ReferSource) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ReferSource))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ReferSource)]);
}
// Department.
if (Transaction.Department != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.Department);
responseData.SetControlValue(controlName, Transaction.Department);
if (StringUtil.GetLength(Transaction.Department) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Department))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Department)]);
}
// Desc Intro.
if (Transaction.DescIntro != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DescIntro);
responseData.SetControlValue(controlName, Transaction.DescIntro);
if (StringUtil.GetLength(Transaction.DescIntro) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescIntro))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescIntro)]);
}
// Desc Outline.
if (Transaction.DescOutline != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DescOutline);
responseData.SetControlValue(controlName, Transaction.DescOutline);
if (StringUtil.GetLength(Transaction.DescOutline) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescOutline))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescOutline)]);
}
// Desc Detail.
if (Transaction.DescDetail != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DescDetail);
responseData.SetControlValue(controlName, Transaction.DescDetail);
if (StringUtil.GetLength(Transaction.DescDetail) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescDetail))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DescDetail)]);
}
// Contact Area code.
if (Transaction.ContactAreaCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.ContactAreaCode);
responseData.SetControlValue(controlName, Transaction.ContactAreaCode);
if (StringUtil.GetLength(Transaction.ContactAreaCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ContactAreaCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ContactAreaCode)]);
}
// Response code.
if (Transaction.ResponseCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.ResponseCode);
responseData.SetControlValue(controlName, Transaction.ResponseCode);
if (StringUtil.GetLength(Transaction.ResponseCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ResponseCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_ResponseCode)]);
}
// Box Count.
if (Transaction.BoxCount != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.BoxCount);
responseData.SetControlValue(controlName, Transaction.BoxCount);
if (StringUtil.GetLength(Transaction.BoxCount) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_BoxCount))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_BoxCount)]);
}
// Delivery Status code.
if (Transaction.DeliveryStatusCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryStatus);
responseData.SetControlValue(controlName, Transaction.DeliveryStatusCode);
if (StringUtil.GetLength(Transaction.DeliveryStatusCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryStatusCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryStatusCode)]);
}
// Delivery Type code.
if (Transaction.DeliveryTypeCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryType);
responseData.SetControlValue(controlName, Transaction.DeliveryTypeCode);
if (StringUtil.GetLength(Transaction.DeliveryTypeCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryTypeCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryTypeCode)]);
}
// Delivery Method code.
if (Transaction.DeliveryMethodCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryMethod);
responseData.SetControlValue(controlName, Transaction.DeliveryMethodCode);
if (StringUtil.GetLength(Transaction.DeliveryMethodCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryMethodCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryMethodCode)]);
}
// Delivery Courier code.
if (Transaction.DeliveryCourierCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryCourier);
responseData.SetControlValue(controlName, Transaction.DeliveryCourierCode);
if (StringUtil.GetLength(Transaction.DeliveryCourierCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryCourierCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryCourierCode)]);
}
// Delivery Book In code.
if (Transaction.DeliveryBookInCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryBookIn);
responseData.SetControlValue(controlName, Transaction.DeliveryBookInCode);
if (StringUtil.GetLength(Transaction.DeliveryBookInCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryBookInCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryBookInCode)]);
}
// Stock Picker code.
if (Transaction.StockPickerCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.StockPicker);
responseData.SetControlValue(controlName, Transaction.StockPickerCode);
if (StringUtil.GetLength(Transaction.StockPickerCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_StockPickerCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_StockPickerCode)]);
}
// Delivery Ref.
if (Transaction.DeliveryRef != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryRef);
responseData.SetControlValue(controlName, Transaction.DeliveryRef);
if (StringUtil.GetLength(Transaction.DeliveryRef) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryRef))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryRef)]);
}
// Delivery Comment.
if (Transaction.DeliveryComment != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryComment);
responseData.SetControlValue(controlName, Transaction.DeliveryComment);
if (StringUtil.GetLength(Transaction.DeliveryComment) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryComment))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryComment)]);
}
// Delivery Department.
if (Transaction.DeliveryDepartment != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryDepartment);
responseData.SetControlValue(controlName, Transaction.DeliveryDepartment);
if (StringUtil.GetLength(Transaction.DeliveryDepartment) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryDepartment))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryDepartment)]);
}
// Delivery Nominal code.
if (Transaction.DeliveryNominalCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.DeliveryNominalCode);
responseData.SetControlValue(controlName, Transaction.DeliveryNominalCode);
if (StringUtil.GetLength(Transaction.DeliveryNominalCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryNominalCode))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_DeliveryNominalCode)]);
}
// Transaction Notes.
if (Transaction.Notes != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.Notes);
responseData.SetControlValue(controlName, Transaction.Notes);
if (!Transaction.Notes.IsEmpty() && StringUtil.GetLength(Transaction.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Notes))
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Transaction_Notes)]);
}
// Transaction status.
if (Transaction.StatusCode != null)
{
String controlName = Model_Transaction.GetFieldName(Model_Transaction.ItemField.Status);
if (Transaction.StatusCode.IsEmpty())
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
else if (!SbmTransaction.ValidStatusesByType(transactionType).Contains(GetTransactionStatus()))
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
}
return !responseData.HasControlErrors();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -13,9 +13,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="jQuery" Version="3.5.1" /> <PackageReference Include="jQuery" Version="3.7.1" />
<PackageReference Include="jQuery.UI.Combined" Version="1.13.3" /> <PackageReference Include="jQuery.UI.Combined" Version="1.14.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.31" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.36" />
<PackageReference Include="System.Data.Odbc" Version="6.0.2" /> <PackageReference Include="System.Data.Odbc" Version="6.0.2" />
</ItemGroup> </ItemGroup>
@@ -68,3 +68,5 @@
<ul class="sbm-dropdown-menu Commodity"> <ul class="sbm-dropdown-menu Commodity">
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li> <li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
</ul> </ul>
</div>
@@ -65,6 +65,4 @@
</div> </div>
</div> </div>
</div>
<partial name="Panel-CommodityDialog.cshtml" /> <partial name="Panel-CommodityDialog.cshtml" />
@@ -169,8 +169,8 @@
</header> </header>
@* Page body *@ @* Page body *@
<div id="sbm-page-body" class="container"> <div id="sbm-page-body">
<main role="main" class="pb-3 fullheight"> <main role="main" class="container pt-2 pb-2 fullheight">
@RenderBody() @RenderBody()
</main> </main>
</div> </div>
@@ -26,7 +26,7 @@
.sbm-panel-data .sbm-panel-data
{ {
margin: 6px auto; margin: 0 auto;
background-color: #f8f8f8; background-color: #f8f8f8;
border: solid 1px var(--color-panel-data); border: solid 1px var(--color-panel-data);
border-radius: 6px; border-radius: 6px;
@@ -59,6 +59,7 @@ body
{ {
flex: 1; flex: 1;
min-height: 0; min-height: 0;
overflow-y: auto;
} }
} }
@@ -52,7 +52,7 @@
} }
ac.populateItem = function ($item, item) ac.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return $item;
$pnl.msgs.hide().empty(); $pnl.msgs.hide().empty();
$item.prop('id', ac.getItemId(item)); $item.prop('id', ac.getItemId(item));
$('.AssetCategoryType', $item).text(item.typeDesc); $('.AssetCategoryType', $item).text(item.typeDesc);
@@ -51,7 +51,7 @@
} }
ac.populateItem = function ($item, item) ac.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return $item;
$pnl.msgs.hide().empty(); $pnl.msgs.hide().empty();
$item.prop('id', ac.getItemId(item)); $item.prop('id', ac.getItemId(item));
$('.AssetCategory', $item).text(item.categoryDesc); $('.AssetCategory', $item).text(item.categoryDesc);
@@ -74,7 +74,7 @@
} }
as.populateItem = function (env, $item, item) as.populateItem = function (env, $item, item)
{ {
if (!item) return; if (!item) return $item;
$item.prop('id', as.getItemId(item)); $item.prop('id', as.getItemId(item));
let cfg = env.config; let cfg = env.config;
sbm.populateItemValues(cfg, $item, item.field.value); sbm.populateItemValues(cfg, $item, item.field.value);
@@ -51,7 +51,7 @@
} }
ac.populateItem = function ($item, item) ac.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return $item;
$pnl.msgs.hide().empty(); $pnl.msgs.hide().empty();
$item.prop('id', ac.getItemId(item)); $item.prop('id', ac.getItemId(item));
$('.CodeTypeCode', $item).text(item.code); $('.CodeTypeCode', $item).text(item.code);
@@ -52,7 +52,7 @@
} }
ac.populateItem = function ($item, item) ac.populateItem = function ($item, item)
{ {
if (!item) return; if (!item) return $item;
$pnl.msgs.hide().empty(); $pnl.msgs.hide().empty();
$item.prop('id', ac.getItemId(item)); $item.prop('id', ac.getItemId(item));
$('.CodeType', $item).text(item.typeName); $('.CodeType', $item).text(item.typeName);
@@ -68,7 +68,7 @@
} }
co.populateItem = function (env, $item, item) co.populateItem = function (env, $item, item)
{ {
if (!item) return; if (!item) return $item;
$item.prop('id', co.getItemId(item)); $item.prop('id', co.getItemId(item));
let cfg = env.config; let cfg = env.config;
if (cfg) sbm.populateItemValues(cfg, $item, item.field.value); if (cfg) sbm.populateItemValues(cfg, $item, item.field.value);

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