Session data.
This commit is contained in:
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Consoles;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Control.Consoles;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
@@ -16,10 +17,18 @@ using Sarand.BusinessMgr.Web.Portal.Consoles;
|
||||
using Sarand.BusinessMgr.Web.Portal.Helpers;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.CodeTypes;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Diary;
|
||||
using Sarand.Net.Standard.Base.Interfaces;
|
||||
using Sarand.Net.Standard.Base.IO;
|
||||
using Sarand.Net.Standard.Base.ItemData;
|
||||
using Sarand.Net.Standard.Base.ItemDocs;
|
||||
using Sarand.Net.Standard.Base.ItemOptions;
|
||||
using Sarand.Net.Standard.Base.ReferenceData;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using Sarand.Net.Standard.Base.UpdateLog;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using Sarand.Net.Standard.Dbas.Base;
|
||||
using System;
|
||||
@@ -82,7 +91,7 @@ namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
try
|
||||
{
|
||||
properties = new PropertySet();
|
||||
SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Web(properties)));
|
||||
SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Portal(properties)));
|
||||
Configuration = configuration;
|
||||
}
|
||||
catch (Exception exc)
|
||||
@@ -159,12 +168,48 @@ namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
public override SbmEmailConfig EmailConfig { get { return emailConfigs.Values.ToList().getConfigForSession(AppConfig); } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Create Consoles.
|
||||
public override SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext)
|
||||
// Create consoles.
|
||||
public SbmSessionConsole CreateSessionConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return SbmSessionConsole.CreateConsole(userContext);
|
||||
}
|
||||
public SaDiaryConsole CreateDiaryConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmSecurityConsole_Web(userContext);
|
||||
}
|
||||
public SaCodeTypeConsole CreateCodeTypeConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmCodeTypeConsole_Web(userContext);
|
||||
}
|
||||
public SaItemDataConsole CreateItemDataConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public SaItemDocConsole CreateItemDocConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public SaItemOptionConsole CreateItemOptionConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmItemOptionConsole_Web(userContext);
|
||||
}
|
||||
public SaInterfaceConsole CreateInterfaceConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public SaUpdateLogConsole CreateUpdateLogConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmUpdateLogConsole_Web(userContext);
|
||||
}
|
||||
public SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmReferenceDataConsole_Portal(userContext);
|
||||
}
|
||||
public override SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext)
|
||||
public SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmEmailConsole_Portal(EmailConfig);
|
||||
}
|
||||
|
||||
@@ -18,33 +18,46 @@ using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config;
|
||||
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm.Config.Database;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Core;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
{
|
||||
//=======================================================================
|
||||
public class SbmSessionData_Portal : SbmSessionData_Web, ISbmUserOrganisationContext
|
||||
public class SbmSessionData_Portal : SbmSessionData_Web, ISbmSessionData_Core
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
[JsonConstructor]
|
||||
private SbmSessionData_Portal(long sessionIdx, int itemIdx, SbmSessionContext sessionContext) :
|
||||
base(sessionIdx, itemIdx, sessionContext)
|
||||
private SbmSessionData_Portal(long sessionIdx, SbmSessionContext sessionContext) :
|
||||
base(sessionIdx, sessionContext)
|
||||
{
|
||||
securityProfile = new SbmSecurityProfile(this, false);
|
||||
securityProfile = new SbmSecurityProfile(false);
|
||||
Organisation = new OrganisationData_Portal(null, null);
|
||||
User = new UserData_Portal(sessionContext, null, null);
|
||||
}
|
||||
/// <summary>
|
||||
/// SessionData construction.
|
||||
/// <para>SessionContext and UserAccount must be supplied.</para>
|
||||
/// <para>Organisation is optional.</para>
|
||||
/// Session Data construction for non-session data, eg. background tasks.
|
||||
/// <para>.</para>
|
||||
/// </summary>
|
||||
public SbmSessionData_Portal(SbmSessionContext sessionContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) :
|
||||
public SbmSessionData_Portal(SbmSessionContext sessionContext) :
|
||||
base(0, sessionContext)
|
||||
{
|
||||
securityProfile = new SbmSecurityProfile(false);
|
||||
Organisation = new OrganisationData_Portal(null, null);
|
||||
User = new UserData_Portal(sessionContext, null, null);
|
||||
}
|
||||
/// <summary>
|
||||
/// Session Data construction.
|
||||
/// <para>- Session Context must be supplied.</para>
|
||||
/// <para>- Other parameters are optional and can be added later via Refresh().</para>
|
||||
/// </summary>
|
||||
public SbmSessionData_Portal(SbmSessionContext sessionContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) :
|
||||
base(sessionContext)
|
||||
{
|
||||
RepositoryContext = repositoryContext;
|
||||
securityProfile = new SbmSecurityProfile(this, false);
|
||||
securityProfile = new SbmSecurityProfile(false);
|
||||
Organisation = new OrganisationData_Portal(associationOrganisation, affiliateOrganisation);
|
||||
User = new UserData_Portal(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations);
|
||||
User = new UserData_Portal(sessionContext, securityItemUser, affiliateUser);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -136,24 +149,10 @@ namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
{
|
||||
[JsonConstructor]
|
||||
private UserData_Portal() { }
|
||||
public UserData_Portal(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations) :
|
||||
public UserData_Portal(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser) :
|
||||
base(sessionContext)
|
||||
{
|
||||
if (securityItemUser != null)
|
||||
{
|
||||
SecurityItemId = securityItemUser.Id;
|
||||
}
|
||||
if (affiliateUser != null)
|
||||
{
|
||||
AffiliateId = affiliateUser.Id;
|
||||
Refresh(securityItemUser, affiliateUser, supervisedOrganisations);
|
||||
if (sessionContext.Application == Sbm.Application.WebControl)
|
||||
KeepLoggedIn = affiliateUser.KeepLoggedIn_Control;
|
||||
else if (sessionContext.Application == Sbm.Application.WebPortal)
|
||||
KeepLoggedIn = affiliateUser.KeepLoggedIn_Portal;
|
||||
else Debugger.Break();
|
||||
}
|
||||
this.supervisedOrganisations = supervisedOrganisations ?? new List<SysIdString>();
|
||||
Refresh(securityItemUser, affiliateUser);
|
||||
}
|
||||
public UserData_Portal(UserData userData) :
|
||||
base(userData)
|
||||
@@ -163,31 +162,36 @@ namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
{
|
||||
SecurityItemId = userData_Portal.SecurityItemId;
|
||||
AffiliateId = userData_Portal.AffiliateId;
|
||||
supervisedOrganisations = userData_Portal.supervisedOrganisations;
|
||||
}
|
||||
}
|
||||
// Properties.
|
||||
public SysId SecurityItemId { get; protected set; }
|
||||
public SysId AffiliateId { get; protected set; }
|
||||
public bool KeepLoggedIn { get; private set; }
|
||||
/// <summary>User managed associations - Id and display name.</summary>
|
||||
public List<SysIdString> SupervisedOrganisations { get { return new List<SysIdString>(supervisedOrganisations); } }
|
||||
protected List<SysIdString> supervisedOrganisations { get; } = new List<SysIdString>();
|
||||
// Utilities.
|
||||
public bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations)
|
||||
public bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser)
|
||||
{
|
||||
base.Refresh();
|
||||
// Check that user matches the session.
|
||||
if (!SysId.IsValid(SecurityItemId) || !SysId.IsValid(securityItemUser?.Id ?? null) || !SecurityItemId.Equals(securityItemUser.Id)) return false;
|
||||
if (!SysId.IsValid(AffiliateId) || !SysId.IsValid(affiliateUser?.Id ?? null) || !AffiliateId.Equals(affiliateUser.Id)) return false;
|
||||
if (!SysId.IsValid(securityItemUser?.Id) || (SysId.IsValid(SecurityItemId) && !SecurityItemId.Equals(securityItemUser.Id)))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Invalid - User Security Item doesn't match session. Expected Id: {SecurityItemId}. Found: {securityItemUser?.Id}.");
|
||||
return false;
|
||||
}
|
||||
if (!SysId.IsValid(affiliateUser?.Id) || (SysId.IsValid(AffiliateId) && !AffiliateId.Equals(affiliateUser.Id)))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Invalid - User Affiliate doesn't match session. Expected Id: {AffiliateId}. Found: {affiliateUser?.Id}.");
|
||||
return false;
|
||||
}
|
||||
// Refresh properties.
|
||||
EmailAddress = securityItemUser.EmailAddress;
|
||||
Title = affiliateUser.Title;
|
||||
FirstName = affiliateUser.FirstName;
|
||||
LastName = affiliateUser.LastName;
|
||||
DisplayName = affiliateUser.GetDisplayName();
|
||||
this.supervisedOrganisations.Clear();
|
||||
this.supervisedOrganisations.AddRange(supervisedOrganisations);
|
||||
AffiliateId = affiliateUser?.Id ?? new SysId();
|
||||
SecurityItemId = securityItemUser?.Id ?? new SysId();
|
||||
EmailAddress = securityItemUser?.EmailAddress ?? "";
|
||||
Title = affiliateUser?.Title ?? "";
|
||||
FirstName = affiliateUser?.FirstName ?? "";
|
||||
LastName = affiliateUser?.LastName ?? "";
|
||||
DisplayName = affiliateUser?.GetDisplayName() ?? "";
|
||||
KeepLoggedIn = affiliateUser?.KeepLoggedIn_Portal ?? false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -195,13 +199,14 @@ namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
/// <summary>Portal User details.</summary>
|
||||
public UserData_Portal User { get; private set; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Update the user's contact details against the session.
|
||||
/// Update the User and Organisation details against the Session Data.
|
||||
/// <para>- User identity must match that already against the session.</para>
|
||||
/// </summary>
|
||||
public bool RefreshUser(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
public bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
{
|
||||
if (User != null && User.Refresh(securityItemUser, affiliateUser, supervisedOrganisations))
|
||||
if (User != null && User.Refresh(securityItemUser, affiliateUser))
|
||||
{
|
||||
Organisation = new OrganisationData_Portal(associationOrganisation, affiliateOrganisation);
|
||||
return true;
|
||||
@@ -211,7 +216,7 @@ namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// User Profile.
|
||||
/// User Profile - persistent session properties relating to default population of views, forms etc.
|
||||
/// <para>- Filter settings.</para>
|
||||
/// </summary>
|
||||
public class UserProfileData
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Consoles;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Control.Consoles;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Core;
|
||||
using Sarand.BusinessMgr.Web.Portal.Consoles;
|
||||
using Sarand.Net.Standard.Base.CodeTypes;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Diary;
|
||||
using Sarand.Net.Standard.Base.Interfaces;
|
||||
using Sarand.Net.Standard.Base.ItemData;
|
||||
using Sarand.Net.Standard.Base.ItemDocs;
|
||||
using Sarand.Net.Standard.Base.ItemOptions;
|
||||
using Sarand.Net.Standard.Base.ReferenceData;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using Sarand.Net.Standard.Base.UpdateLog;
|
||||
using static Sarand.BusinessMgr.Net.Core.Web.App.SbmAppConfig;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.App
|
||||
{
|
||||
public class SbmSystem_Portal:SbmSystem_Web
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SbmSystem_Portal(PropertySet properties) : base(properties)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Create consoles.
|
||||
|
||||
public override SbmSessionConsole CreateSessionConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return SbmSessionConsole.CreateConsole(userContext);
|
||||
}
|
||||
public override SaDiaryConsole CreateDiaryConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public override SaSecurityConsole CreateSecurityConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmSecurityConsole_Web(userContext);
|
||||
}
|
||||
public override SaCodeTypeConsole CreateCodeTypeConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmCodeTypeConsole_Web(userContext);
|
||||
}
|
||||
public override SaItemDataConsole CreateItemDataConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public override SaItemDocConsole CreateItemDocConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public override SaItemOptionConsole CreateItemOptionConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmItemOptionConsole_Web(userContext);
|
||||
}
|
||||
public override SaInterfaceConsole CreateInterfaceConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public override SaUpdateLogConsole CreateUpdateLogConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmUpdateLogConsole_Web(userContext);
|
||||
}
|
||||
public override SaReferenceDataConsole CreateReferenceDataConsole(ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
return new SbmReferenceDataConsole_Portal(userContext);
|
||||
}
|
||||
public override SbmEmailConsole CreateEmailConsole(ISbmUserOrganisationContext userContext, SbmEmailConfig emailConfig)
|
||||
{
|
||||
return new SbmEmailConsole_Portal(emailConfig);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
+131
-32
@@ -1,9 +1,9 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models.Assets;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models.Commodities;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
@@ -14,19 +14,26 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
{
|
||||
//=======================================================================
|
||||
// Portal Asset Category Controller - Ajax actions.
|
||||
//=======================================================================
|
||||
partial class AssetCategoryController
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
// AssetCategory data.
|
||||
// Item data.
|
||||
private class AssetCategoryListData : AjaxResponse_Data.ItemData_Base
|
||||
{
|
||||
public String TypeDesc { get; set; }
|
||||
public String Code { get; set; }
|
||||
public String DescBrief { get; set; }
|
||||
public String Caption { get; set; }
|
||||
public long? AssetCount { get; set; }
|
||||
// Fields.
|
||||
public class FieldData
|
||||
{
|
||||
// Item property values keyed to match field name.
|
||||
public Dictionary<string, string> Value { get; } = new Dictionary<string, string>();
|
||||
}
|
||||
public FieldData Field { get; } = new FieldData();
|
||||
}
|
||||
private class AssetCategoryItemData : AssetCategoryListData
|
||||
{
|
||||
@@ -35,33 +42,111 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
private void PopulateAssetCategoryResponseListData(SbmModel_Portal model, AssetCategoryListData data, SbmAssetCategory assetCategory)
|
||||
{
|
||||
data.Id = SysId.ToString(assetCategory.Id);
|
||||
data.TypeDesc = Internals.AssetTypeCodes.GetDescForType(assetCategory.AssetType);
|
||||
// Prominent properties for selecting and editing.
|
||||
data.Code = assetCategory.Code;
|
||||
data.DescBrief = assetCategory.DescBrief;
|
||||
data.StatusCode = assetCategory.StatusCode;
|
||||
data.StatusDesc = assetCategory.StatusDesc;
|
||||
data.Caption = assetCategory.DescBrief;
|
||||
// Asset count.
|
||||
long assetCount = Internals.AssetMgr.GetAssetCountForAssetCategory(assetCategory.Id);
|
||||
if (assetCount > 0) data.AssetCount = assetCount;
|
||||
}
|
||||
private void PopulateAssetCategoryResponseItemData(SbmModel_Portal model, AssetCategoryItemData data, SbmAssetCategory assetCategory)
|
||||
{
|
||||
PopulateAssetCategoryResponseListData(model, data, assetCategory);
|
||||
// Asset type - populate for list ('Type' property populated with desc) and form (Type Code & Desc).
|
||||
data.TypeCode = Internals.AssetTypeCodes.GetCodeForType(assetCategory.AssetType);
|
||||
data.Notes = assetCategory.Notes;
|
||||
data.TypeDesc = Internals.AssetTypeCodes.GetDescForType(assetCategory.AssetType);
|
||||
data.Field.Value.Add($"{Model_AssetCategory.ItemField.Type}", Internals.AssetTypeCodes.GetDescForType(assetCategory.AssetType));
|
||||
// Asset Category properties.
|
||||
data.Field.Value.Add($"{Model_AssetCategory.ItemField.Code}", assetCategory.Code);
|
||||
data.Field.Value.Add($"{Model_AssetCategory.ItemField.Caption}", assetCategory.DescBrief);
|
||||
// Common properties.
|
||||
data.StatusCode = assetCategory.StatusCode;
|
||||
data.StatusDesc = assetCategory.StatusDesc;
|
||||
data.Field.Value.Add($"{Model_AssetCategory.ItemField.Status}", assetCategory.StatusDesc);
|
||||
// Cleanse field values.
|
||||
data.Field.Value.RemoveAll(item => StringUtil.IsBlank(item.Value));
|
||||
// Populate item list values that might be cleared during update after removing blank values to ensure that blank values are published.
|
||||
data.Field.Value.Add($"{Model_AssetCategory.ItemField.Notes}", assetCategory.Notes);
|
||||
data.Field.Value.Add($"{Model_AssetCategory.ItemField.UpdatedOn}", Localiser.FormatDate(assetCategory.UpdateStamp.On));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Get AssetCategory List ajax request.
|
||||
// Asset Category configuration.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_AssetCategoryList : AjaxResponse_Data
|
||||
private class AjaxResponse_AssetCategoryConfig : AjaxResponse_Data
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_AssetCategoryList(SbmModel_Portal model) : base(model) { }
|
||||
// AssetCategory list.
|
||||
public List<AssetCategoryListData> AssetCategories { get; } = new List<AssetCategoryListData>();
|
||||
public AjaxResponse_AssetCategoryConfig(SbmModel_Portal model) : base(model) { }
|
||||
// Configuration.
|
||||
public Model_AssetCategory.ListConfigData Config { get; } = new Model_AssetCategory.ListConfigData();
|
||||
public Model_AssetCategory.ItemConfigData ConfigItemNew { get; } = new Model_AssetCategory.ItemConfigData();
|
||||
// Reference data.
|
||||
public List<CodeDesc> AssetTypes { get; } = new List<CodeDesc>();
|
||||
public List<CodeDesc> IncomeTypes { get; } = new List<CodeDesc>();
|
||||
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
|
||||
public List<CodeDesc> StatusesCreate { get; } = new List<CodeDesc>();
|
||||
public String StatusCodeDefault { get; set; }
|
||||
}
|
||||
// Ajax request.
|
||||
[HttpPost]
|
||||
[Route("Assets/AssetCategory/Ajax/Config")]
|
||||
[Route("Assets/AssetCategory/Ajax/GetConfig")]
|
||||
public IActionResult Ajax_AssetCategoryConfig(Model_AssetCategory model)
|
||||
{
|
||||
AjaxResponse_AssetCategoryConfig responseData = new AjaxResponse_AssetCategoryConfig(model);
|
||||
String messageTitle = Localiser["caption.asset.categories"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
RefreshModel(model);
|
||||
|
||||
// Populate configuration data.
|
||||
PopulateAssetCategoryConfig(model, responseData);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
return Json(responseData);
|
||||
}
|
||||
private void PopulateAssetCategoryConfig(Model_AssetCategory model, AjaxResponse_AssetCategoryConfig responseData)
|
||||
{
|
||||
// Configuration.
|
||||
model.PopulateListConfig(responseData.Config);
|
||||
model.PopulateItemConfig(responseData.ConfigItemNew, null, Sbm.AssetType.Unknown);
|
||||
|
||||
// Reference data - select lists.
|
||||
foreach (TypeCodeDesc assetType in GetCodesOfType(Sbm.SystemCode.AssetType))
|
||||
responseData.AssetTypes.Add(assetType.Code, assetType.Desc);
|
||||
foreach (TypeCodeDesc incomeType in GetCodesOfType(Sbm.SystemCode.AssetIncomeType))
|
||||
responseData.IncomeTypes.Add(incomeType.Code, incomeType.Desc);
|
||||
|
||||
// Reference data - statuses.
|
||||
foreach (SaStatus status in SbmAssetCategory.ValidStatuses)
|
||||
{
|
||||
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
|
||||
if (status != SaStatus.Deleted)
|
||||
responseData.StatusesCreate.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
|
||||
}
|
||||
responseData.StatusCodeDefault = SacsSystem.GetStatusCode(SbmAssetCategory.DefaultStatus);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Asset Category List.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_AssetCategoryList : AjaxResponse_AssetCategoryConfig
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_AssetCategoryList(SbmModel_Portal model) : base(model) { }
|
||||
// View mode.
|
||||
public class ModeData
|
||||
{
|
||||
public bool? Search { get; set; }
|
||||
public bool? Maintain { get; set; }
|
||||
}
|
||||
public ModeData Mode { get; set; }
|
||||
// AssetCategory list.
|
||||
public List<AssetCategoryListData> AssetCategories { get; } = new List<AssetCategoryListData>();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Assets/AssetCategory/Ajax/GetList")]
|
||||
@@ -77,19 +162,21 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
RefreshModel(model);
|
||||
|
||||
// Reference data - statuses.
|
||||
foreach (SaStatus status in SbmAssetCategory.ValidStatuses)
|
||||
{
|
||||
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
|
||||
if (status != SaStatus.Deleted)
|
||||
responseData.StatusesCreate.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
|
||||
}
|
||||
responseData.StatusCodeDefault = SacsSystem.GetStatusCode(SbmAssetCategory.DefaultStatus);
|
||||
// Populate configuration data.
|
||||
PopulateAssetCategoryConfig(model, responseData);
|
||||
|
||||
// View mode.
|
||||
responseData.Mode = new AjaxResponse_AssetCategoryList.ModeData();
|
||||
Model_AssetCategory.ViewMode viewMode = model.GetFilterMode();
|
||||
if (viewMode == Model_AssetCategory.ViewMode.Maintain)
|
||||
responseData.Mode.Maintain = true;
|
||||
else
|
||||
responseData.Mode.Search = true;
|
||||
|
||||
// Item filter.
|
||||
SbmAssetCategory.Params prmAssetCategory = new SbmAssetCategory.Params();
|
||||
prmAssetCategory.Search = model.Filter.Search;
|
||||
prmAssetCategory.StatusCat = model.Filter.GetStatusCat();
|
||||
prmAssetCategory.StatusCat = model.GetFilterStatusCat();
|
||||
model.Paging.ItemTotal = (ulong)AssetMgr.GetAssetCategoryCount(prmAssetCategory);
|
||||
model.PopulatePagingTo(prmAssetCategory.ResultsPaging);
|
||||
|
||||
@@ -99,11 +186,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
ColumnDfn colCode = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.Code);
|
||||
ColumnDfn colDescBrief = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.DescBrief);
|
||||
ColumnDfn colAssetCount = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.AssetCount);
|
||||
ColumnDfn colNotes = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.Notes);
|
||||
ColumnDfn colStatus = AssetMgr.GetAssetCategoryColumnDfn(SbmAssetCategory.Column.Status);
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||
{
|
||||
colId, colType, colCode, colDescBrief,
|
||||
colAssetCount, colStatus
|
||||
colAssetCount, colNotes, colStatus
|
||||
};
|
||||
|
||||
// Query items.
|
||||
@@ -116,15 +204,21 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
AssetCategoryListData assetCategoryData = new AssetCategoryListData()
|
||||
{
|
||||
Id = values.GetLong(colId.DataName).ToString(),
|
||||
TypeDesc = Localiser.GetAssetTypeCaption(assetType),
|
||||
Code = values.GetString(colCode.DataName),
|
||||
DescBrief = values.GetString(colDescBrief.DataName),
|
||||
Caption = values.GetString(colDescBrief.DataName),
|
||||
TypeDesc = Localiser.GetAssetTypeCaption(assetType),
|
||||
StatusCode = values.GetString(colStatus.DataName),
|
||||
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
|
||||
};
|
||||
assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Type}", Internals.AssetTypeCodes.GetDescForType(assetType));
|
||||
assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Code}", assetCategoryData.Code);
|
||||
assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Caption}", assetCategoryData.Caption);
|
||||
assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Notes}", AssetMgr.GetAssetCategoryDataValue(colNotes, values).ToString());
|
||||
assetCategoryData.Field.Value.Add($"{Model_AssetCategory.ItemField.Status}", SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)));
|
||||
long assetCount = values.GetLong(colAssetCount.DataName);
|
||||
if (assetCount > 0)
|
||||
assetCategoryData.AssetCount = assetCount;
|
||||
// Cleanse item values.
|
||||
assetCategoryData.Field.Value.RemoveAll(item => StringUtil.IsBlank(item.Value));
|
||||
responseData.AssetCategories.Add(assetCategoryData);
|
||||
}
|
||||
}
|
||||
@@ -144,7 +238,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_AssetCategory(SbmModel_Portal model) : base(model) { }
|
||||
// AssetCategory details.
|
||||
// Configuration.
|
||||
public Model_AssetCategory.ItemConfigData Config { get; } = new Model_AssetCategory.ItemConfigData();
|
||||
// Asset Category details.
|
||||
public AssetCategoryItemData assetCategory { get; } = new AssetCategoryItemData();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
@@ -180,6 +276,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
model.PopulateItemConfig(responseData.Config, assetCategory);
|
||||
PopulateAssetCategoryResponseItemData(model, responseData.assetCategory, assetCategory);
|
||||
responseData.Success = true;
|
||||
}
|
||||
@@ -243,15 +340,16 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
assetCategory = AssetMgr.CreateAssetCategory(model.AssetCategory.AssetType);
|
||||
disposables.Add(assetCategory);
|
||||
}
|
||||
|
||||
// Populate item properties.
|
||||
if (model.AssetCategory.Code != null)
|
||||
assetCategory.Code = model.AssetCategory.Code;
|
||||
if (model.AssetCategory.DescBrief != null)
|
||||
assetCategory.DescBrief = model.AssetCategory.DescBrief;
|
||||
if (model.AssetCategory.Caption != null)
|
||||
assetCategory.DescBrief = model.AssetCategory.Caption;
|
||||
if (model.AssetCategory.StatusCode != null)
|
||||
assetCategory.Status = model.AssetCategory.GetStatus();
|
||||
assetCategory.Status = model.GetAssetCategoryStatus();
|
||||
if (model.AssetCategory.Notes != null)
|
||||
assetCategory.Notes = model.AssetCategory.Notes;
|
||||
|
||||
@@ -274,6 +372,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
model.PopulateItemConfig(responseData.Config, assetCategory);
|
||||
PopulateAssetCategoryResponseItemData(model, responseData.assetCategory, assetCategory);
|
||||
responseData.Success = true;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[Route("Assets/AssetCategory")]
|
||||
public IActionResult Index()
|
||||
public IActionResult Index(Model_AssetCategory model)
|
||||
{
|
||||
if (!ValidUserSession)
|
||||
AutoLoginUser();
|
||||
@@ -38,8 +38,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
return RedirectToAction("", "Security");
|
||||
}
|
||||
|
||||
// AssetCategory page.
|
||||
Model_AssetCategory model = new Model_AssetCategory(Localiser);
|
||||
// Asset Category page.
|
||||
RefreshModel(model);
|
||||
model.PopulateListConfig();
|
||||
model.Paging.PageNo = SessionData_Portal.Profile.Commodity.Filter.PageNo;
|
||||
model.Paging.PageLength = SessionData_Portal.Profile.Commodity.Filter.PageLength;
|
||||
return View("Views/Assets/AssetCategory/Index.cshtml", model);
|
||||
}
|
||||
|
||||
|
||||
+76
-71
@@ -108,7 +108,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
|
||||
public AjaxResponse_CommodityConfig(SbmModel_Portal model) : base(model) { }
|
||||
// Configuration.
|
||||
public Model_Commodity.ListConfigData Config { get; } = new Model_Commodity.ListConfigData();
|
||||
public Model_Commodity.ItemConfigData ConfigCmd { get; } = new Model_Commodity.ItemConfigData();
|
||||
public Model_Commodity.ItemConfigData ConfigItemNew { get; } = new Model_Commodity.ItemConfigData();
|
||||
// Reference data.
|
||||
public List<CodeDesc> CommodityTypes { get; } = new List<CodeDesc>();
|
||||
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
|
||||
@@ -139,7 +139,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
|
||||
{
|
||||
// Configuration.
|
||||
model.PopulateListConfig(responseData.Config);
|
||||
model.PopulateItemConfig(responseData.ConfigCmd, null, Sbm.CommodityType.Unknown);
|
||||
model.PopulateItemConfig(responseData.ConfigItemNew, null, Sbm.CommodityType.Unknown);
|
||||
|
||||
// Reference data - commodity types.
|
||||
foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType))
|
||||
@@ -189,12 +189,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
|
||||
|
||||
// View mode.
|
||||
responseData.Mode = new AjaxResponse_CommodityList.ModeData();
|
||||
Model_Commodity.CommodityViewMode viewMode = model.GetFilterMode();
|
||||
if (viewMode == Model_Commodity.CommodityViewMode.Maintain)
|
||||
Model_Commodity.ViewMode viewMode = model.GetFilterMode();
|
||||
if (viewMode == Model_Commodity.ViewMode.Maintain)
|
||||
responseData.Mode.Maintain = true;
|
||||
else if (viewMode == Model_Commodity.CommodityViewMode.StockControl)
|
||||
else if (viewMode == Model_Commodity.ViewMode.StockControl)
|
||||
responseData.Mode.StockControl = true;
|
||||
else if (viewMode == Model_Commodity.CommodityViewMode.StockTake)
|
||||
else if (viewMode == Model_Commodity.ViewMode.StockTake)
|
||||
responseData.Mode.StockTake = true;
|
||||
else
|
||||
responseData.Mode.Search = true;
|
||||
@@ -303,26 +303,29 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
|
||||
if (!ValidReferer) return Forbid();
|
||||
RefreshModel(model);
|
||||
|
||||
// Identify item.
|
||||
SysId commodityId = SysId.ToSysId(model.Commodity.Id);
|
||||
if (!SysId.IsValid(commodityId))
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
|
||||
|
||||
// Retrieve item.
|
||||
SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId);
|
||||
if (commodity == null)
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve commodity for Id: '{model.Commodity.Id}'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
|
||||
// Identify item.
|
||||
SysId commodityId = SysId.ToSysId(model.Commodity.Id);
|
||||
if (!SysId.IsValid(commodityId))
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
|
||||
|
||||
// Retrieve item.
|
||||
SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId);
|
||||
disposables.Add(commodity);
|
||||
if (commodity == null)
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve commodity for Id: '{model.Commodity.Id}'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
model.PopulateItemConfig(responseData.Config, commodity);
|
||||
PopulateCommodityResponseItemData(commodity, responseData.commodity);
|
||||
responseData.Success = true;
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
model.PopulateItemConfig(responseData.Config, commodity);
|
||||
PopulateCommodityResponseItemData(commodity, responseData.commodity);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
@@ -361,63 +364,65 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Commodities
|
||||
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
|
||||
}
|
||||
|
||||
// Retrieve existing item.
|
||||
SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId);
|
||||
if (commodity == null && SysId.IsValid(commodityId))
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve commodity for Id: '{model.Commodity.Id}'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
|
||||
// Create new item if required.
|
||||
if (commodity == null)
|
||||
{
|
||||
commodity = CommodityMgr.CreateCommodity(model.GetCommodityType(), model.Commodity.Code);
|
||||
// Retrieve existing item.
|
||||
SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId);
|
||||
disposables.Add(commodity);
|
||||
if (commodity == null && SysId.IsValid(commodityId))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve commodity for Id: '{model.Commodity.Id}'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
|
||||
// Create new item if required.
|
||||
if (commodity == null)
|
||||
{
|
||||
commodity = CommodityMgr.CreateCommodity(model.GetCommodityType(), model.Commodity.Code);
|
||||
disposables.Add(commodity);
|
||||
}
|
||||
|
||||
// Populate item properties.
|
||||
if (model.Commodity.Type != null)
|
||||
commodity.CommodityType = model.GetCommodityType();
|
||||
if (model.Commodity.Code != null)
|
||||
commodity.Code = model.Commodity.Code;
|
||||
}
|
||||
if (model.Commodity.DescBrief != null)
|
||||
commodity.DescBrief = model.Commodity.DescBrief;
|
||||
// Common properties.
|
||||
if (model.Commodity.Notes != null)
|
||||
commodity.Notes = model.Commodity.Notes;
|
||||
if (model.Commodity.StatusCode != null)
|
||||
commodity.Status = model.GetCommodityStatus();
|
||||
|
||||
// Populate item properties.
|
||||
if (model.Commodity.Type != null)
|
||||
commodity.CommodityType = model.GetCommodityType();
|
||||
if (model.Commodity.Code != null)
|
||||
commodity.Code = model.Commodity.Code;
|
||||
if (model.Commodity.DescBrief != null)
|
||||
commodity.DescBrief = model.Commodity.DescBrief;
|
||||
// Common properties.
|
||||
if (model.Commodity.Notes != null)
|
||||
commodity.Notes = model.Commodity.Notes;
|
||||
if (model.Commodity.StatusCode != null)
|
||||
commodity.Status = model.GetCommodityStatus();
|
||||
|
||||
// Store item.
|
||||
if (!SysId.IsValid(commodity.Id))
|
||||
{
|
||||
if (!CommodityMgr.InsertCommodity(commodity, DbUpdateInfo))
|
||||
// Store item.
|
||||
if (!SysId.IsValid(commodity.Id))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to insert commodity: {CommodityMgr.ErrorStateMessage}");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"]));
|
||||
if (!CommodityMgr.InsertCommodity(commodity, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to insert commodity: {CommodityMgr.ErrorStateMessage}");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"]));
|
||||
}
|
||||
responseData.SetNotification(messageTitle, Localiser["msg.item.created"]);
|
||||
}
|
||||
responseData.SetNotification(messageTitle, Localiser["msg.item.created"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CommodityMgr.UpdateCommodity(commodity, DbUpdateInfo))
|
||||
else
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to update commodity [Id:{SysId.ToLong(commodity.Id)}]: {CommodityMgr.ErrorStateMessage}");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"]));
|
||||
if (!CommodityMgr.UpdateCommodity(commodity, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to update commodity [Id:{SysId.ToLong(commodity.Id)}]: {CommodityMgr.ErrorStateMessage}");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"]));
|
||||
}
|
||||
responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]);
|
||||
}
|
||||
responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]);
|
||||
UpdateAssociatedData(commodity);
|
||||
|
||||
// Construct response.
|
||||
model.PopulateItemConfig(responseData.Config, commodity);
|
||||
PopulateCommodityResponseItemData(commodity, responseData.commodity);
|
||||
responseData.Success = true;
|
||||
}
|
||||
UpdateAssociatedData(commodity);
|
||||
|
||||
// Construct response.
|
||||
model.PopulateItemConfig(responseData.Config, commodity);
|
||||
PopulateCommodityResponseItemData(commodity, responseData.commodity);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -199,12 +199,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
||||
|
||||
// View mode.
|
||||
responseData.Mode = new AjaxResponse_AssociationList.ModeData();
|
||||
Model_Association.AssociationViewMode viewMode = model.GetFilterMode();
|
||||
if (viewMode == Model_Association.AssociationViewMode.Maintain)
|
||||
Model_Association.ViewMode viewMode = model.GetFilterMode();
|
||||
if (viewMode == Model_Association.ViewMode.Maintain)
|
||||
responseData.Mode.Maintain = true;
|
||||
else if (viewMode == Model_Association.AssociationViewMode.Relationships)
|
||||
else if (viewMode == Model_Association.ViewMode.Relationships)
|
||||
responseData.Mode.Relationships = true;
|
||||
else if (viewMode == Model_Association.AssociationViewMode.PriceSet)
|
||||
else if (viewMode == Model_Association.ViewMode.PriceSet)
|
||||
responseData.Mode.PriceSet = true;
|
||||
else
|
||||
responseData.Mode.Search = true;
|
||||
|
||||
@@ -205,8 +205,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
||||
|
||||
// View mode.
|
||||
responseData.Mode = new AjaxResponse_ContactList.ModeData();
|
||||
Model_Contact.ContactViewMode viewMode = model.GetFilterMode();
|
||||
if (viewMode == Model_Contact.ContactViewMode.Maintain)
|
||||
Model_Contact.ViewMode viewMode = model.GetFilterMode();
|
||||
if (viewMode == Model_Contact.ViewMode.Maintain)
|
||||
responseData.Mode.Maintain = true;
|
||||
else
|
||||
responseData.Mode.Search = true;
|
||||
@@ -215,7 +215,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Contacts
|
||||
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
|
||||
prmAffiliate.Search = model.Filter.Search;
|
||||
prmAffiliate.AffiliateType = model.GetFilterContactType();
|
||||
if (prmAffiliate.AffiliateType == Sbm.AffiliateType.Any && viewMode == Model_Contact.ContactViewMode.Search)
|
||||
if (prmAffiliate.AffiliateType == Sbm.AffiliateType.Any && viewMode == Model_Contact.ViewMode.Search)
|
||||
prmAffiliate.AffiliateType = Sbm.AffiliateType.AnyContact;
|
||||
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.NotDeleted;
|
||||
prmAffiliate.SortColumns.Add(AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Name));
|
||||
|
||||
@@ -28,6 +28,16 @@ using DocumentFormat.OpenXml.EMMA;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Models;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
|
||||
using Sarand.Net.Standard.Base.CodeTypes;
|
||||
using Sarand.Net.Standard.Base.Diary;
|
||||
using Sarand.Net.Standard.Base.Email;
|
||||
using Sarand.Net.Standard.Base.Interfaces;
|
||||
using Sarand.Net.Standard.Base.ItemData;
|
||||
using Sarand.Net.Standard.Base.ItemDocs;
|
||||
using Sarand.Net.Standard.Base.ItemOptions;
|
||||
using Sarand.Net.Standard.Base.ReferenceData;
|
||||
using Sarand.Net.Standard.Base.UpdateLog;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
{
|
||||
@@ -38,6 +48,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private SbmInternals internals;
|
||||
private SbmSysParamCache sysParamCache = null;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -49,12 +60,44 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (sysParamCache != null) sysParamCache.Dispose();
|
||||
sysParamCache = null;
|
||||
if (internals != null) internals.Dispose(); internals = null;
|
||||
if (sysParamCache != null) sysParamCache.Dispose(); sysParamCache = null;
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public SbmInternals Internals { get { if (internals == null && UserContext_Core != null) { internals = new SbmInternals(UserContext_Core); } return internals; } }
|
||||
// Managers.
|
||||
public SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } }
|
||||
public SbmAssetMgr AssetMgr { get { return Internals.AssetMgr; } }
|
||||
public SbmCommodityMgr CommodityMgr { get { return Internals.CommodityMgr; } }
|
||||
public SbmPriceMgr PriceMgr { get { return Internals.PriceMgr; } }
|
||||
public SbmTransactionMgr TransactionMgr { get { return Internals.TransactionMgr; } }
|
||||
public SbmStockMgr StockMgr { get { return Internals.StockMgr; } }
|
||||
public SbmProcessMgr ProcessMgr { get { return Internals.ProcessMgr; } }
|
||||
public SbmDataItemMgr DataItemMgr { get { return Internals.DataItemMgr; } }
|
||||
// Consoles.
|
||||
public SbmSessionConsole SessionConsole { get { return Internals.SessionConsole; } }
|
||||
public SaDiaryConsole DiaryConsole { get { return Internals.DiaryConsole; } }
|
||||
public SaSecurityConsole SecurityConsole { get { return Internals.SecurityConsole; } }
|
||||
public SaCodeTypeConsole CodeTypeConsole { get { return Internals.CodeTypeConsole; } }
|
||||
public SaReferenceDataConsole ReferenceDataConsole { get { return Internals.ReferenceDataConsole; } }
|
||||
public SaUpdateLogConsole UpdateLogConsole { get { return Internals.UpdateLogConsole; } }
|
||||
public SaInterfaceConsole InterfaceConsole { get { return Internals.InterfaceConsole; } }
|
||||
public SaItemDocConsole ItemDocConsole { get { return Internals.ItemDocConsole; } }
|
||||
public SaItemOptionConsole ItemOptionConsole { get { return Internals.ItemOptionConsole; } }
|
||||
public SaItemDataConsole ItemDataConsole { get { return Internals.ItemDataConsole; } }
|
||||
// Configurations.
|
||||
public SbmStockControlConfig StockControlConfig { get { return Internals.StockControlConfig; } }
|
||||
public SbmRequirementCostingConfig RequirementCostingConfig { get { return Internals.RequirementCostingConfig; } }
|
||||
// System codes.
|
||||
public List<TypeCodeDesc> GetCodesOfType(Sbm.SystemCode systemCode) { return Internals.GetSystemCodes(systemCode); }
|
||||
// Email.
|
||||
public SaEmailConfig EmailConfig { get { return Internals.EmailConfig; } }
|
||||
public SbmEmailConsole EmailConsole { get { return Internals.EmailConsole; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Session data.
|
||||
|
||||
@@ -84,24 +127,26 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
/// <para>- Open user session - store details against Sesion Data.</para>
|
||||
/// <para>- Set 'Keep logged in' cookie if required.</para>
|
||||
/// </summary>
|
||||
protected bool SignUserIn(SbmInternals internalsForUser, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage)
|
||||
protected bool SignUserIn(SbmSessionData_Portal sessionDataForUser, SbmInternals internalsForUser, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage)
|
||||
{
|
||||
string errorPrefix = $"Unable to sign account in";
|
||||
string errorSuffix = $"Context: {sessionDataForUser.RepositoryContext}. Email: {sessionDataForUser.UserEmailAddress}.";
|
||||
// Validate Security Item and Affiliate, just in case - should have been done before arriving here!
|
||||
if (securityItemUser == null)
|
||||
{
|
||||
SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - null security item.");
|
||||
SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - null security item. {errorSuffix}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
if (affiliateUser == null)
|
||||
{
|
||||
SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - null affiliate.");
|
||||
SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - null affiliate. {errorSuffix}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
if (!affiliateUser.IsStatusCurrent)
|
||||
{
|
||||
SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - affiliate is not active. Email: {securityItemUser.EmailAddress}");
|
||||
SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - affiliate is not active. {errorSuffix}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
@@ -109,54 +154,64 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
// Organisation.
|
||||
if (associationOrganisation == null)
|
||||
{
|
||||
SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - null organisation association.");
|
||||
SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - null organisation association. {errorSuffix}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
if (associationOrganisation.AssociationType != Sbm.AssociationType.Internal)
|
||||
{
|
||||
SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - organisation association is not type 'Internal'.");
|
||||
SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - organisation association is not type 'Internal'. {errorSuffix}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
if (affiliateOrganisation == null)
|
||||
{
|
||||
SaLogger.Error($"{SysUtil.Fn} Unable to sign account in - null organisation affiliate.");
|
||||
SaLogger.Error($"{SysUtil.Fn} {errorPrefix} - null organisation affiliate. {errorSuffix}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify Organisation is supervised by User.
|
||||
if (!internalsForUser.AccountMgr.IsAffiliateSupervisedBy(affiliateOrganisation.Id, affiliateUser.Id))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} {errorPrefix} - Organisation is not supervised by user. {errorSuffix}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
|
||||
// Configure security profile.
|
||||
sessionDataForUser.SecurityProfile_Core.RefreshProfile(internalsForUser.SessionConsole, internalsForUser.SecurityConsole, securityItemUser.Id, internalsForUser.SecurityConsole.GetRegisteredRights());
|
||||
|
||||
// 'Keep logged in' can be switched off by the application configuration.
|
||||
keepLoggedIn = App.AppConfig.Security.SignIn.KeepLoggedIn.Allowed && keepLoggedIn;
|
||||
|
||||
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
|
||||
// Log user in.
|
||||
securityItemUser.LastLogin = DateTime.Now;
|
||||
securityItemUser.InvalidLoginCount = 0;
|
||||
securityItemUser.LastInvalidLoginAt = DateTime.MinValue;
|
||||
if (!internalsForUser.SecurityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
||||
{
|
||||
// Log user in.
|
||||
securityItemUser.LastLogin = DateTime.Now;
|
||||
securityItemUser.InvalidLoginCount = 0;
|
||||
securityItemUser.LastInvalidLoginAt = DateTime.MinValue;
|
||||
if (!internalsForUser.SecurityConsole.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to update security item for {securityItemUser.EmailAddress}: {internalsForUser.SecurityConsole.ErrorStateMessage}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to update security item for {securityItemUser.EmailAddress}: {internalsForUser.SecurityConsole.ErrorStateMessage}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update affiliate.
|
||||
affiliateUser.KeepLoggedIn_Portal = keepLoggedIn;
|
||||
if (!internalsForUser.AccountMgr.UpdateAffiliate(affiliateUser, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to update affiliate for {securityItemUser.EmailAddress}: {internalsForUser.AccountMgr.ErrorStateMessage}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
SaLogger.Info($"{SysUtil.Fn} User session opened for {securityItemUser.EmailAddress}", true);
|
||||
// Update affiliate.
|
||||
affiliateUser.KeepLoggedIn_Portal = keepLoggedIn;
|
||||
if (!internalsForUser.AccountMgr.UpdateAffiliate(affiliateUser, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to update affiliate for {securityItemUser.EmailAddress}: {internalsForUser.AccountMgr.ErrorStateMessage}");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
SaLogger.Info($"{SysUtil.Fn} User session opened for {securityItemUser.EmailAddress}", true);
|
||||
|
||||
// Create session.
|
||||
OpenUserSession(internalsForUser.SessionContext, repositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
|
||||
|
||||
// Configure security profile.
|
||||
SessionData_Portal.SecurityProfile_Core.RefreshProfile(SessionConsole, internalsForUser.SecurityConsole, securityItemUser.Id, internalsForUser.SecurityConsole.GetRegisteredRights());
|
||||
// Create session.
|
||||
if (!OpenUserSession(sessionDataForUser))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to open user session. Repository context: {sessionDataForUser.RepositoryContext}. Email: {securityItemUser.EmailAddress}.");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the 'Keep Logged In' cookie if requested.
|
||||
@@ -168,7 +223,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Populate the user's profile contact details to the session.</summary>
|
||||
protected bool RefreshSessionProfileContact(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
protected bool RefreshSessionData(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
{
|
||||
SbmSessionData_Portal sessionData = SessionData_Portal;
|
||||
SysId affiliateIdUser = sessionData?.User?.AffiliateId ?? null;
|
||||
@@ -177,24 +232,30 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
if (!affiliateIdUser.Equals(affiliateUser.Id)) return false;
|
||||
if (!SysId.IsValid(affiliateOrganisation?.Id ?? null)) return false;
|
||||
|
||||
sessionData.RefreshUser(securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
|
||||
sessionData.Refresh(securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Start a new user session on sign-in.</summary>
|
||||
protected bool OpenUserSession(SbmSessionContext sessionContext, String repositoryContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
protected bool OpenUserSession(SbmSessionData_Portal sessionDataForUser)
|
||||
{
|
||||
// Validate user properties.
|
||||
if (!SysId.IsValid(affiliateUser.Id)) return false;
|
||||
if (StringUtil.IsEmpty(securityItemUser.EmailAddress)) return false;
|
||||
if (!SysId.IsValid(sessionDataForUser.UserAffiliateId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (StringUtil.IsBlank(sessionDataForUser.UserEmailAddress))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close previous session.
|
||||
CloseUserSession();
|
||||
|
||||
// Open session.
|
||||
return SetSessionData(new SbmSessionData_Portal(sessionContext, repositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation));
|
||||
return SetSessionData(sessionDataForUser);
|
||||
}
|
||||
protected void CloseUserSession()
|
||||
{
|
||||
@@ -267,8 +328,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
if (sessionContext != null)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
using (SbmInternals internalsForUser = new SbmInternals(userContext))
|
||||
SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContext, keepLoggedInParams.RepositoryContext, null, null, null, null);
|
||||
using (SbmInternals internalsForUser = new SbmInternals(sessionDataForUser))
|
||||
{
|
||||
using (SaSecurityItem securityItemUser = internalsForUser.SecurityConsole.GetUserByEmail(keepLoggedInParams.EmailAddress))
|
||||
using (SbmAffiliate affiliateUser = internalsForUser.AccountMgr.GetAffiliateById(keepLoggedInParams.AffiliateIdUser))
|
||||
@@ -281,10 +342,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers
|
||||
{
|
||||
if (affiliateUser.IsStatusCurrent)
|
||||
{
|
||||
List<SysIdString> supervisedOrganisations = internalsForUser.AccountMgr.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
// Bring the Session Data up to date with the session properties.
|
||||
sessionDataForUser.Refresh(securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation);
|
||||
String errorMessage = "";
|
||||
if (SignUserIn(internalsForUser, keepLoggedInParams.RepositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage))
|
||||
if (SignUserIn(sessionDataForUser, internalsForUser, securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation, true, ref errorMessage))
|
||||
{
|
||||
// User auto-login successful.
|
||||
SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -93,24 +93,24 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
{
|
||||
if (sessionContext == null) return false;
|
||||
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContext, model.RepositoryContext, null, null, null, null);
|
||||
ISacsDatabase busMgrDatabase = App.GetBusMgrDatabase(sessionContext);
|
||||
if (busMgrDatabase == null) return false;
|
||||
|
||||
using (DisposableCollection<IDisposable> disposables = new DisposableCollection<IDisposable>())
|
||||
{
|
||||
SbmInternals internalsForUser = new SbmInternals(userContext);
|
||||
SbmInternals internalsForUser = new SbmInternals(sessionDataForUser);
|
||||
disposables.Add(internalsForUser);
|
||||
|
||||
// User's security item.
|
||||
SaSecurityItem securityItemUser = GetSecurityItemForSignin(userContext, internalsForUser.SecurityConsole, model);
|
||||
SaSecurityItem securityItemUser = GetSecurityItemForSignin(sessionDataForUser, internalsForUser.SecurityConsole, model);
|
||||
disposables.Add(securityItemUser);
|
||||
if (securityItemUser == null)
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve Security Item. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}.");
|
||||
return false;
|
||||
}
|
||||
if (!internalsForUser.SecurityConsole.PasswordMatches(securityItemUser, model.Password, userContext.DbUpdateInfo))
|
||||
if (!internalsForUser.SecurityConsole.PasswordMatches(securityItemUser, model.Password, sessionDataForUser.DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Supplied password doesn't match Security Item. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}.");
|
||||
return false;
|
||||
@@ -125,17 +125,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
return false;
|
||||
}
|
||||
|
||||
// User's supervised organisations.
|
||||
List<SysIdString> supervisedOrganisations = internalsForUser.AccountMgr.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
if (supervisedOrganisations.IsEmpty())
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} User has no supervised organisations. Database: {busMgrDatabase.DatabaseName}. Email: {model.EmailAddress}.");
|
||||
return false;
|
||||
}
|
||||
userContext.RefreshUser(securityItemUser, affiliateUser, supervisedOrganisations);
|
||||
|
||||
// User's organisation association.
|
||||
SbmAssociation associationOrganisation = GetOrganisationAssociationForSignIn(internalsForUser.AccountMgr, model, userContext);
|
||||
SbmAssociation associationOrganisation = GetOrganisationAssociationForSignIn(internalsForUser.AccountMgr, model, sessionDataForUser);
|
||||
disposables.Add(associationOrganisation);
|
||||
if (associationOrganisation == null)
|
||||
{
|
||||
@@ -152,15 +143,18 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
return false;
|
||||
}
|
||||
|
||||
// Populate User properties to the Session Data.
|
||||
sessionDataForUser.Refresh(securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation);
|
||||
|
||||
// Initialise user session.
|
||||
if (SignUserIn(internalsForUser, model.RepositoryContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage))
|
||||
if (SignUserIn(sessionDataForUser, internalsForUser, securityItemUser, affiliateUser, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SaSecurityItem GetSecurityItemForSignin(SbmUserContext_Web userContext, SaSecurityConsole securityConsoleForUser, Model_Security model)
|
||||
private SaSecurityItem GetSecurityItemForSignin(ISbmUserContext userContext, SaSecurityConsole securityConsoleForUser, Model_Security model)
|
||||
{
|
||||
// Retrieve security item by email address.
|
||||
SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress);
|
||||
@@ -216,13 +210,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
/// <summary>
|
||||
/// Identify the organisation for the user to login to - either last selected (via SysParam) or first in list.
|
||||
/// </summary>
|
||||
private SbmAssociation GetOrganisationAssociationForSignIn(SbmAccountMgr accountMgrForUser, Model_Security model, SbmUserContext userContext)
|
||||
private SbmAssociation GetOrganisationAssociationForSignIn(SbmAccountMgr accountMgrForUser, Model_Security model, ISbmUserOrganisationContext userContext)
|
||||
{
|
||||
// Previously selected organisation is stored in user params (SysParam table).
|
||||
SbmSysParamCache sysParamCache = new SbmSysParamCache(userContext, userContext.UserAffiliateId);
|
||||
SysId affiliateIdOrganisation = SysId.ToSysId(sysParamCache.GetUserParamValue(SbmSysParamCache.ParamName_SelectedCompany));
|
||||
SbmAssociation associationOrganisation = null;
|
||||
foreach (SysIdString supervisedOrganisation in userContext.SupervisedOrganisations)
|
||||
List<SysIdString> supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(userContext.UserAffiliateId);
|
||||
foreach (SysIdString supervisedOrganisation in supervisedOrganisations)
|
||||
{
|
||||
SbmAssociation associationOrganisationCandidate = accountMgrForUser.GetAssociationByOwnerTypeTarget(supervisedOrganisation.Id, Sbm.AssociationType.Internal, supervisedOrganisation.Id);
|
||||
if (associationOrganisationCandidate == null)
|
||||
@@ -374,10 +369,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
// Validate referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
|
||||
// If user is logged in, session Consoles and Managers can be used.
|
||||
// If 'Request Password' parameters are specified, Consoles and Managers must be associated with the specific database for the user.
|
||||
SbmSessionContext sessionContextForUser = null;
|
||||
SbmUserContext_Web userContextForUser = null;
|
||||
// If user is logged in, session Internals can be used.
|
||||
// If 'Request Password' parameters are specified, Internals must be associated with the specific context for the user.
|
||||
SbmInternals internalsForUser = null;
|
||||
|
||||
// If 'Request Password' encrypted params (from email link) are present,
|
||||
// Session is not required and password can be set directly against the user.
|
||||
@@ -389,29 +383,27 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
if (storePasswordParams.IsValid())
|
||||
{
|
||||
// Instance Repository configured on Control database identified by Context.
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(storePasswordParams.RepositoryContext);
|
||||
if (sessionContext != null)
|
||||
SbmSessionContext sessionContextForUser = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(storePasswordParams.RepositoryContext);
|
||||
if (sessionContextForUser != null)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
using (SbmInternals internalsForUser = new SbmInternals(userContext))
|
||||
// Consoles and Managers must be associated with the specific context for the User storing the password.
|
||||
SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContextForUser, storePasswordParams.RepositoryContext, null, null, null, null);
|
||||
internalsForUser = new SbmInternals(sessionDataForUser);
|
||||
// Retrieve user details and validate email address.
|
||||
securityItemUser = internalsForUser.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, storePasswordParams.SecurityItemId);
|
||||
affiliateUser = internalsForUser.AccountMgr.GetAffiliateById(storePasswordParams.AffiliateId);
|
||||
if (storePasswordParams.IsValid(securityItemUser, affiliateUser))
|
||||
{
|
||||
// Retrieve user details and validate email address.
|
||||
securityItemUser = internalsForUser.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, storePasswordParams.SecurityItemId);
|
||||
affiliateUser = internalsForUser.AccountMgr.GetAffiliateById(storePasswordParams.AffiliateId);
|
||||
if (storePasswordParams.IsValid(securityItemUser, affiliateUser))
|
||||
{
|
||||
sessionContextForUser = sessionContext;
|
||||
userContextForUser = userContext;
|
||||
validRequestPasswordParams = true;
|
||||
validSessionRequired = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} 'Request Password' parameters supplied but invalid. Email: {storePasswordParams.EmailAddress}. SecurityItemId: {SysId.ToString(storePasswordParams.SecurityItemId)}. AffiliateId: {SysId.ToString(storePasswordParams.AffiliateId)}.");
|
||||
if (securityItemUser != null) securityItemUser.Dispose(); securityItemUser = null;
|
||||
if (affiliateUser != null) affiliateUser.Dispose(); affiliateUser = null;
|
||||
}
|
||||
sessionDataForUser.Refresh(securityItemUser, affiliateUser, null, null);
|
||||
validRequestPasswordParams = true;
|
||||
validSessionRequired = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} 'Request Password' parameters supplied but invalid. Email: {storePasswordParams.EmailAddress}. SecurityItemId: {SysId.ToString(storePasswordParams.SecurityItemId)}. AffiliateId: {SysId.ToString(storePasswordParams.AffiliateId)}.");
|
||||
if (securityItemUser != null) securityItemUser.Dispose(); securityItemUser = null;
|
||||
if (affiliateUser != null) affiliateUser.Dispose(); affiliateUser = null;
|
||||
if (internalsForUser != null) internalsForUser.Dispose(); internalsForUser = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -420,20 +412,24 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
if (validSessionRequired && (securityItemUser == null || affiliateUser == null) && !ValidUserSession)
|
||||
return Json(responseData.SetSessionExpired(messageTitle, Localiser["security.msg.warn.sessionExpired"]));
|
||||
|
||||
// User specific Consoles and Managers if User Context specified.
|
||||
using (SaSecurityConsole securityConsoleForUser = userContextForUser != null ? App.CreateSecurityConsole(userContextForUser) : null)
|
||||
using (SbmAccountMgr accountMgrForUser = userContextForUser != null ? App.System.CreateAccountMgr(userContextForUser) : null)
|
||||
// User specific Internals if Request Password params supplied, otherwise use Session Internals for current User Session.
|
||||
SbmInternals internalsForStorePassword = internalsForUser ?? Internals;
|
||||
|
||||
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
|
||||
{
|
||||
SaSecurityConsole securityConsole = (securityConsoleForUser ?? SecurityConsole);
|
||||
SbmAccountMgr accountMgr = (accountMgrForUser ?? AccountMgr);
|
||||
disposables.Add(internalsForUser);
|
||||
disposables.Add(securityItemUser);
|
||||
disposables.Add(affiliateUser);
|
||||
|
||||
// Retrieve user details if not previously populated.
|
||||
if (securityItemUser == null && SessionData_Portal != null)
|
||||
securityItemUser = (securityConsole.GetSecurityItemById(SaSecurity.ItemType.User, SessionData_Portal.User.SecurityItemId));
|
||||
securityItemUser = internalsForStorePassword.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, SessionData_Portal.User.SecurityItemId);
|
||||
disposables.Add(securityItemUser);
|
||||
if (securityItemUser == null)
|
||||
return Json(responseData.SetControlError(nameof(model.Password), "System error - failed to retrieve security item details."));
|
||||
if (affiliateUser == null && SessionData_Portal != null)
|
||||
affiliateUser = accountMgr.GetAffiliateById(SessionData_Portal.User.AffiliateId);
|
||||
affiliateUser = internalsForStorePassword.AccountMgr.GetAffiliateById(SessionData_Portal.User.AffiliateId);
|
||||
disposables.Add(affiliateUser);
|
||||
if (affiliateUser == null)
|
||||
return Json(responseData.SetControlError(nameof(model.Password), "System error - failed to retrieve affiliate details."));
|
||||
|
||||
@@ -447,7 +443,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
|
||||
// Store password.
|
||||
// NB Do not use Microsoft.AspNetCore.Identity.PasswordHasher.HashPassword() while legacy (C++) desktop application still in use.
|
||||
securityConsole.SetPassword(securityItemUser, model.Password);
|
||||
internalsForStorePassword.SecurityConsole.SetPassword(securityItemUser, model.Password);
|
||||
securityItemUser.PasswordChangedAt = DateTime.Now;
|
||||
// Remove new password from history if present.
|
||||
for (int passwordHistoryIdx = 0; passwordHistoryIdx < securityItemUser.PasswordHistory.Count; passwordHistoryIdx++)
|
||||
@@ -465,21 +461,14 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
securityItemUser.PasswordHistory.Add(oldPasswordHashed);
|
||||
while (securityItemUser.PasswordHistory.Count > 10)
|
||||
securityItemUser.PasswordHistory.RemoveAt(securityItemUser.PasswordHistory.Count - 1);
|
||||
if (!securityConsole.UpdateSecurityItem(securityItemUser, userContextForUser?.DbUpdateInfo ?? DbUpdateInfo))
|
||||
if (!internalsForStorePassword.SecurityConsole.UpdateSecurityItem(securityItemUser, internalsForStorePassword.DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to change password for {securityItemUser.EmailAddress}: {securityConsole.ErrorStateMessage}");
|
||||
SaLogger.Warn($"{SysUtil.Fn} Failed to change password for {securityItemUser.EmailAddress}: {internalsForStorePassword.SecurityConsole.ErrorStateMessage}");
|
||||
return Json(responseData.SetControlError(nameof(model.Password), Localiser["security.msg.change.password.failed"]));
|
||||
}
|
||||
SaLogger.Info($"{SysUtil.Fn} Password changed for {securityItemUser.EmailAddress}.", true);
|
||||
}
|
||||
|
||||
// Cleanup. NB The Security Item and/or Affiliate aren't disposed when the method
|
||||
// returns above but these objects shouldn't be carrying any disposable resources.
|
||||
if (securityItemUser != null) securityItemUser.Dispose(); securityItemUser = null;
|
||||
if (affiliateUser != null) affiliateUser.Dispose(); affiliateUser = null;
|
||||
sessionContextForUser = null;
|
||||
userContextForUser = null;
|
||||
|
||||
// Construct response.
|
||||
responseData.Success = true;
|
||||
if (validRequestPasswordParams)
|
||||
@@ -517,10 +506,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Portal.GetControlSessionContextByRepositoryContext(model.RepositoryContext);
|
||||
if (sessionContext != null)
|
||||
{
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContext, model.RepositoryContext, null, null, null, null);
|
||||
|
||||
// Get user security item and affiliate.
|
||||
using (SbmInternals internalsForUser = new SbmInternals(userContext))
|
||||
using (SbmInternals internalsForUser = new SbmInternals(sessionDataForUser))
|
||||
using (SaSecurityItem securityItemUser = internalsForUser.SecurityConsole.GetUserByEmail(model.EmailAddress))
|
||||
{
|
||||
if (securityItemUser != null)
|
||||
@@ -529,16 +518,17 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
{
|
||||
if (affiliateUser != null)
|
||||
{
|
||||
sessionDataForUser.Refresh(securityItemUser, affiliateUser, null, null);
|
||||
if (affiliateUser.Status == SaStatus.Current || affiliateUser.IsStatusActive)
|
||||
{
|
||||
SbmEmailConsole emailConsole = App.CreateEmailConsole(userContext);
|
||||
SbmEmailConsole emailConsole = internalsForUser.EmailConsole;
|
||||
|
||||
// Send password request email.
|
||||
SaEmailData emailData = new SaEmailData();
|
||||
emailData.Config = App.EmailConfig;
|
||||
emailData.AddressesTo.Add(model.EmailAddress);
|
||||
emailData.Subject = Localiser["security.caption.request.password"];
|
||||
PopulateRequestPasswordEmailBody(emailConsole, userContext, emailData, securityItemUser, affiliateUser);
|
||||
PopulateRequestPasswordEmailBody(emailConsole, sessionDataForUser, emailData, securityItemUser, affiliateUser);
|
||||
if (emailConsole.SendEmail(emailData))
|
||||
SaLogger.Info($"{SysUtil.Fn} Password request email sent to {model.EmailAddress}.", true);
|
||||
else SaLogger.Warn($"{SysUtil.Fn} Failed to send password request email to {model.EmailAddress}.");
|
||||
|
||||
@@ -17,6 +17,7 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Sarand.BusinessMgr.Web.Portal.Helpers;
|
||||
using Sarand.BusinessMgr.Web.Portal.App;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
{
|
||||
@@ -81,12 +82,13 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Security
|
||||
if (sessionContext != null)
|
||||
{
|
||||
// Consoles and Managers must be associated with the specific context.
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
using (SbmInternals internalsForUser = new SbmInternals(userContext))
|
||||
SbmSessionData_Portal sessionDataForUser = new SbmSessionData_Portal(sessionContext, changePasswordParams.RepositoryContext, null, null, null, null);
|
||||
using (SbmInternals internalsForUser = new SbmInternals(sessionDataForUser))
|
||||
{
|
||||
using (SaSecurityItem securityItemUser = internalsForUser.SecurityConsole.GetUserByEmail(changePasswordParams.EmailAddress))
|
||||
using (SbmAffiliate affiliateUser = internalsForUser.AccountMgr.GetAffiliateById(changePasswordParams.AffiliateId))
|
||||
{
|
||||
sessionDataForUser.Refresh(securityItemUser, affiliateUser, null, null);
|
||||
if (securityItemUser != null && affiliateUser != null)
|
||||
{
|
||||
if (securityItemUser.Id.Equals(changePasswordParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id))
|
||||
|
||||
+2
-2
@@ -96,7 +96,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
|
||||
public AjaxResponse_TransactionConfig(SbmModel_Portal model) : base(model) { }
|
||||
// Configuration.
|
||||
public Model_Transaction.ListConfigData Config { get; } = new Model_Transaction.ListConfigData();
|
||||
public Model_Transaction.ItemConfigData ConfigCmd { get; } = new Model_Transaction.ItemConfigData();
|
||||
public Model_Transaction.ItemConfigData ConfigItemNew { get; } = new Model_Transaction.ItemConfigData();
|
||||
// Reference data.
|
||||
public List<CodeDesc> TransactionTypes { get; } = new List<CodeDesc>();
|
||||
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
|
||||
@@ -127,7 +127,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Transactions
|
||||
{
|
||||
// Configuration.
|
||||
model.PopulateListConfig(responseData.Config);
|
||||
model.PopulateItemConfig(responseData.ConfigCmd, null, Sbm.TransactionType.Unknown);
|
||||
model.PopulateItemConfig(responseData.ConfigItemNew, null, Sbm.TransactionType.Unknown);
|
||||
|
||||
// Reference data - transaction types.
|
||||
foreach (TypeCodeDesc transactionType in GetCodesOfType(Sbm.SystemCode.TransactionType))
|
||||
|
||||
+10
-10
@@ -3,7 +3,7 @@ using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models.Assets;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models.Vehicles;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
@@ -13,7 +13,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Vehicles
|
||||
{
|
||||
//=======================================================================
|
||||
partial class VehicleClassController
|
||||
@@ -71,9 +71,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Assets/VehicleClass/Ajax/GetList")]
|
||||
[Route("Assets/VehicleClass/Ajax/GetVehicleClasses")]
|
||||
[Route("Assets/VehicleClass/Ajax/GetVehicleClassList")]
|
||||
[Route("Vehicles/VehicleClass/Ajax/GetList")]
|
||||
[Route("Vehicles/VehicleClass/Ajax/GetVehicleClasses")]
|
||||
[Route("Vehicles/VehicleClass/Ajax/GetVehicleClassList")]
|
||||
public IActionResult Ajax_GetVehicleClassList(Model_VehicleClass model)
|
||||
{
|
||||
String messageTitle = Localiser["caption.vehicle.classes"];
|
||||
@@ -96,7 +96,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
// Item filter.
|
||||
SbmVehicleClass.Params prmVehicleClass = new SbmVehicleClass.Params();
|
||||
prmVehicleClass.Search = model.Filter.Search;
|
||||
prmVehicleClass.StatusCat = model.Filter.GetStatusCat();
|
||||
prmVehicleClass.StatusCat = model.GetFilterStatusCat();
|
||||
model.Paging.ItemTotal = (ulong)AssetMgr.GetVehicleClassCount(prmVehicleClass);
|
||||
model.PopulatePagingTo(prmVehicleClass.ResultsPaging);
|
||||
|
||||
@@ -157,8 +157,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Assets/VehicleClass/Ajax/GetItem")]
|
||||
[Route("Assets/VehicleClass/Ajax/GetVehicleClass")]
|
||||
[Route("Vehicles/VehicleClass/Ajax/GetItem")]
|
||||
[Route("Vehicles/VehicleClass/Ajax/GetVehicleClass")]
|
||||
public IActionResult Ajax_GetVehicleClass(Model_VehicleClass model)
|
||||
{
|
||||
String messageTitle = Localiser["caption.vehicle.class"];
|
||||
@@ -198,8 +198,8 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
// Store VehicleClass ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Assets/VehicleClass/Ajax/StoreItem")]
|
||||
[Route("Assets/VehicleClass/Ajax/StoreVehicleClass")]
|
||||
[Route("Vehicles/VehicleClass/Ajax/StoreItem")]
|
||||
[Route("Vehicles/VehicleClass/Ajax/StoreVehicleClass")]
|
||||
public IActionResult Ajax_StoreVehicleClass(Model_VehicleClass model)
|
||||
{
|
||||
String messageTitle = Localiser["caption.vehicle.class"];
|
||||
+4
-4
@@ -2,14 +2,14 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models.Assets;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models.Vehicles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Controllers.Vehicles
|
||||
{
|
||||
//======================================================================
|
||||
public partial class VehicleClassController : SbmController_Portal
|
||||
@@ -25,7 +25,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[Route("Assets/VehicleClass")]
|
||||
[Route("Vehicles/VehicleClass")]
|
||||
public IActionResult Index()
|
||||
{
|
||||
if (!ValidUserSession)
|
||||
@@ -40,7 +40,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Controllers.Assets
|
||||
|
||||
// VehicleClass page.
|
||||
Model_VehicleClass model = new Model_VehicleClass(Localiser);
|
||||
return View("Views/Assets/VehicleClass/Index.cshtml", model);
|
||||
return View("Views/Vehicles/VehicleClass/Index.cshtml", model);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -15,7 +15,7 @@ using System;
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
{
|
||||
//=======================================================================
|
||||
public class Model_Asset : SbmModel_Portal
|
||||
public partial class Model_Asset : SbmModel_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static Sarand.BusinessMgr.Net.Standard.Base.App.Sbm;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
{
|
||||
//=======================================================================
|
||||
// Asset Category model - Configuration.
|
||||
//=======================================================================
|
||||
partial class Model_AssetCategory
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
/// <summary>Prefix for field names.</summary>
|
||||
public const String FieldNamePrefix = "AssetCat";
|
||||
|
||||
/// <summary>Item fields.</summary>
|
||||
public enum ItemField
|
||||
{
|
||||
// AssetCategory properties.
|
||||
Id,
|
||||
// Identity.
|
||||
Type,
|
||||
Code,
|
||||
Caption,
|
||||
// Defaults.
|
||||
IncomeType,
|
||||
// Purchase.
|
||||
TaxCodePurchase,
|
||||
PaymentTerms,
|
||||
// Sale.
|
||||
TaxCodeSale,
|
||||
TaxCodeProfit,
|
||||
// Associated properties.
|
||||
AssetCount,
|
||||
// Common.
|
||||
Notes,
|
||||
Status,
|
||||
CreatedOn,
|
||||
UpdatedOn,
|
||||
Actions,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifier used by form fields to show control specific messages generated by model validation etc.
|
||||
/// <para>- Both page and model should use this method to consistently generate the field name.</para>
|
||||
/// </summary>
|
||||
public static String GetFieldName(ItemField field)
|
||||
{
|
||||
return $"{FieldNamePrefix}{field}";
|
||||
}
|
||||
|
||||
// List configuration.
|
||||
public class ListConfigData
|
||||
{
|
||||
// Actions.
|
||||
public class ActionData
|
||||
{
|
||||
public class AllowData
|
||||
{
|
||||
public bool? Create { get; set; }
|
||||
public bool? Update { get; set; }
|
||||
}
|
||||
public AllowData Allow { get; } = new AllowData();
|
||||
}
|
||||
public ActionData Action { get; } = new ActionData();
|
||||
// List columns.
|
||||
public class ColumnData
|
||||
{
|
||||
// Column name prefix.
|
||||
public String Prefix { get; } = Model_AssetCategory.FieldNamePrefix;
|
||||
// Hide column.
|
||||
public HashSet<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
// Column labels.
|
||||
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
public ColumnData Column { get; } = new ColumnData();
|
||||
}
|
||||
public ListConfigData ListConfig { get; private set; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Populate AssetCategory list configuration data - only required on initial page construction.
|
||||
/// </summary>
|
||||
public void PopulateListConfig()
|
||||
{
|
||||
ListConfig = new ListConfigData();
|
||||
PopulateListConfig(ListConfig);
|
||||
}
|
||||
public void PopulateListConfig(ListConfigData config)
|
||||
{
|
||||
ViewMode pageMode = GetFilterMode();
|
||||
bool modeIsSearch = pageMode == ViewMode.Search;
|
||||
bool modeIsMaintain = pageMode == ViewMode.Maintain;
|
||||
bool userCanCreateAssetCategories = SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(Sbm.ItemType.AssetCategory);
|
||||
bool userCanUpdateAssetCategories = SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(Sbm.ItemType.AssetCategory);
|
||||
|
||||
// Actions.
|
||||
|
||||
if (userCanCreateAssetCategories)
|
||||
config.Action.Allow.Create = true;
|
||||
if (userCanUpdateAssetCategories)
|
||||
config.Action.Allow.Update = true;
|
||||
|
||||
// List columns.
|
||||
|
||||
if (GetFilterAssetType() <= 0)
|
||||
config.Column.Hide.Add($"{ItemField.Type}");
|
||||
|
||||
// Asset Category Assets.
|
||||
if (!modeIsMaintain || !SessionConsole.AllowOption(Sbm.ConfigOption.Assets))
|
||||
config.Column.Hide.Add($"{ItemField.AssetCount}");
|
||||
|
||||
// Actions.
|
||||
if (!modeIsMaintain)
|
||||
config.Column.Hide.Add($"{ItemField.Actions}");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Item configuration.
|
||||
//-------------------------------------------------------------------
|
||||
// Legacy AssetCategory dialog tabs and panels.
|
||||
// Dialog:
|
||||
// - Asset type, code, caption.
|
||||
// Tab 1 'Properties':
|
||||
// Defaults - Income type.
|
||||
// Purchase - Purcahse tax code, payment terms.
|
||||
// Sale - Sell tax code, profit tax code.
|
||||
// Notes.
|
||||
// Tab 2 'Processes'.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
public class ItemConfigData
|
||||
{
|
||||
// Update dialog title.
|
||||
public String Title { get; set; }
|
||||
// Pre-select AssetCategory type.
|
||||
public class TypeData
|
||||
{
|
||||
public TypeData(string code, String desc)
|
||||
{
|
||||
Code = code;
|
||||
Desc = desc;
|
||||
}
|
||||
public String Code { get; set; }
|
||||
public String Desc { get; set; }
|
||||
}
|
||||
public TypeData Type { get; set; }
|
||||
// Field name prefix.
|
||||
public String Prefix { get; } = Model_AssetCategory.FieldNamePrefix;
|
||||
// Control flags.
|
||||
public bool? ManagedByAccounts { get; set; }
|
||||
public bool? LocalPricing { get; set; }
|
||||
// Allowed actions.
|
||||
public class AllowData
|
||||
{
|
||||
public bool? UpdateCode { get; set; }
|
||||
}
|
||||
public AllowData Allow { get; } = new AllowData();
|
||||
// Item fields.
|
||||
public class FieldData
|
||||
{
|
||||
// Field name prefix.
|
||||
public String Prefix { get; } = Model_AssetCategory.FieldNamePrefix;
|
||||
// Hide field.
|
||||
public HashSet<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
// Read-only field.
|
||||
public HashSet<string> Readonly { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
// Field labels.
|
||||
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
public FieldData Field { get; } = new FieldData();
|
||||
}
|
||||
/// <summary>
|
||||
/// Populate item configuration for existing vehicle.
|
||||
/// </summary>
|
||||
public void PopulateItemConfig(ItemConfigData config, SbmAssetCategory assetCategory)
|
||||
{
|
||||
PopulateItemConfig(config, assetCategory.GetItemId(), assetCategory.AssetType);
|
||||
}
|
||||
/// <summary>
|
||||
/// Populate item configuration for new or existing vehicle.
|
||||
/// </summary>
|
||||
public void PopulateItemConfig(ItemConfigData config, ItemId assetCategoryId, Sbm.AssetType assetType)
|
||||
{
|
||||
// Session configuration.
|
||||
bool userCanCreateAssetCategories = SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(Sbm.ItemType.AssetCategory);
|
||||
bool userCanUpdateAssetCategories = SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(Sbm.ItemType.AssetCategory);
|
||||
|
||||
// Update dialog title.
|
||||
config.Title = Localiser["caption.vehicle.update"];
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Identity.
|
||||
|
||||
// Asset type.
|
||||
// ToDo - Asset type readonly if any associated assets.
|
||||
if (!userCanUpdateAssetCategories || (ItemId.IsValid(assetCategoryId) && AssetMgr.AssetCategoryHasAssets(assetCategoryId.Id)))
|
||||
config.Field.Readonly.Add($"{ItemField.Type}");
|
||||
|
||||
// Code.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.Code}");
|
||||
|
||||
// Caption.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.Caption}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Defaults.
|
||||
|
||||
// Income type.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.IncomeType}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Purchase.
|
||||
|
||||
// Tax code - purchase.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.TaxCodePurchase}");
|
||||
|
||||
// Payment terms.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.PaymentTerms}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Sale.
|
||||
|
||||
// Tax code - sell.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.TaxCodeSale}");
|
||||
|
||||
// Tax code - profit.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.TaxCodeProfit}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Common properties.
|
||||
|
||||
// Status.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.Status}");
|
||||
|
||||
// Notes.
|
||||
if (!userCanUpdateAssetCategories)
|
||||
config.Field.Readonly.Add($"{ItemField.Notes}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
@@ -15,8 +16,15 @@ using System;
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
{
|
||||
//=======================================================================
|
||||
public class Model_AssetCategory : SbmModel_Portal
|
||||
public partial class Model_AssetCategory : SbmModel_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum ViewMode
|
||||
{
|
||||
Search, Maintain
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public Model_AssetCategory(SbmLocaliser localiser) :
|
||||
@@ -28,14 +36,24 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
// Filter properties.
|
||||
public class FilterData
|
||||
{
|
||||
public String Mode { get; set; }
|
||||
public String AssetType { get; set; }
|
||||
public String Search { get; set; }
|
||||
public String StatusCat { get; set; }
|
||||
public SbmAssetCategory.StatusCat GetStatusCat()
|
||||
{
|
||||
return EnumUtil.ParseEnum(StatusCat, SbmAssetCategory.StatusCat.NotDeleted);
|
||||
}
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
public ViewMode GetFilterMode()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search);
|
||||
}
|
||||
public Sbm.AssetType GetFilterAssetType()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.AssetType, Sbm.AssetType.Unknown);
|
||||
}
|
||||
public SbmAssetCategory.StatusCat GetFilterStatusCat()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.StatusCat, SbmAssetCategory.StatusCat.NotDeleted);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Item properties.
|
||||
@@ -46,12 +64,12 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
public String TypeCode { get; set; }
|
||||
public Sbm.AssetType AssetType { get; set; }
|
||||
public String Code { get; set; }
|
||||
public String DescBrief { get; set; }
|
||||
public String Caption { get; set; }
|
||||
public String Notes { get; set; }
|
||||
public String StatusCode { get; set; }
|
||||
public SaStatus GetStatus() { return SacsSystem.GetStatusForCode(StatusCode); }
|
||||
}
|
||||
public AssetCategoryData AssetCategory { get; } = new AssetCategoryData();
|
||||
public SaStatus GetAssetCategoryStatus() { return SacsSystem.GetStatusForCode(AssetCategory.StatusCode); }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Validation.
|
||||
@@ -66,7 +84,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
// AssetCategory type.
|
||||
if (AssetCategory.TypeCode != null)
|
||||
{
|
||||
String controlName = "AssetCategoryType";
|
||||
String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Type);
|
||||
AssetCategory.AssetType = (Sbm.AssetType)Internals.AssetTypeCodes.GetTypeForCode(AssetCategory.TypeCode);
|
||||
responseData.SetControlValue(controlName, AssetCategory.TypeCode);
|
||||
if (StringUtil.IsBlank(AssetCategory.TypeCode))
|
||||
@@ -78,7 +96,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
// AssetCategory Code.
|
||||
if (AssetCategory.Code != null)
|
||||
{
|
||||
String controlName = "AssetCategoryCode";
|
||||
String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Code);
|
||||
AssetCategory.Code = AssetCategory.Code.ToUpper();
|
||||
responseData.SetControlValue(controlName, AssetCategory.Code);
|
||||
if (StringUtil.IsBlank(AssetCategory.Code))
|
||||
@@ -87,21 +105,21 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Code)]);
|
||||
}
|
||||
|
||||
// AssetCategory DescBrief.
|
||||
if (AssetCategory.DescBrief != null)
|
||||
// AssetCategory Caption.
|
||||
if (AssetCategory.Caption != null)
|
||||
{
|
||||
String controlName = "AssetCategoryDescription";
|
||||
responseData.SetControlValue(controlName, AssetCategory.DescBrief);
|
||||
if (StringUtil.IsBlank(AssetCategory.DescBrief))
|
||||
String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Caption);
|
||||
responseData.SetControlValue(controlName, AssetCategory.Caption);
|
||||
if (StringUtil.IsBlank(AssetCategory.Caption))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (StringUtil.GetLength(AssetCategory.DescBrief) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief))
|
||||
else if (StringUtil.GetLength(AssetCategory.Caption) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief)]);
|
||||
}
|
||||
|
||||
// Notes.
|
||||
if (AssetCategory.Notes != null)
|
||||
{
|
||||
String controlName = "AssetCategoryNotes";
|
||||
String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Notes);
|
||||
responseData.SetControlValue(controlName, AssetCategory.Notes);
|
||||
if (StringUtil.GetLength(AssetCategory.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes)]);
|
||||
@@ -110,10 +128,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
// AssetCategory status.
|
||||
if (AssetCategory.StatusCode != null)
|
||||
{
|
||||
String controlName = "AssetCategoryStatus";
|
||||
String controlName = @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Status);
|
||||
if (StringUtil.IsBlank(AssetCategory.StatusCode))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SbmAssetCategory.ValidStatuses.Contains(AssetCategory.GetStatus()))
|
||||
else if (!SbmAssetCategory.ValidStatuses.Contains(GetAssetCategoryStatus()))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
{
|
||||
//=======================================================================
|
||||
public class Model_VehicleClass : SbmModel_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public Model_VehicleClass(SbmLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Filter properties.
|
||||
public class FilterData
|
||||
{
|
||||
public string Search { get; set; }
|
||||
public string StatusCat { get; set; }
|
||||
public SbmVehicleClass.StatusCat GetStatusCat()
|
||||
{
|
||||
return EnumUtil.ParseEnum(StatusCat, SbmVehicleClass.StatusCat.NotDeleted);
|
||||
}
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Item properties.
|
||||
public class VehicleClassData
|
||||
{
|
||||
public string Exists { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string MakeCode { get; set; }
|
||||
public string Model { get; set; }
|
||||
public string Derivative { get; set; }
|
||||
public string DescBrief { get; set; }
|
||||
public string VehicleTypeCode { get; set; }
|
||||
public Sbm.VehicleType VehicleType { get; set; } = Sbm.VehicleType.Unknown;
|
||||
public string VehicleCategoryCode { get; set; }
|
||||
public string FuelTypeCode { get; set; }
|
||||
public Sbm.VehicleFuelType FuelType { get; set; } = Sbm.VehicleFuelType.Unknown;
|
||||
public string OdometerUnitsCode { get; set; }
|
||||
public Sbm.VehicleOdometerUnits OdometerUnits { get; set; } = Sbm.VehicleOdometerUnits.Unknown;
|
||||
public string Notes { get; set; }
|
||||
public string StatusCode { get; set; }
|
||||
public SaStatus GetStatus() { return SacsSystem.GetStatusForCode(StatusCode); }
|
||||
}
|
||||
public VehicleClassData VehicleClass { get; } = new VehicleClassData();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Validation.
|
||||
//-------------------------------------------------------------------
|
||||
// VehicleClass.
|
||||
public bool ValidateVehicleClassData(Sacs.Web.Components.SaController.AjaxResponse_Data responseData)
|
||||
{
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
|
||||
{
|
||||
|
||||
// Make.
|
||||
if (VehicleClass.MakeCode != null)
|
||||
{
|
||||
string controlName = "VehicleClassMake";
|
||||
responseData.SetControlValue(controlName, VehicleClass.MakeCode);
|
||||
if (VehicleClass.MakeCode.IsBlank())
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
}
|
||||
|
||||
// Model.
|
||||
if (VehicleClass.Model != null)
|
||||
{
|
||||
string controlName = "VehicleClassModel";
|
||||
VehicleClass.Model = VehicleClass.Model.ToUpper();
|
||||
responseData.SetControlValue(controlName, VehicleClass.Model);
|
||||
if (VehicleClass.Model.IsBlank())
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (StringUtil.GetLength(VehicleClass.Model) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Model))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Model)]);
|
||||
}
|
||||
|
||||
// VehicleClass DescBrief.
|
||||
if (VehicleClass.DescBrief != null)
|
||||
{
|
||||
string controlName = "VehicleClassDescription";
|
||||
responseData.SetControlValue(controlName, VehicleClass.DescBrief);
|
||||
if (VehicleClass.DescBrief.IsBlank())
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (StringUtil.GetLength(VehicleClass.DescBrief) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_DescBrief))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_DescBrief)]);
|
||||
}
|
||||
|
||||
// Notes.
|
||||
if (VehicleClass.Notes != null)
|
||||
{
|
||||
string controlName = "VehicleClassNotes";
|
||||
responseData.SetControlValue(controlName, VehicleClass.Notes);
|
||||
if (StringUtil.GetLength(VehicleClass.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Notes))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Notes)]);
|
||||
}
|
||||
|
||||
// VehicleClass status.
|
||||
if (VehicleClass.StatusCode != null)
|
||||
{
|
||||
string controlName = "VehicleClassStatus";
|
||||
if (VehicleClass.StatusCode.IsBlank())
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SbmVehicleClass.ValidStatuses.Contains(VehicleClass.GetStatus()))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
}
|
||||
|
||||
return !responseData.HasControlErrors();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -219,11 +219,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
|
||||
public void PopulateListConfig(ListConfigData config)
|
||||
{
|
||||
// View properties.
|
||||
CommodityViewMode viewMode = GetFilterMode();
|
||||
bool modeIsMaintain = viewMode == CommodityViewMode.Maintain;
|
||||
bool modeIsSearch = viewMode == CommodityViewMode.Search;
|
||||
bool modeIsStockControl = viewMode == CommodityViewMode.StockControl;
|
||||
bool modeIsStockTake = viewMode == CommodityViewMode.StockTake;
|
||||
ViewMode viewMode = GetFilterMode();
|
||||
bool modeIsMaintain = viewMode == ViewMode.Maintain;
|
||||
bool modeIsSearch = viewMode == ViewMode.Search;
|
||||
bool modeIsStockControl = viewMode == ViewMode.StockControl;
|
||||
bool modeIsStockTake = viewMode == ViewMode.StockTake;
|
||||
|
||||
Sbm.CommodityType commodityType = GetFilterCommodityType();
|
||||
|
||||
@@ -260,7 +260,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
|
||||
config.Column.Hide.Add($"{ItemField.SalesPrice}");
|
||||
|
||||
// Pack qty.
|
||||
if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_PackQtySale))
|
||||
if (modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_PackQtySale))
|
||||
config.Column.Label.Add($"{ItemField.PackQtySale}", Localiser["label.pack.quantity"]);
|
||||
else
|
||||
config.Column.Hide.Add($"{ItemField.PackQtySale}");
|
||||
@@ -288,7 +288,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
|
||||
// Specification.
|
||||
|
||||
// Weight.
|
||||
if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_Weight))
|
||||
if (modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_Weight))
|
||||
config.Column.Label.Add($"{ItemField.Weight}", Localiser["label.weight"]);
|
||||
else
|
||||
config.Column.Hide.Add($"{ItemField.Weight}");
|
||||
@@ -297,7 +297,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
|
||||
// Defaults.
|
||||
|
||||
// Catalog Reference.
|
||||
if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_CatalogRef))
|
||||
if (modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_CatalogRef))
|
||||
config.Column.Label.Add($"{ItemField.CatalogRef}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_CatalogRef, Localiser["label.catalog.ref"]));
|
||||
else
|
||||
config.Column.Hide.Add($"{ItemField.CatalogRef}");
|
||||
@@ -306,19 +306,19 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
|
||||
// Stock.
|
||||
|
||||
// Stock - allocated.
|
||||
if ((modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAllocated)) && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_QtyAllocated))
|
||||
if ((modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAllocated)) && SessionConsole.DisplayAttribute(SbmDbDfn.ColumnIdx.Commodity_QtyAllocated))
|
||||
config.Column.Label.Add($"{ItemField.QtyAllocated}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Commodity_QtyAllocated, Localiser["label.allocated"]));
|
||||
else
|
||||
config.Column.Hide.Add($"{ItemField.QtyAllocated}");
|
||||
|
||||
// Stock - available.
|
||||
if (!modeIsStockControl && SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAvailable))
|
||||
if (!modeIsStockControl && SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockAvailable))
|
||||
config.Column.Label.Add($"{ItemField.StockAvailable}", Localiser["label.available"]);
|
||||
else
|
||||
config.Column.Hide.Add($"{ItemField.StockAvailable}");
|
||||
|
||||
// Current Level.
|
||||
if (modeIsStockControl || SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockLevelSales))
|
||||
if (modeIsStockControl || SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Commodity_StockLevelSales))
|
||||
config.Column.Label.Add($"{ItemField.CurrentLevel}", Localiser["label.current.level"]);
|
||||
else
|
||||
config.Column.Hide.Add($"{ItemField.CurrentLevel}");
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum CommodityViewMode
|
||||
public enum ViewMode
|
||||
{
|
||||
Search, Maintain, StockControl, StockTake
|
||||
}
|
||||
@@ -49,9 +49,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Commodities
|
||||
public String Search { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
public CommodityViewMode GetFilterMode()
|
||||
public ViewMode GetFilterMode()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.Mode, CommodityViewMode.Search);
|
||||
return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search);
|
||||
}
|
||||
public Sbm.CommodityType GetFilterCommodityType()
|
||||
{
|
||||
|
||||
@@ -134,9 +134,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
}
|
||||
public void PopulateListConfig(ListConfigData config)
|
||||
{
|
||||
AssociationViewMode pageMode = GetFilterMode();
|
||||
bool modeIsRelationships = pageMode == AssociationViewMode.Relationships;
|
||||
bool modeIsMaintain = pageMode == AssociationViewMode.Maintain;
|
||||
ViewMode pageMode = GetFilterMode();
|
||||
bool modeIsRelationships = pageMode == ViewMode.Relationships;
|
||||
bool modeIsMaintain = pageMode == ViewMode.Maintain;
|
||||
Sbm.AssociationType associationType = GetFilterAssociationType();
|
||||
bool typeIsCustomer = associationType == Sbm.AssociationType.Customer;
|
||||
bool typeIsSupplier = associationType == Sbm.AssociationType.Supplier;
|
||||
@@ -177,15 +177,15 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
config.Column.Hide.Add($"{ItemField.Address}");
|
||||
|
||||
// Customer financials.
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Open))
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Open))
|
||||
config.Column.Hide.Add($"{ItemField.TransSalesValueOpen}");
|
||||
if (!modeIsMaintain || !typeIsCustomer || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_LastSaleRaised))
|
||||
if (!modeIsMaintain || !typeIsCustomer || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_LastSaleRaised))
|
||||
config.Column.Hide.Add($"{ItemField.TransLastSaleRaised}");
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_AnnualSalesTarget))
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_AnnualSalesTarget))
|
||||
config.Column.Hide.Add($"{ItemField.AnnualSalesTarget}");
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Cytd))
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Cytd))
|
||||
config.Column.Hide.Add($"{ItemField.TransSalesValueCytd}");
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Lcy))
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Trans_SalesValue_Lcy))
|
||||
config.Column.Hide.Add($"{ItemField.TransSalesValueLcy}");
|
||||
// Customer commodities.
|
||||
if (!modeIsMaintain || !typeIsCustomer || !CommodityMgr.CanManageCommodityCustomers())
|
||||
@@ -196,7 +196,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
if (!modeIsMaintain || !typeIsCustomer || !UserCanViewFinancials() || !SessionConsole.AllowOption(Sbm.ConfigOption.CustomerPriceSet) && PriceMgr.PriceDatabaseIsValid)
|
||||
config.Column.Hide.Add($"{ItemField.PriceSet}");
|
||||
// Association group.
|
||||
if (!modeIsMaintain || !typeIsCustomer || !SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Group))
|
||||
if (!modeIsMaintain || !typeIsCustomer || !SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Association_Group))
|
||||
config.Column.Hide.Add($"{ItemField.Group}");
|
||||
// Customer codes.
|
||||
if (!modeIsMaintain || !typeIsCustomer || !CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.AccountManager)))
|
||||
@@ -331,7 +331,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
config.Type = new ItemConfigData.TypeData(associationTypes.GetCodeForType(Sbm.AssociationType.Member), Localiser.GetAssociationTypeCaption(Sbm.AssociationType.Member));
|
||||
|
||||
// Allow actions.
|
||||
if (SessionData_Portal.GetOwnerOption_AllowOption(Sbm.OrgOption_AllowOption.UpdateAssociationCode))
|
||||
if (SessionConsole.GetOwnerOption_AllowOption(Sbm.OrgOption_AllowOption.UpdateAssociationCode))
|
||||
config.Allow.UpdateCode = true;
|
||||
|
||||
// Item Fields.
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum AssociationViewMode
|
||||
public enum ViewMode
|
||||
{
|
||||
Search, Maintain, Relationships, PriceSet,
|
||||
}
|
||||
@@ -39,9 +39,6 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Filter.
|
||||
public class FilterData
|
||||
@@ -53,9 +50,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
public string Search { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
public AssociationViewMode GetFilterMode()
|
||||
public ViewMode GetFilterMode()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.Mode, AssociationViewMode.Search);
|
||||
return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search);
|
||||
}
|
||||
public Sbm.AssociationType GetFilterAssociationType()
|
||||
{
|
||||
|
||||
@@ -114,9 +114,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
public void PopulateListConfig(ListConfigData config)
|
||||
{
|
||||
|
||||
ContactViewMode viewMode = GetFilterMode();
|
||||
bool modeIsMaintain= viewMode == ContactViewMode.Maintain;
|
||||
bool modeIsSearch = viewMode == ContactViewMode.Search;
|
||||
ViewMode viewMode = GetFilterMode();
|
||||
bool modeIsMaintain= viewMode == ViewMode.Maintain;
|
||||
bool modeIsSearch = viewMode == ViewMode.Search;
|
||||
|
||||
Sbm.AffiliateType affiliateType = GetFilterContactType();
|
||||
bool contactGroupsOnly = affiliateType == Sbm.AffiliateType.ContactGroup;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum ContactViewMode
|
||||
public enum ViewMode
|
||||
{
|
||||
Search, Maintain,
|
||||
}
|
||||
@@ -49,9 +49,9 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
public String Email { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
public ContactViewMode GetFilterMode()
|
||||
public ViewMode GetFilterMode()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.Mode, ContactViewMode.Search);
|
||||
return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search);
|
||||
}
|
||||
public Sbm.AffiliateType GetFilterContactType()
|
||||
{
|
||||
|
||||
@@ -106,6 +106,10 @@ namespace Sarand.BusinessMgr.Web.Portal.Models
|
||||
Menu.Items.Add(referenceItem);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// View reference data.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// View reference data - Contacts.
|
||||
|
||||
@@ -113,7 +117,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models
|
||||
/// List of Affiliate Types for filter dropdown.
|
||||
/// <para>- Contact model cannot define this as contact list/dialog may be included in other views with their own model, eg. Association page.</para>
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetAffiliateTypeCodesForFilterSelect()
|
||||
public IEnumerable<SelectListItem> GetAffiliateTypeCodesForFilterDropdown()
|
||||
{
|
||||
List<TypeCodeDesc> affiliateTypes = GetCodesOfType(Sbm.SystemCode.AffiliateType);
|
||||
if (!affiliateTypes.Any(item => item.Type == (int)Sbm.AffiliateType.AnyOrganisation))
|
||||
@@ -125,7 +129,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models
|
||||
/// List of Association Types for filter dropdown.
|
||||
/// <para>- Association model cannot define this as association list/dialog may be included in other views with their own model, eg. Commodity page.</para>
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetAssociationTypeCodesForFilterSelect()
|
||||
public IEnumerable<SelectListItem> GetAssociationTypeCodesForFilterDropdown()
|
||||
{
|
||||
List<TypeCodeDesc> associationTypes = GetCodesOfType(Sbm.SystemCode.AssociationType);
|
||||
associationTypes.RemoveAll(item => item.Type == (short)Sbm.AssociationType.Internal);
|
||||
@@ -137,13 +141,72 @@ namespace Sarand.BusinessMgr.Web.Portal.Models
|
||||
return new SelectList(associationTypes, "Code", "Desc");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// View reference data - Commodities.
|
||||
|
||||
/// <summary>
|
||||
/// List of Commodity Types for filter dropdown.
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetCommodityTypeCodesForFilterDropdown()
|
||||
{
|
||||
List<TypeCodeDesc> commodityTypes = new List<TypeCodeDesc>();
|
||||
commodityTypes.Add(Sbm.CommodityType.Any, "", Localiser["label.any"]);
|
||||
foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType))
|
||||
{
|
||||
if (commodityType.Type == (int)Sbm.CommodityType.Asset && !SessionConsole.AllowOption(ConfigOption.Assets)) continue;
|
||||
commodityTypes.Add(commodityType);
|
||||
}
|
||||
return new SelectList(commodityTypes, "Code", "Desc");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of Commodity Types for form dropdown.
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetCommodityTypeCodesForDropdown()
|
||||
{
|
||||
List<TypeCodeDesc> commodityTypes = new List<TypeCodeDesc>();
|
||||
foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType))
|
||||
{
|
||||
if (commodityType.Type == (int)Sbm.CommodityType.Asset && !SessionConsole.AllowOption(ConfigOption.Assets)) continue;
|
||||
commodityTypes.Add(commodityType);
|
||||
}
|
||||
return new SelectList(commodityTypes, "Code", "Desc");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of Asset Types for filter dropdown.
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetAssetTypeCodesForFilterDropdown()
|
||||
{
|
||||
List<TypeCodeDesc> assetTypes = new List<TypeCodeDesc>();
|
||||
assetTypes.Add(Sbm.AssetType.Any, "", Localiser["label.any"]);
|
||||
foreach (TypeCodeDesc assetType in GetCodesOfType(Sbm.SystemCode.AssetType))
|
||||
{
|
||||
assetTypes.Add(assetType);
|
||||
}
|
||||
return new SelectList(assetTypes, "Code", "Desc");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of Asset Types for form dropdown.
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetAssetTypeCodesForDropdown()
|
||||
{
|
||||
List<TypeCodeDesc> assetTypes = new List<TypeCodeDesc>();
|
||||
foreach (TypeCodeDesc assetType in GetCodesOfType(Sbm.SystemCode.AssetType))
|
||||
{
|
||||
assetTypes.Add(assetType);
|
||||
}
|
||||
return new SelectList(assetTypes, "Code", "Desc");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// View reference data - Transactions.
|
||||
|
||||
/// <summary>
|
||||
/// List of Transaction Types for filter dropdown.
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetTransactionTypeCodesForFilterSelect()
|
||||
public IEnumerable<SelectListItem> GetTransactionTypeCodesForFilterDropdown()
|
||||
{
|
||||
List<TypeCodeDesc> transactionTypes = new List<TypeCodeDesc>();
|
||||
transactionTypes.Add(Sbm.TransactionType.Any, "", Localiser["label.any"]);
|
||||
@@ -171,44 +234,11 @@ namespace Sarand.BusinessMgr.Web.Portal.Models
|
||||
return new SelectList(transactionTypes, "Code", "Desc");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// View reference data - Commodities.
|
||||
|
||||
/// <summary>
|
||||
/// List of Commodity Types for filter dropdown.
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetCommodityTypeCodesForFilterSelect()
|
||||
{
|
||||
List<TypeCodeDesc> commodityTypes = new List<TypeCodeDesc>();
|
||||
commodityTypes.Add(Sbm.CommodityType.Any, "", Localiser["label.any"]);
|
||||
foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType))
|
||||
{
|
||||
if (commodityType.Type == (int)Sbm.CommodityType.Asset && !SessionConsole.AllowOption(ConfigOption.Assets)) continue;
|
||||
commodityTypes.Add(commodityType);
|
||||
}
|
||||
return new SelectList(commodityTypes, "Code", "Desc");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of Commodity Types for form dropdown.
|
||||
/// </summary>
|
||||
public IEnumerable<SelectListItem> GetCommodityTypeCodesForDropdown()
|
||||
{
|
||||
List<TypeCodeDesc> commodityTypes = new List<TypeCodeDesc>();
|
||||
foreach (TypeCodeDesc commodityType in GetCodesOfType(Sbm.SystemCode.CommodityType))
|
||||
{
|
||||
if (commodityType.Type == (int)Sbm.CommodityType.Asset && !SessionConsole.AllowOption(ConfigOption.Assets)) continue;
|
||||
commodityTypes.Add(commodityType);
|
||||
}
|
||||
return new SelectList(commodityTypes, "Code", "Desc");
|
||||
}
|
||||
|
||||
// ToDo - Organisation Option - Show Column:
|
||||
// case Sbm.SystemCode.OrgOption_ShowColumn:
|
||||
// if (code.Type == (int) Sbm.OrgOption_ShowColumn.Transaction_ContactArea)
|
||||
// Desc = "Transaction: " + sessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Association_ContactAreaCode, "Contact area");
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -394,7 +394,7 @@ namespace Sarand.BusinessMgr.Web.Portal.Models.Transactions
|
||||
|
||||
// Contact Area.
|
||||
if (CodeTypeConsole.CodeTypeHasCodes(Internals.GetCodeTypeCode(Sbm.ApplCodeType.ContactArea)) &&
|
||||
SessionData_Portal.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Transaction_ContactArea) &&
|
||||
SessionConsole.GetOwnerOption_ShowColumn(Sbm.OrgOption_ShowColumn.Transaction_ContactArea) &&
|
||||
(modeIsDeliveryPlanning || isSalesOrder))
|
||||
{
|
||||
config.Column.Label.Add($"{ItemField.ContactArea}", SessionConsole.GetAttributeCaption(SbmDbDfn.ColumnIdx.Transaction_ContactAreaCode, Localiser["label.contact.area"]));
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Models.Vehicles
|
||||
{
|
||||
//=======================================================================
|
||||
// Vehicle model - Configuration.
|
||||
//=======================================================================
|
||||
partial class Model_Vehicle
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
/// <summary>Prefix for field names.</summary>
|
||||
public const String FieldNamePrefix = "Vehicle";
|
||||
|
||||
/// <summary>Item fields.</summary>
|
||||
public enum ItemField
|
||||
{
|
||||
// Vehicle properties.
|
||||
Id,
|
||||
// Identity.
|
||||
Registration,
|
||||
Vin,
|
||||
// Model.
|
||||
Make,
|
||||
Model,
|
||||
Class,
|
||||
// Defaults.
|
||||
CapCode,
|
||||
KeyNumber,
|
||||
KeyLocation,
|
||||
Weight,
|
||||
// Spec.
|
||||
BuildOn,
|
||||
PurchaseOdo,
|
||||
RegisterOn,
|
||||
FirstRegisterOn,
|
||||
EngineNumber,
|
||||
RegistrationPrevious,
|
||||
LatestOdo,
|
||||
LatestOdoOn,
|
||||
// Associated properties.
|
||||
AssetCount,
|
||||
// Common.
|
||||
Notes,
|
||||
Status,
|
||||
CreatedOn,
|
||||
UpdatedOn,
|
||||
Actions,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifier used by form fields to show control specific messages generated by model validation etc.
|
||||
/// <para>- Both page and model should use this method to consistently generate the field name.</para>
|
||||
/// </summary>
|
||||
public static String GetFieldName(ItemField field)
|
||||
{
|
||||
return $"{FieldNamePrefix}{field}";
|
||||
}
|
||||
|
||||
// List configuration.
|
||||
public class ListConfigData
|
||||
{
|
||||
// Actions.
|
||||
public class ActionData
|
||||
{
|
||||
public class AllowData
|
||||
{
|
||||
public bool? Create { get; set; }
|
||||
public bool? Update { get; set; }
|
||||
}
|
||||
public AllowData Allow { get; } = new AllowData();
|
||||
}
|
||||
public ActionData Action { get; } = new ActionData();
|
||||
// List columns.
|
||||
public class ColumnData
|
||||
{
|
||||
// Column name prefix.
|
||||
public String Prefix { get; } = Model_Vehicle.FieldNamePrefix;
|
||||
// Hide column.
|
||||
public HashSet<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
// Column labels.
|
||||
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
public ColumnData Column { get; } = new ColumnData();
|
||||
}
|
||||
public ListConfigData ListConfig { get; private set; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Populate Vehicle list configuration data - only required on initial page construction.
|
||||
/// </summary>
|
||||
public void PopulateListConfig()
|
||||
{
|
||||
ListConfig = new ListConfigData();
|
||||
PopulateListConfig(ListConfig);
|
||||
}
|
||||
public void PopulateListConfig(ListConfigData config)
|
||||
{
|
||||
ViewMode pageMode = GetFilterMode();
|
||||
bool modeIsSearch = pageMode == ViewMode.Search;
|
||||
bool modeIsMaintain = pageMode == ViewMode.Maintain;
|
||||
bool userCanCreateVehicles = SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(Sbm.ItemType.Vehicle);
|
||||
bool userCanUpdateVehicles = SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(Sbm.ItemType.Vehicle);
|
||||
|
||||
// Actions.
|
||||
|
||||
if (userCanCreateVehicles)
|
||||
config.Action.Allow.Create = true;
|
||||
if (userCanUpdateVehicles)
|
||||
config.Action.Allow.Update = true;
|
||||
|
||||
// List columns.
|
||||
|
||||
if (SysId.IsValid(SysId.ToSysId(Filter.VehicleClassId)))
|
||||
config.Column.Hide.Add($"{ItemField.Class}");
|
||||
|
||||
// Vehicle Assets.
|
||||
if (!modeIsMaintain || !SessionConsole.AllowOption(Sbm.ConfigOption.Assets))
|
||||
config.Column.Hide.Add($"{ItemField.AssetCount}");
|
||||
|
||||
// Actions.
|
||||
if (!modeIsMaintain)
|
||||
config.Column.Hide.Add($"{ItemField.Actions}");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Item configuration.
|
||||
//-------------------------------------------------------------------
|
||||
// Legacy Vehicle dialog tabs and panels.
|
||||
// Tab 1 'Properties':
|
||||
// Model
|
||||
// Defaults
|
||||
// Spec
|
||||
// HPI
|
||||
// Service
|
||||
// Notes
|
||||
// Tab 2 'Features':
|
||||
// Features
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
public class ItemConfigData
|
||||
{
|
||||
// Update dialog title.
|
||||
public String Title { get; set; }
|
||||
// Pre-select Vehicle type.
|
||||
public class TypeData
|
||||
{
|
||||
public TypeData(string code, String desc)
|
||||
{
|
||||
Code = code;
|
||||
Desc = desc;
|
||||
}
|
||||
public String Code { get; set; }
|
||||
public String Desc { get; set; }
|
||||
}
|
||||
public TypeData Type { get; set; }
|
||||
// Field name prefix.
|
||||
public String Prefix { get; } = Model_Vehicle.FieldNamePrefix;
|
||||
// Control flags.
|
||||
public bool? ManagedByAccounts { get; set; }
|
||||
public bool? LocalPricing { get; set; }
|
||||
// Allowed actions.
|
||||
public class AllowData
|
||||
{
|
||||
public bool? UpdateCode { get; set; }
|
||||
}
|
||||
public AllowData Allow { get; } = new AllowData();
|
||||
// Item fields.
|
||||
public class FieldData
|
||||
{
|
||||
// Field name prefix.
|
||||
public String Prefix { get; } = Model_Vehicle.FieldNamePrefix;
|
||||
// Hide field.
|
||||
public HashSet<string> Hide { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
// Read-only field.
|
||||
public HashSet<string> Readonly { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
// Field labels.
|
||||
public Dictionary<String, String> Label { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
public FieldData Field { get; } = new FieldData();
|
||||
}
|
||||
/// <summary>
|
||||
/// Populate item configuration for existing vehicle.
|
||||
/// </summary>
|
||||
public void PopulateItemConfig(ItemConfigData config, SbmVehicle vehicle)
|
||||
{
|
||||
PopulateItemConfig(config, vehicle.GetItemId());
|
||||
}
|
||||
/// <summary>
|
||||
/// Populate item configuration for new or existing vehicle.
|
||||
/// </summary>
|
||||
public void PopulateItemConfig(ItemConfigData config, ItemId vehicleItemId)
|
||||
{
|
||||
// Session configuration.
|
||||
bool userCanCreateVehicles = SessionData_Portal.SecurityProfile_Core.UserCanCreateItemType(Sbm.ItemType.Vehicle);
|
||||
bool userCanUpdateVehicles = SessionData_Portal.SecurityProfile_Core.UserCanUpdateItemType(Sbm.ItemType.Vehicle);
|
||||
|
||||
// Update dialog title.
|
||||
config.Title = Localiser["caption.vehicle.update"];
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Identity.
|
||||
|
||||
// Registration.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.Registration}");
|
||||
|
||||
// VIN.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.Vin}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Model.
|
||||
|
||||
// Make.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.Make}");
|
||||
|
||||
// Model.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.Model}");
|
||||
|
||||
// Class.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.Class}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Defaults.
|
||||
|
||||
// CAP code.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.CapCode}");
|
||||
|
||||
// Key Number.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.KeyNumber}");
|
||||
|
||||
// Key Location.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.KeyLocation}");
|
||||
|
||||
// Weight.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.Weight}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Spec.
|
||||
|
||||
// Build On.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.BuildOn}");
|
||||
|
||||
// Purchase Odomoeter.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.PurchaseOdo}");
|
||||
|
||||
// Register On.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.RegisterOn}");
|
||||
|
||||
// First Register On.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.FirstRegisterOn}");
|
||||
|
||||
// Engine Number.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.EngineNumber}");
|
||||
|
||||
// Previous Registration.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.RegistrationPrevious}");
|
||||
|
||||
// Latest Odomoeter.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.LatestOdo}");
|
||||
|
||||
// Latest Odomoeter.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.LatestOdoOn}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Service.
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Common properties.
|
||||
|
||||
// Status.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.Status}");
|
||||
|
||||
// Notes.
|
||||
if (!userCanUpdateVehicles)
|
||||
config.Field.Readonly.Add($"{ItemField.Notes}");
|
||||
|
||||
//---------------------------------------------------------------
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
|
||||
using Sarand.BusinessMgr.Web.Portal.Models;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Models.Vehicles
|
||||
{
|
||||
//=======================================================================
|
||||
public partial class Model_Vehicle : SbmModel_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum ViewMode
|
||||
{
|
||||
Search, Maintain
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public Model_Vehicle(SbmLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Filter properties.
|
||||
public class FilterData
|
||||
{
|
||||
public String Mode { get; set; }
|
||||
public String VehicleClassId { get; set; }
|
||||
public String Search { get; set; }
|
||||
public String StatusCat { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
public ViewMode GetFilterMode()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.Mode, ViewMode.Search);
|
||||
}
|
||||
public SbmVehicle.StatusCat GetFilterStatusCat()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.StatusCat, SbmVehicle.StatusCat.NotDeleted);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Item properties.
|
||||
public class VehicleData
|
||||
{
|
||||
public String Exists { get; set; }
|
||||
public String Id { get; set; }
|
||||
public String ClassId { get; set; }
|
||||
public String Registration { get; set; }
|
||||
public String Vin { get; set; }
|
||||
public String CapCode { get; set; }
|
||||
public String KeyNumber { get; set; }
|
||||
public String KeyLocation { get; set; }
|
||||
public String EngineNumber { get; set; }
|
||||
public String EngineCapacity { get; set; }
|
||||
public String Seats { get; set; }
|
||||
public String Weight { get; set; }
|
||||
public String ManufactureYear { get; set; }
|
||||
public String Notes { get; set; }
|
||||
public String StatusCode { get; set; }
|
||||
public SaStatus GetStatus() { return SacsSystem.GetStatusForCode(StatusCode); }
|
||||
}
|
||||
public VehicleData Vehicle { get; } = new VehicleData();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Validation.
|
||||
//-------------------------------------------------------------------
|
||||
// Vehicle.
|
||||
public bool ValidateVehicleData(SbmController_Base.AjaxResponse_Data responseData)
|
||||
{
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
|
||||
{
|
||||
|
||||
// Vehicle Class.
|
||||
if (Vehicle.ClassId != null)
|
||||
{
|
||||
String controlName = "VehicleClass";
|
||||
if (StringUtil.IsBlank(Vehicle.ClassId))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!AssetMgr.VehicleClassExistsById(SysId.ToSysId(Vehicle.ClassId)))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
|
||||
// Registration.
|
||||
if (Vehicle.Registration != null)
|
||||
{
|
||||
String controlName = "VehicleRegistration";
|
||||
Vehicle.Registration = Vehicle.Registration.ToUpper();
|
||||
responseData.SetControlValue(controlName, Vehicle.Registration);
|
||||
if (StringUtil.IsBlank(Vehicle.Registration))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (StringUtil.GetLength(Vehicle.Registration) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_RegNumber))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_RegNumber)]);
|
||||
}
|
||||
|
||||
// Vin.
|
||||
if (Vehicle.Vin != null)
|
||||
{
|
||||
String controlName = "VehicleVin";
|
||||
Vehicle.Vin = Vehicle.Vin.ToUpper();
|
||||
responseData.SetControlValue(controlName, Vehicle.Vin);
|
||||
if (StringUtil.GetLength(Vehicle.Vin) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_VIN))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_VIN)]);
|
||||
}
|
||||
|
||||
// Notes.
|
||||
if (Vehicle.Notes != null)
|
||||
{
|
||||
String controlName = "VehicleNotes";
|
||||
responseData.SetControlValue(controlName, Vehicle.Notes);
|
||||
if (StringUtil.GetLength(Vehicle.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_Notes))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicle_Notes)]);
|
||||
}
|
||||
|
||||
// Vehicle status.
|
||||
if (Vehicle.StatusCode != null)
|
||||
{
|
||||
String controlName = "VehicleStatus";
|
||||
if (StringUtil.IsBlank(Vehicle.StatusCode))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SbmVehicle.ValidStatuses.Contains(Vehicle.GetStatus()))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
}
|
||||
|
||||
return !responseData.HasControlErrors();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
|
||||
namespace Sarand.BusinessMgr.Web.Portal.Models.Vehicles
|
||||
{
|
||||
//=======================================================================
|
||||
public partial class Model_VehicleClass : SbmModel_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public Model_VehicleClass(SbmLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Filter properties.
|
||||
public class FilterData
|
||||
{
|
||||
public string VehicleType { get; set; }
|
||||
public string Search { get; set; }
|
||||
public string StatusCat { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
public Sbm.VehicleType GetFilterVehicleType()
|
||||
{
|
||||
return (Sbm.VehicleType)Internals.VehicleTypeCodes.GetTypeForCode(Filter.VehicleType);
|
||||
}
|
||||
public SbmVehicleClass.StatusCat GetFilterStatusCat()
|
||||
{
|
||||
return EnumUtil.ParseEnum(Filter.StatusCat, SbmVehicleClass.StatusCat.NotDeleted);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Item properties.
|
||||
public class VehicleClassData
|
||||
{
|
||||
public string Exists { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string MakeCode { get; set; }
|
||||
public string Model { get; set; }
|
||||
public string Derivative { get; set; }
|
||||
public string DescBrief { get; set; }
|
||||
public string VehicleTypeCode { get; set; }
|
||||
public Sbm.VehicleType VehicleType { get; set; } = Sbm.VehicleType.Unknown;
|
||||
public string VehicleCategoryCode { get; set; }
|
||||
public string FuelTypeCode { get; set; }
|
||||
public Sbm.VehicleFuelType FuelType { get; set; } = Sbm.VehicleFuelType.Unknown;
|
||||
public string OdometerUnitsCode { get; set; }
|
||||
public Sbm.VehicleOdometerUnits OdometerUnits { get; set; } = Sbm.VehicleOdometerUnits.Unknown;
|
||||
public string Notes { get; set; }
|
||||
public string StatusCode { get; set; }
|
||||
public SaStatus GetStatus() { return SacsSystem.GetStatusForCode(StatusCode); }
|
||||
}
|
||||
public VehicleClassData VehicleClass { get; } = new VehicleClassData();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Validation.
|
||||
//-------------------------------------------------------------------
|
||||
// VehicleClass.
|
||||
public bool ValidateVehicleClassData(Sacs.Web.Components.SaController.AjaxResponse_Data responseData)
|
||||
{
|
||||
// Record disposable items as they are created so all can be disposed when needed.
|
||||
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
|
||||
{
|
||||
|
||||
// Make.
|
||||
if (VehicleClass.MakeCode != null)
|
||||
{
|
||||
string controlName = "VehicleClassMake";
|
||||
responseData.SetControlValue(controlName, VehicleClass.MakeCode);
|
||||
if (VehicleClass.MakeCode.IsBlank())
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
}
|
||||
|
||||
// Model.
|
||||
if (VehicleClass.Model != null)
|
||||
{
|
||||
string controlName = "VehicleClassModel";
|
||||
VehicleClass.Model = VehicleClass.Model.ToUpper();
|
||||
responseData.SetControlValue(controlName, VehicleClass.Model);
|
||||
if (VehicleClass.Model.IsBlank())
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (StringUtil.GetLength(VehicleClass.Model) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Model))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Model)]);
|
||||
}
|
||||
|
||||
// VehicleClass DescBrief.
|
||||
if (VehicleClass.DescBrief != null)
|
||||
{
|
||||
string controlName = "VehicleClassDescription";
|
||||
responseData.SetControlValue(controlName, VehicleClass.DescBrief);
|
||||
if (VehicleClass.DescBrief.IsBlank())
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (StringUtil.GetLength(VehicleClass.DescBrief) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_DescBrief))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_DescBrief)]);
|
||||
}
|
||||
|
||||
// Notes.
|
||||
if (VehicleClass.Notes != null)
|
||||
{
|
||||
string controlName = "VehicleClassNotes";
|
||||
responseData.SetControlValue(controlName, VehicleClass.Notes);
|
||||
if (StringUtil.GetLength(VehicleClass.Notes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Notes))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.SaVehicleClass_Notes)]);
|
||||
}
|
||||
|
||||
// VehicleClass status.
|
||||
if (VehicleClass.StatusCode != null)
|
||||
{
|
||||
string controlName = "VehicleClassStatus";
|
||||
if (VehicleClass.StatusCode.IsBlank())
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SbmVehicleClass.ValidStatuses.Contains(VehicleClass.GetStatus()))
|
||||
responseData.SetControlError(controlName, Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
}
|
||||
|
||||
return !responseData.HasControlErrors();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -52,7 +52,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\Assets\Asset\" />
|
||||
<Folder Include="Views\Assets\Vehicle\" />
|
||||
<Folder Include="Views\Transaction\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -2,207 +2,8 @@
|
||||
@model Model_AssetCategory
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Asset Category view. */
|
||||
ViewData["Title"] = "Asset Categories";
|
||||
Model.AdditionalFiles_JS.Add("js/sbm-asset-cat.js");
|
||||
}
|
||||
|
||||
<div class="sbm-panel AssetCategories fullheight">
|
||||
|
||||
<script type="text/javascript">
|
||||
sbm.dlg.title.createItem = '@(Localiser.GetJavascriptText("caption.asset.category.create"))';
|
||||
sbm.dlg.title.updateItem = '@(Localiser.GetJavascriptText("caption.asset.category.update"))';
|
||||
</script>
|
||||
|
||||
<div class="sbm-panel-data sbm-flex">
|
||||
|
||||
@* Filter form - wrap header to include paging controls. *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryFilter", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
|
||||
@* Header - Page caption, paging controls, actions. *@
|
||||
<div class="sbm-panel-header">
|
||||
<div class="row">
|
||||
<div class="fixed">
|
||||
<partial name="~/Views/Common/ResultsPaging.cshtml" />
|
||||
</div>
|
||||
<div class="col center"><div class="sbm-panel-caption">@Localiser["caption.asset.categories"]</div></div>
|
||||
<div class="fixed">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Filter Panel *@
|
||||
<div class="sbm-panel-filter">
|
||||
<div class="row pb4">
|
||||
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||
<div class="col-sm-7">
|
||||
@Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
@* Item list *@
|
||||
<div class="sbm-panel-item-table sbm-flex">
|
||||
<table class="sbm-item-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="pl-2">@Localiser["label.type"]</th>
|
||||
<th class="">@Localiser["label.code"]</th>
|
||||
<th class="">@Localiser["label.description"]</th>
|
||||
<th class="center">@Localiser["label.status"]</th>
|
||||
<th class="right" style="width:2%;"></th>
|
||||
</tr>
|
||||
<tr><td colspan="6"><div class="sbm-panel-messages"></div></td></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@* Element templates *@
|
||||
<div class="sbm-panel-item-template">
|
||||
|
||||
@* Filter Burger option template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu AssetCategoryFilter">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
|
||||
@* AssetCategory row template - table is ignored. *@
|
||||
<table class="">
|
||||
<tr class="sbm-row-item AssetCategory">
|
||||
<td><div class="AssetCategoryType pl-1"></div></td>
|
||||
<td><div class="AssetCategoryCode"></div></td>
|
||||
<td><div class="AssetCategoryDescription"></div></td>
|
||||
<td><div class="AssetCategoryStatusDesc center"></div></td>
|
||||
<td>
|
||||
<div class="right">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-light navbar-right sbm-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@* Item Burger option template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu AssetCategory">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryId", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.AssetCategory.Id, new { @id = "", @class = "AssetCategoryId" })
|
||||
}
|
||||
<div id="dlgAssetCategory" class="sbm-dialog">
|
||||
<div class="spacer2"></div>
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategory", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.AssetCategory.Exists, new { @id = "", @class = "AssetCategoryExists" })
|
||||
@Html.HiddenFor(model => model.AssetCategory.Id, new { @id = "", @class = "AssetCategoryId" })
|
||||
|
||||
@* Type *@
|
||||
<div class="sbm-form-control AssetCategoryType">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetCategoryType"><span>@Localiser["label.type"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
@Html.DropDownListFor(model => model.AssetCategory.TypeCode, Model.GetAssetTypeCodesForSelect(), Localiser["label.select"], new { @id = "ifAssetCategoryType", @class = "AssetCategoryType sbm-select" })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Contact Code *@
|
||||
<div class="sbm-form-control AssetCategoryCode">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetCategoryCode"><span>@Localiser["label.code"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.AssetCategory.Code, new { @id = "ifAssetCategoryCode", @class = "AssetCategoryCode sbm-input upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Code) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Description *@
|
||||
<div class="sbm-form-control AssetCategoryDescription">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetCategoryDescription"><span>@Localiser["label.description"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.AssetCategory.DescBrief, new { @id = "ifAssetCategoryDescription", @class = "AssetCategoryDescription sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Status *@
|
||||
<div class="sbm-form-control AssetCategoryStatus">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="cbAssetCategoryStatus"><span>@Localiser["label.status"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
<select id="cbAssetCategoryStatus" class="sbm-select AssetCategoryStatus" name="AssetCategory.StatusCode"></select>
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Notes *@
|
||||
<div class="sbm-form-control AssetCategoryNotes">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetCategoryNotes"><span>@Localiser["label.notes"]</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<div class="sbm-control">
|
||||
@Html.TextAreaFor(model => model.AssetCategory.Notes, new { @id = "ifAssetCategoryNotes", @class = "AssetCategoryNotes sbm-textarea", @rows = 3, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
<div class="spacer2"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<partial name="Panel-AssetCategoryMaintain.cshtml" />
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
@* View is decoupled from Asset Category model as it may be included in other views, eg. Assets. *@
|
||||
@model SbmModel_Portal
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Asset Category - Dialog panel */
|
||||
// Ensure view is only included once in page.
|
||||
if (!Model.RegisterView("Views/Assets/AssetCategory/Panel-AssetCategoryDialog")) return;
|
||||
}
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryId", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("AssetCategory.Id", "", new { @id = "", @class = "AssetCategoryId" })
|
||||
}
|
||||
<div id="dlgAssetCategory" class="sbm-dialog">
|
||||
<div class="spacer2"></div>
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategory", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("AssetCategory.Exists", "", new { @id = "", @class = "AssetCategoryExists sbm-input" })
|
||||
@Html.Hidden("AssetCategory.Id", "", new { @id = "", @class = "AssetCategoryId sbm-input" })
|
||||
|
||||
@* Type *@
|
||||
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Type)">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetCategoryType"><span>@Localiser["label.type"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
@Html.DropDownList("AssetCategory.TypeCode", Model.GetAssetTypeCodesForDropdown(), Localiser["label.select"], new { @id = "ifAssetCategoryType", @class = "AssetCategoryType sbm-select sbm-auto-val" })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Contact Code *@
|
||||
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Code)">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetCategoryCode"><span>@Localiser["label.code"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
@Html.TextBox("AssetCategory.Code", "", new { @id = "ifAssetCategoryCode", @class = "AssetCategoryCode sbm-input sbm-auto-val upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Code) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Caption *@
|
||||
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Caption)">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetCategoryCaption"><span>@Localiser["label.description"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
@Html.TextBox("AssetCategory.Caption", "", new { @id = "ifAssetCategoryCaption", @class = "AssetCategoryDescription sbm-input sbm-auto-val", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_DescBrief) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Status *@
|
||||
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Status)">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="cbAssetCategoryStatus"><span>@Localiser["label.status"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
<select id="cbAssetCategoryStatus" class="sbm-select AssetCategoryStatus sbm-auto-val" name="AssetCategory.StatusCode"></select>
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Notes *@
|
||||
<div class="sbm-form-control @Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Notes)">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetCategoryNotes"><span>@Localiser["label.notes"]</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<div class="sbm-control">
|
||||
@Html.TextArea("AssetCategory.Notes", "", new { @id = "ifAssetCategoryNotes", @class = "AssetCategoryNotes sbm-textarea sbm-auto-val", @rows = 3, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAssetCategory_Notes) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
<div class="spacer2"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,62 @@
|
||||
@* View is decoupled from Asset Category model as it may be included in other views, eg. Assets. *@
|
||||
@model SbmModel_Portal
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Asset Category - List panel */
|
||||
/* NB Can potentially appear more than once on a page. */
|
||||
}
|
||||
|
||||
@* Item list *@
|
||||
<div class="sbm-panel-item-table sbm-flex">
|
||||
<table class="sbm-item-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Type) width25pc pl-1">@Localiser["label.type"]</th>
|
||||
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Code) width10pc">@Localiser["label.code"]</th>
|
||||
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Caption) width25pc">@Localiser["label.description"]</th>
|
||||
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Notes) width25pc d-none d-md-table-cell">@Localiser["label.notes"]</th>
|
||||
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Status) width10pc center">@Localiser["label.status"]</th>
|
||||
<th class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Actions) width5pc"></th>
|
||||
</tr>
|
||||
<tr><td colspan="6"><div class="sbm-panel-messages"></div></td></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@* Element templates *@
|
||||
<div class="sbm-panel-item-template">
|
||||
|
||||
@* Filter Burger option template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu AssetCategoryFilter">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
|
||||
@* AssetCategory row template - table is ignored. *@
|
||||
<table class="">
|
||||
<tr class="sbm-row-item AssetCategory">
|
||||
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Type) pl-1"></td>
|
||||
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Code)"></td>
|
||||
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Caption)"></td>
|
||||
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Notes) d-none d-md-table-cell"></td>
|
||||
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Status) center"></td>
|
||||
<td class="@Model_AssetCategory.GetFieldName(Model_AssetCategory.ItemField.Actions)">
|
||||
<div class="right">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-light navbar-right sbm-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@* Item Burger option template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu AssetCategory">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
@* View is decoupled from Asset Category model as it may be included in other views, eg. Assets. *@
|
||||
@model SbmModel_Portal
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Asset Category - Maintain panel */
|
||||
// Ensure view is only included once in page.
|
||||
if (!Model.RegisterView("Views/Assets/AssetCategory/Panel-AssetCategoryMaintain")) return;
|
||||
Model.AdditionalFiles_JS.Add("js/sbm-asset-cat.js");
|
||||
}
|
||||
|
||||
<div class="sbm-panel AssetCategories fullheight">
|
||||
|
||||
<script type="text/javascript">
|
||||
sbm.dlg.title.createItem = '@(Localiser.GetJavascriptText("caption.asset.category.create"))';
|
||||
sbm.dlg.title.updateItem = '@(Localiser.GetJavascriptText("caption.asset.category.update"))';
|
||||
</script>
|
||||
|
||||
<div class="sbm-panel-data sbm-flex">
|
||||
|
||||
@* Filter form - wrap header to include paging controls. *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetCategoryFilter", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("Filter.Mode", Model_AssetCategory.ViewMode.Maintain, new { @id = "" })
|
||||
|
||||
@* Header - Page caption, paging controls, actions. *@
|
||||
<div class="sbm-panel-header">
|
||||
<div class="row">
|
||||
<div class="fixed">
|
||||
<partial name="~/Views/Common/ResultsPaging.cshtml" />
|
||||
</div>
|
||||
<div class="col center"><div class="sbm-panel-caption">@Localiser["caption.asset.categories"]</div></div>
|
||||
<div class="fixed">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Filter Panel *@
|
||||
<div class="sbm-panel-filter">
|
||||
<div class="row pb4">
|
||||
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||
<div class="col-sm-7">
|
||||
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch", @maxlength = "32" })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
<partial name="Panel-AssetCategoryList.cshtml" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<partial name="Panel-AssetCategoryDialog.cshtml" />
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
@* View is decoupled from Asset Category model as it may be included in other views, eg. Assets. *@
|
||||
@model SbmModel_Portal
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Asset Category - Select panel */
|
||||
// Ensure view is only included once in page.
|
||||
if (!Model.RegisterView("Views/Assets/AssetCategory/Panel-AssetCategorySelect")) return;
|
||||
Model.AdditionalFiles_JS.Add("js/sbm-asset-cat.js");
|
||||
}
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
<div id="dlgAssetCategorySelect" class="sbm-dialog sbm-flex sbm-no-padding" title="@Localiser["caption.contact.select"]">
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmAssetCategoryFilter sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("Filter.Mode", Model_AssetCategory.ViewMode.Search, new { @id = "" })
|
||||
|
||||
@* Filter Panel *@
|
||||
<div class="sbm-panel-filter">
|
||||
<div class="row">
|
||||
<div class="col-sm-4 row pb4">
|
||||
@* AssetCategory type *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-8 col-sm-8">
|
||||
@Html.DropDownList("Filter.AssetCategoryType", Model.GetAssetTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterAssetCategoryType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
@* AssetCategory filter - name etc. *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||
<div class="col-8 col-sm-8">
|
||||
@Html.TextBox("Filter.Search", "", new { @id = "", @class = "FilterSearch sbm-input", @maxlength = "32" })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<partial name="Panel-AssetCategoryList.cshtml" />
|
||||
|
||||
</div>
|
||||
@@ -20,7 +20,7 @@
|
||||
@* Filter form - wrap header to include paging controls. *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmAssociationFilter sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("Filter.Mode", Model_Association.AssociationViewMode.Maintain, new { @id = "" })
|
||||
@Html.Hidden("Filter.Mode", Model_Association.ViewMode.Maintain, new { @id = "" })
|
||||
|
||||
@* Header - Page caption, paging controls, actions. *@
|
||||
<div class="sbm-panel-header">
|
||||
@@ -48,7 +48,7 @@
|
||||
@* Association Category *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-7 col-sm-8">
|
||||
@Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterSelect(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" })
|
||||
@Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterDropdown(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmAssociationFilter sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("Filter.Mode", Model_Association.AssociationViewMode.Search, new { @id = "" })
|
||||
@Html.Hidden("Filter.Mode", Model_Association.ViewMode.Search, new { @id = "" })
|
||||
@Html.Hidden("Filter.OwnerId", "", new { @id = "", @class = "FilterOwnerId" })
|
||||
@Html.Hidden("Filter.TargetId", "", new { @id = "", @class = "FilterTargetId" })
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
@* Association type *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-8 col-sm-8">
|
||||
@Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterSelect(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" })
|
||||
@Html.DropDownList("Filter.AssociationType", Model.GetAssociationTypeCodesForFilterDropdown(), @Localiser["label.any"], new { @id = "", @class = "FilterAssociationType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@model SbmModel_Portal
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Commodity dialog panel */
|
||||
/* Commodity - Dialog panel */
|
||||
// Ensure view is only included once in page.
|
||||
if (!Model.RegisterView("Views/Commodity/Panel-CommodityDialog")) return;
|
||||
}
|
||||
@@ -35,7 +35,7 @@
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<div class="sbm-control">
|
||||
@Html.DropDownList("Commodity.Type", Model.GetCommodityTypeCodesForSelect(), Localiser["label.select"], new { @id = "cbCommodityType", @class = "CommodityType sbm-select" })
|
||||
@Html.DropDownList("Commodity.Type", Model.GetCommodityTypeCodesForDropdown(), Localiser["label.select"], new { @id = "cbCommodityType", @class = "CommodityType sbm-select" })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@model SbmModel_Portal
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Commodity list panel */
|
||||
/* Commodity - List panel */
|
||||
/* NB Can potentially appear more than once on a page. */
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@model SbmModel_Portal
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Commodity maintain panel */
|
||||
/* Commodity - Maintain panel */
|
||||
// Ensure view is only included once in page.
|
||||
if (!Model.RegisterView("Views/Commodity/Panel-CommodityMaintain")) return;
|
||||
Model.AdditionalFiles_JS.Add("js/sbm-commodity.js");
|
||||
@@ -18,7 +18,7 @@
|
||||
@* Filter form - wrap header to include paging controls. *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodityFilter", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("Filter.Mode", Model_Commodity.CommodityViewMode.Maintain, new { @id = "" })
|
||||
@Html.Hidden("Filter.Mode", Model_Commodity.ViewMode.Maintain, new { @id = "" })
|
||||
|
||||
@* Header - Page caption, paging controls, actions. *@
|
||||
<div class="sbm-panel-header">
|
||||
@@ -44,7 +44,7 @@
|
||||
@* Commodity Category *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-7 col-sm-8">
|
||||
@Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
|
||||
@Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@model SbmModel_Portal
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Commodity select panel */
|
||||
/* Commodity - Select panel */
|
||||
// Ensure view is only included once in page.
|
||||
if (!Model.RegisterView("Views/Commodity/Panel-CommoditySelect")) return;
|
||||
Model.AdditionalFiles_JS.Add("js/sbm-commodity.js");
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmCommodityFilter sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("Filter.Mode", Model_Commodity.CommodityViewMode.Search, new { @id = "" })
|
||||
@Html.Hidden("Filter.Mode", Model_Commodity.ViewMode.Search, new { @id = "" })
|
||||
|
||||
@* Filter Panel *@
|
||||
<div class="sbm-panel-filter">
|
||||
@@ -24,7 +24,7 @@
|
||||
@* Commodity type *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-8 col-sm-8">
|
||||
@Html.DropDownList("Filter.CommodityType", Model.GetAffiliateTypeCodesForFilterSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
|
||||
@Html.DropDownList("Filter.CommodityType", Model.GetCommodityTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
@* Filter form - wrap header to include paging controls. *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmContactFilter sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("Filter.Mode", Model_Contact.ContactViewMode.Maintain, new { @id = "" })
|
||||
@Html.Hidden("Filter.Mode", Model_Contact.ViewMode.Maintain, new { @id = "" })
|
||||
|
||||
@* Header - Page caption, paging controls, actions. *@
|
||||
<div class="sbm-panel-header">
|
||||
@@ -47,7 +47,7 @@
|
||||
@* Contact type *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-7 col-sm-8">
|
||||
@Html.DropDownList("Filter.ContactType", Model.GetAffiliateTypeCodesForFilterSelect(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" })
|
||||
@Html.DropDownList("Filter.ContactType", Model.GetAffiliateTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "", @class = "frmContactFilter sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.Hidden("Filter.Mode", Model_Contact.ContactViewMode.Search, new { @id = "" })
|
||||
@Html.Hidden("Filter.Mode", Model_Contact.ViewMode.Search, new { @id = "" })
|
||||
|
||||
@* Filter Panel *@
|
||||
<div class="sbm-panel-filter">
|
||||
@@ -24,7 +24,7 @@
|
||||
@* Contact type *@
|
||||
<div class="col-4 col-sm-4 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-8 col-sm-8">
|
||||
@Html.DropDownList("Filter.ContactType", Model.GetAffiliateTypeCodesForFilterSelect(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" })
|
||||
@Html.DropDownList("Filter.ContactType", Model.GetAffiliateTypeCodesForFilterDropdown(), Localiser["label.any"], new { @id = "", @class = "FilterContactType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 row pb4">
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" />
|
||||
</environment>
|
||||
<link rel="stylesheet" href="~/css/sbm-base.css?@Model.HrefVersion" />
|
||||
<link rel="stylesheet" href="~/css/sbm-cols.css?@Model.HrefVersion" />
|
||||
<link rel="stylesheet" href="~/css/sbm-main.css?@Model.HrefVersion" />
|
||||
<link rel="stylesheet" href="~/css/sbm-form.css?@Model.HrefVersion" />
|
||||
<link rel="stylesheet" href="~/css/sbm-data.css?@Model.HrefVersion" />
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
@* Assets - Asset *@
|
||||
@model Model_Asset
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
ViewData["Title"] = "Assets";
|
||||
Model.AdditionalFiles_JS.Add("js/sbm-asset.js");
|
||||
}
|
||||
|
||||
<div class="sbm-panel Assets fullheight">
|
||||
|
||||
<script type="text/javascript">
|
||||
sbm.dlg.title.createItem = '@(Localiser.GetJavascriptText("caption.asset.create"))';
|
||||
sbm.dlg.title.updateItem = '@(Localiser.GetJavascriptText("caption.asset.update"))';
|
||||
sbm.lbl.selectCategory = '@(Localiser.GetJavascriptText("caption.category.select"))';
|
||||
</script>
|
||||
|
||||
<div class="sbm-panel-data sbm-flex">
|
||||
|
||||
@* Filter form - wrap header to include paging controls. *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetFilter", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
|
||||
<div class="sbm-panel-header">
|
||||
<div class="row">
|
||||
<div class="fixed">
|
||||
<partial name="~/Views/Common/ResultsPaging.cshtml" />
|
||||
</div>
|
||||
<div class="col center"><div class="sbm-panel-caption">@Localiser["label.assets"]</div></div>
|
||||
<div class="fixed">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-dark navbar-right sbm-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="navbar-toggler-icon"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Filter Panel *@
|
||||
<div class="sbm-panel-filter">
|
||||
<div class="row pb4">
|
||||
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.search"]</div>
|
||||
<div class="col-sm-7">
|
||||
@Html.TextBoxFor(model => model.Filter.Search, new { @id = "", @class = "FilterSearch", @maxlength = "32" })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
<div class="sbm-panel-item-table sbm-flex">
|
||||
<table class="sbm-item-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="pl-2">@Localiser["label.category"]</th>
|
||||
<th class="">@Localiser["label.serial"]</th>
|
||||
<th class="">@Localiser["label.description"]</th>
|
||||
<th class="center">@Localiser["label.status"]</th>
|
||||
<th class="right" style="width:2%;"></th>
|
||||
</tr>
|
||||
<tr><td colspan="6"><div class="sbm-panel-messages"></div></td></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@* Element templates *@
|
||||
<div class="sbm-panel-item-template">
|
||||
@* Filter Burger option template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu AssetFilter">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
@* Asset row template - table is ignored. *@
|
||||
<table class="">
|
||||
<tr class="sbm-row-item Asset">
|
||||
<td><div class="AssetCategory pl-1"></div></td>
|
||||
<td><div class="AssetSerial"></div></td>
|
||||
<td><div class="AssetDescription"></div></td>
|
||||
<td><div class="AssetStatusDesc center"></div></td>
|
||||
<td>
|
||||
<div class="right">
|
||||
@* Burger menu *@
|
||||
<ul class="nav navbar-nav navbar-light navbar-right sbm-burger">
|
||||
<li class="dropdown-toggle caret-off">
|
||||
<a href="#" class="dropdown" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span><span class="sbm-ellipsis-dot"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right sbm-dropdown-menu">@* Menu items will be inserted here. *@</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@* Item Burger option template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu Asset">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAssetId", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.Asset.Id, new { @id = "", @class = "AssetId" })
|
||||
}
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCategories", @onSubmit = "return false;" }))
|
||||
{
|
||||
}
|
||||
<div id="dlgAsset" class="sbm-dialog">
|
||||
<div class="spacer2"></div>
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmAsset", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.Asset.Exists, new { @id = "", @class = "AssetExists" })
|
||||
@Html.HiddenFor(model => model.Asset.Id, new { @id = "", @class = "AssetId" })
|
||||
|
||||
@* Type *@
|
||||
<div class="sbm-form-control AssetCategory">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for=""><span>@Localiser["label.category"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control row">
|
||||
<div class="col">
|
||||
@Html.HiddenFor(model => model.Asset.CategoryId, new { @id = "", @class = "AssetCategoryId" })
|
||||
<input type="text" class="AssetCategory sbm-input" readonly="readonly" />
|
||||
</div>
|
||||
<div class="fixed">
|
||||
<div class="sbm-action AssetCategorySearch"><img src="~/img/action/search24.png" alt="" title="" /></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Serial Number*@
|
||||
<div class="sbm-form-control AssetSerialNumber">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetSerialNumber"><span>@Localiser["label.serial"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.Asset.SerialNumber, new { @id = "ifAssetSerialNumber", @class = "AssetSerialNumber sbm-input upper", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAsset_SerialNumber) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Description *@
|
||||
<div class="sbm-form-control AssetDescription">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetDescription"><span>@Localiser["label.description"]</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.Asset.DescBrief, new { @id = "ifAssetDescription", @class = "AssetDescription sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAsset_DescBrief) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Status *@
|
||||
<div class="sbm-form-control AssetStatus">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="cbAssetStatus"><span>@Localiser["label.status"]</span><span class="required"> *</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="sbm-control">
|
||||
<select id="cbAssetStatus" class="sbm-select AssetStatus" name="Asset.StatusCode"></select>
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Notes *@
|
||||
<div class="sbm-form-control AssetNotes">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="sbm-label">
|
||||
<label for="ifAssetNotes"><span>@Localiser["label.notes"]</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<div class="sbm-control">
|
||||
@Html.TextAreaFor(model => model.Asset.Notes, new { @id = "ifAssetNotes", @class = "AssetNotes sbm-textarea", @rows = 3, @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.SaAsset_Notes) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
<div class="spacer2"></div>
|
||||
</div>
|
||||
|
||||
@* Select Item dialog and script *@
|
||||
<partial name="~/Views/Common/SelectItem.cshtml" />
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -4,6 +4,7 @@
|
||||
@using Sarand.BusinessMgr.Web.Portal.Models.Contacts
|
||||
@using Sarand.BusinessMgr.Web.Portal.Models.Commodities
|
||||
@using Sarand.BusinessMgr.Web.Portal.Models.Assets
|
||||
@using Sarand.BusinessMgr.Web.Portal.Models.Vehicles
|
||||
@using Sarand.BusinessMgr.Web.Portal.Models.Codes
|
||||
@using Sarand.Net.Standard.Base.CodeTypes
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
@@ -2,25 +2,6 @@
|
||||
BusMgr Portal - Base stylesheet.
|
||||
*/
|
||||
|
||||
:root
|
||||
{
|
||||
--color-OldGold: #d4af37;
|
||||
--color-MintGreen: #98fb98;
|
||||
--color-LimeGreen: #32cd32;
|
||||
--color-KellyGreen: #4cbb17;
|
||||
--color-OliveGreen: #808000;
|
||||
--color-ForestGreen: #228b22;
|
||||
--color-CornflowerBlue: #6495ed;
|
||||
--color-RoyalBlue: #4169e1;
|
||||
--color-NavyBlue: #000080;
|
||||
--color-DarkBlue: #00008B;
|
||||
--color-Indigo: #4b0082;
|
||||
--color-Iris: #5d3fd3;
|
||||
--color-Burgundy: #800020;
|
||||
--color-BrightPurple: #bf40bf;
|
||||
--color-DarkPink: #aa336a;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin: 0;
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
BusMgr Portal - Colours stylesheet.
|
||||
*/
|
||||
|
||||
:root
|
||||
{
|
||||
--color-primary: #4b0082;
|
||||
--color-light: #9b71b9;
|
||||
--color-pale: #ebe2f1;
|
||||
--color-OldGold: #d4af37;
|
||||
--color-MintGreen: #98fb98;
|
||||
--color-LimeGreen: #32cd32;
|
||||
--color-KellyGreen: #4cbb17;
|
||||
--color-OliveGreen: #808000;
|
||||
--color-ForestGreen: #228b22;
|
||||
--color-CornflowerBlue: #6495ed;
|
||||
--color-RoyalBlue: #4169e1;
|
||||
--color-NavyBlue: #000080;
|
||||
--color-DarkBlue: #00008B;
|
||||
--color-Indigo: #4b0082;
|
||||
--color-Iris: #5d3fd3;
|
||||
--color-Burgundy: #800020;
|
||||
--color-BrightPurple: #bf40bf;
|
||||
--color-DarkPink: #aa336a;
|
||||
}
|
||||
|
||||
/* Data panel */
|
||||
|
||||
:root
|
||||
{
|
||||
--color-panel-data: var(--color-OliveGreen);
|
||||
}
|
||||
|
||||
.Contacts .sbm-panel-data
|
||||
{
|
||||
--color-panel-data: var(--color-ForestGreen);
|
||||
}
|
||||
|
||||
.Associations .sbm-panel-data
|
||||
{
|
||||
--color-panel-data: var(--color-Iris);
|
||||
}
|
||||
|
||||
.Commodities .sbm-panel-data
|
||||
{
|
||||
--color-panel-data: var(--color-Burgundy);
|
||||
}
|
||||
|
||||
.AssetCategories .sbm-panel-data, .Assets .sbm-panel-data
|
||||
{
|
||||
--color-panel-data: var(--color-BrightPurple);
|
||||
}
|
||||
|
||||
.VehicleClasses .sbm-panel-data, .Vehicles .sbm-panel-data
|
||||
{
|
||||
--color-panel-data: var(--color-Iris);
|
||||
}
|
||||
|
||||
/* Dialogs */
|
||||
|
||||
:root
|
||||
{
|
||||
--color-dialog: var(--color-OldGold);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-dark-blue
|
||||
{
|
||||
--color-dialog: var(--color-DarkBlue);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-Contact
|
||||
{
|
||||
--color-dialog: var(--color-ForestGreen);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-Association
|
||||
{
|
||||
--color-dialog: var(--color-Iris);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-Commodity
|
||||
{
|
||||
--color-dialog: var(--color-Burgundy);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-AssetCategory, .ui-dialog.sbm-Asset
|
||||
{
|
||||
--color-dialog: var(--color-BrightPurple);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-VehicleClass, .ui-dialog.sbm-Vehicle
|
||||
{
|
||||
--color-dialog: var(--color-Iris);
|
||||
}
|
||||
|
||||
/* The End */
|
||||
@@ -4,26 +4,6 @@
|
||||
|
||||
/* Data panel */
|
||||
|
||||
:root
|
||||
{
|
||||
--color-panel-data: var(--color-OliveGreen);
|
||||
}
|
||||
|
||||
.Contacts .sbm-panel-data
|
||||
{
|
||||
--color-panel-data: var(--color-ForestGreen);
|
||||
}
|
||||
|
||||
.Associations .sbm-panel-data
|
||||
{
|
||||
--color-panel-data: var(--color-Iris);
|
||||
}
|
||||
|
||||
.Commodities .sbm-panel-data
|
||||
{
|
||||
--color-panel-data: var(--color-Burgundy);
|
||||
}
|
||||
|
||||
.sbm-panel-data
|
||||
{
|
||||
margin: 0 auto;
|
||||
|
||||
@@ -2,17 +2,6 @@
|
||||
BusMgr Portal - Main stylesheet.
|
||||
*/
|
||||
|
||||
/* Global variables */
|
||||
|
||||
:root
|
||||
{
|
||||
/* Colour analysis: https://www.colorhexa.com/ */
|
||||
/* #4b0082 - Indigo. Ref. https://www.crispedge.com/color/4b0082 */
|
||||
--color-primary: #4b0082;
|
||||
--color-light: #9b71b9;
|
||||
--color-pale: #ebe2f1;
|
||||
}
|
||||
|
||||
/* Document */
|
||||
|
||||
html
|
||||
@@ -332,31 +321,6 @@ a:focus
|
||||
|
||||
/* Dialogs */
|
||||
|
||||
:root
|
||||
{
|
||||
--color-dialog: var(--color-OldGold);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-dark-blue
|
||||
{
|
||||
--color-dialog: var(--color-DarkBlue);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-Contact
|
||||
{
|
||||
--color-dialog: var(--color-ForestGreen);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-Association
|
||||
{
|
||||
--color-dialog: var(--color-Iris);
|
||||
}
|
||||
|
||||
.ui-dialog.sbm-Commodity
|
||||
{
|
||||
--color-dialog: var(--color-Burgundy);
|
||||
}
|
||||
|
||||
.sbm-dialog
|
||||
{
|
||||
display: none;
|
||||
|
||||
@@ -6,99 +6,125 @@
|
||||
(function (win, doc, undef)
|
||||
{
|
||||
"use strict";
|
||||
let ac = sbm.AssetCat = { data: {}, ajax: {} };
|
||||
let $pnl = ac.$pnl = {}, $frm = ac.$frm = {}, $dlg = ac.$dlg = {};
|
||||
let ac = sbm.AssetCats = { env: {} };
|
||||
|
||||
//--------------------------------------------------------------
|
||||
ac.refreshResults = function (delay)
|
||||
ac.refreshConfig = function (env, delay)
|
||||
{
|
||||
env.ajax.refreshConfig = env.ajax.refreshConfig || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/Config', formSel: env.$frm.filter, callbackFn: function (response) { ac.doRefreshConfig(env, response); } };
|
||||
sbm.doAjaxRequest(env.ajax.refreshConfig, delay || 50);
|
||||
}
|
||||
ac.doRefreshConfig = function (env, response)
|
||||
{
|
||||
//sbm.debug('doRefreshConfig', env, response);
|
||||
if (!response.success) return;
|
||||
// Config.
|
||||
env.mode = response.mode;
|
||||
env.config = response.config;
|
||||
env.configItemNew = response.configItemNew;
|
||||
env.data.assetTypes = response.assetTypes;
|
||||
env.data.statuses = response.statuses;
|
||||
env.data.statusesCreate = response.statusesCreate;
|
||||
env.data.statusCodeDefault = response.statusCodeDefault;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
ac.refreshResults = function (env, delay)
|
||||
{
|
||||
if (!ac.awaitingRefreshResponse)
|
||||
{
|
||||
$pnl.bgr.invisible();
|
||||
$pnl.table.find('tbody tr').remove();
|
||||
$pnl.msgs.hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
env.$pnl.bgr.invisible();
|
||||
env.$pnl.table.find('tbody tr').remove();
|
||||
env.$pnl.msgs.hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
ac.ajax.assetCategories = ac.ajax.assetCategories || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/GetAssetCategories', formId: $frm.filter.prop('id'), callbackFn: ac.handleAssetCategories };
|
||||
sbm.doAjaxRequest(ac.ajax.assetCategories, delay || 50);
|
||||
env.ajax.assetCategories = env.ajax.assetCategories || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/GetAssetCategories', formSel: env.$frm.filter, callbackFn: function (response) { ac.doRefreshResults(env, response); } };
|
||||
sbm.doAjaxRequest(env.ajax.assetCategories, delay || 50);
|
||||
ac.awaitingRefreshResponse = true;
|
||||
}
|
||||
ac.handleAssetCategories = function (response)
|
||||
ac.doRefreshResults = function (env, response)
|
||||
{
|
||||
//sbm.debug('handleAssetCategories', response);
|
||||
//sbm.debug('doRefreshResults', response);
|
||||
delete ac.awaitingRefreshResponse;
|
||||
let $table = $('table', $pnl.table).find('tbody tr').remove().end();
|
||||
$pnl.msgs.hide().empty();
|
||||
sbm.refreshPaging(response, '#frmAssetCategoryFilter', ac.refreshResults);
|
||||
env.$pnl.msgs.hide().empty();
|
||||
let $table = $('table', env.$pnl.table).find('tbody tr').remove().end();
|
||||
sbm.refreshPaging(response, env.$frm.filter, function () { ac.refreshResults(env); });
|
||||
if (!response.success) return;
|
||||
|
||||
// Reference data.
|
||||
if (response.statuses) sbm.data.statuses = response.statuses;
|
||||
if (response.statusesCreate) sbm.data.statusesCreate = response.statusesCreate;
|
||||
if (response.statusCodeDefault) sbm.data.statusCodeDefault = response.statusCodeDefault;
|
||||
ac.doRefreshConfig(env, response);
|
||||
|
||||
// Menu.
|
||||
$pnl.bgr.invisible();
|
||||
$pnl.mnu.empty();
|
||||
$pnl.mnu.append(ac.getFilterMenuOption(sbm.lbl.refresh, function () { ac.refreshResults(); }, 'sbm-refresh'));
|
||||
$pnl.mnu.append(ac.getFilterMenuOption(sbm.lbl.create, function () { ac.createItem(); }, 'sbm-add'));
|
||||
$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', $pnl.mnu).length);
|
||||
if (env.$pnl.bgr.length)
|
||||
{
|
||||
env.$pnl.bgr.invisible();
|
||||
env.$pnl.mnu.empty();
|
||||
env.$pnl.mnu.append(ac.getFilterMenuOption(env, sbm.lbl.refresh, function () { ac.refreshResults(env); }, 'sbm-refresh'));
|
||||
env.$pnl.mnu.append(ac.getFilterMenuOption(env, sbm.lbl.create, function () { ac.createItem(env, env.configItemNew); }, 'sbm-add'));
|
||||
env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length);
|
||||
}
|
||||
|
||||
// Items.
|
||||
var items = response.assetCategories || [];
|
||||
if (!items.length)
|
||||
return $pnl.msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
|
||||
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
|
||||
$table.append(ac.populateItem(ac.getItemTemplate(), items[itemIdx]));
|
||||
return env.$pnl.msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
|
||||
for (const item of items)
|
||||
$table.append(env, ac.populateItem(env, ac.getItemTemplate(env), item));
|
||||
}
|
||||
ac.populateItem = function ($item, item)
|
||||
ac.populateItem = function (env, $item, item)
|
||||
{
|
||||
//sbm.debug('populateItem', env, $item, item)
|
||||
if (!item) return $item;
|
||||
$pnl.msgs.hide().empty();
|
||||
$item.prop('id', ac.getItemId(item));
|
||||
$('.AssetCategoryType', $item).text(item.typeDesc);
|
||||
$('.AssetCategoryCode', $item).text(item.code);
|
||||
$('.AssetCategoryDescription', $item).text(item.descBrief);
|
||||
$('.AssetCategoryStatusDesc', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase());
|
||||
// Actions.
|
||||
let fnUpd = function () { ac.updateItem($item, item) };
|
||||
var $bgr = $('.sbm-burger', $item).invisible();
|
||||
let $mnu = $('ul.sbm-dropdown-menu', $bgr).empty();
|
||||
if (!item.deleted)
|
||||
let cfg = env.config;
|
||||
if (cfg) sbm.populateItemValues(cfg, $item, item.field.value);
|
||||
let prefix = cfg.column.prefix;
|
||||
$('.' + prefix + 'Status', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase());
|
||||
if (!env.mode.search)
|
||||
{
|
||||
$mnu.append(ac.getItemMenuOption(sbm.lbl.edit, fnUpd, 'sbm-edit'));
|
||||
$('.AssetCategoryCode', $item).off('click').on('click', fnUpd).addClass('sbm-action-text');
|
||||
$item.off('dblclick').on('dblclick', fnUpd);
|
||||
// Actions.
|
||||
let fnUpd = function () { ac.updateItem(env, item.id) };
|
||||
var $bgr = $('.sbm-burger', $item).invisible();
|
||||
let $mnu = $('ul.sbm-dropdown-menu', $bgr).empty();
|
||||
if (!item.deleted)
|
||||
{
|
||||
$mnu.append(ac.getItemMenuOption(env, sbm.lbl.edit, fnUpd, 'sbm-edit'));
|
||||
$('.' + prefix + 'Code', $item).off('click').on('click', fnUpd).addClass('sbm-action-text');
|
||||
$item.off('dblclick').on('dblclick', fnUpd);
|
||||
}
|
||||
$bgr.toggleVisibility(!!$('.sbm-dropdown-item', $mnu).length);
|
||||
}
|
||||
else
|
||||
{
|
||||
$item.off('click').on('click', function () { ac.selectItemRow(env, $item, item); });
|
||||
$item.off('dblclick').on('dblclick', function () { ac.selectItem(env); });
|
||||
}
|
||||
$bgr.toggleVisibility(!!$('.sbm-dropdown-item', $mnu).length);
|
||||
return $item;
|
||||
}
|
||||
ac.getItemId = function (item)
|
||||
{
|
||||
return 'Itm_' + (item || {}).id;
|
||||
return 'Act_' + (item || {}).id;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
ac.getFilterDropdownTemplate = function ()
|
||||
ac.getFilterDropdownTemplate = function (env)
|
||||
{
|
||||
return $('.sbm-dropdown-menu.AssetCategoryFilter li.sbm-dropdown-item', $pnl.tmpls).clone();
|
||||
return $('.sbm-dropdown-menu.AssetCategoryFilter li.sbm-dropdown-item', env.$pnl.tmpls).clone();
|
||||
}
|
||||
ac.getItemTemplate = function ()
|
||||
ac.getItemTemplate = function (env)
|
||||
{
|
||||
return $('table tr.sbm-row-item.AssetCategory', $pnl.tmpls).clone();
|
||||
return $('table tr.sbm-row-item.AssetCategory', env.$pnl.tmpls).clone();
|
||||
}
|
||||
ac.getItemDropdownTemplate = function ()
|
||||
ac.getItemDropdownTemplate = function (env)
|
||||
{
|
||||
return $('.sbm-dropdown-menu.AssetCategory li.sbm-dropdown-item', $pnl.tmpls).clone();
|
||||
return $('.sbm-dropdown-menu.AssetCategory li.sbm-dropdown-item', env.$pnl.tmpls).clone();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
ac.getFilterMenuOption = function (lbl, fn, cls)
|
||||
ac.getFilterMenuOption = function (env, lbl, fn, cls)
|
||||
{
|
||||
return ac.getMenuOption(ac.getFilterDropdownTemplate(), lbl, fn, cls);
|
||||
return ac.getMenuOption(ac.getFilterDropdownTemplate(env), lbl, fn, cls);
|
||||
}
|
||||
ac.getItemMenuOption = function (lbl, fn, cls)
|
||||
ac.getItemMenuOption = function (env, lbl, fn, cls)
|
||||
{
|
||||
return ac.getMenuOption(ac.getItemDropdownTemplate(), lbl, fn, cls);
|
||||
return ac.getMenuOption(ac.getItemDropdownTemplate(env), lbl, fn, cls);
|
||||
}
|
||||
ac.getMenuOption = function ($opt, lbl, fn, cls)
|
||||
{
|
||||
@@ -106,101 +132,169 @@
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
ac.createItem = function ()
|
||||
ac.createItem = function (env, cfg)
|
||||
{
|
||||
ac.clearItem();
|
||||
sbm.populateSelectCodeDesc('#cbAssetCategoryStatus', sbm.data.statusesCreate);
|
||||
$('#cbAssetCategoryStatus').val(sbm.data.statusCodeDefault).prop('readonly', false);
|
||||
$dlg.item.dialog('option', 'title', sbm.dlg.title.createItem);
|
||||
ac.openAssetCategoryDlg();
|
||||
sbm.debug('createItem', env, cfg);
|
||||
ac.clearItem(env, cfg);
|
||||
let $frm = env.$frm.item;
|
||||
sbm.populateSelectCodeDesc('#cbAssetCategoryStatus', env.data.statusesCreate);
|
||||
$('#cbAssetCategoryStatus').val(env.data.statusCodeDefault).prop('readonly', false);
|
||||
ac.openItemDlg(env, cfg, sbm.dlg.title.createItem);
|
||||
}
|
||||
ac.openAssetCategoryDlg = function ()
|
||||
ac.clearItem = function (env, cfg)
|
||||
{
|
||||
sbm.openDialog($dlg.item, 600, 600);
|
||||
sbm.clearItemForm(env.$frm.item);
|
||||
sbm.populateSelectCodeDesc('#cbAssetCategoryStatus', env.data.statuses);
|
||||
}
|
||||
ac.clearItem = function ()
|
||||
ac.openItemDlg = function (env, cfg, title)
|
||||
{
|
||||
let frm = $frm.item;
|
||||
$('.AssetCategoryExists,.AssetCategoryId,input[type="text"],textarea,select', frm).val('');
|
||||
sbm.populateSelectCodeDesc('#cbAssetCategoryStatus', sbm.data.statuses);
|
||||
$('.AssetCategoryType,.AssetCategoryStatus', frm).prop('disabled', false);
|
||||
sbm.clearControlErrors();
|
||||
let $dlg = env.$dlg.item;
|
||||
let $frm = env.$frm.item;
|
||||
sbm.configureItemControls(cfg, $frm);
|
||||
var btns = {};
|
||||
btns[sbm.lbl.ok] = function () { ac.storeItem(env); };
|
||||
btns[sbm.lbl.cancel] = function () { delete env.prmEdit; $(this).dialog('close'); };
|
||||
$dlg.dialog('option', 'buttons', btns);
|
||||
if (title) $dlg.dialog('option', 'title', title);
|
||||
sbm.openDialog($dlg, 600, 600);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
ac.updateItem = function ($item, item)
|
||||
ac.updateItem = function (env, id)
|
||||
{
|
||||
ac.clearItem();
|
||||
$('.AssetCategoryId', $frm.itemId).val(item.id);
|
||||
sbm.ajax.updateItem = sbm.ajax.updateItem || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/GetItem', formId: $frm.itemId.prop('id'), callbackFn: ac.onUpdateItem };
|
||||
sbm.doAjaxRequest(sbm.ajax.updateItem, 50);
|
||||
let $frm = env.$frm.itemId;
|
||||
$('.AssetCategoryId', $frm).val(id);
|
||||
env.ajax.updateItem = env.ajax.updateItem || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/GetItem', formSel: $frm, callbackFn: function (response) { ac.onUpdateItem(env, response); } };
|
||||
sbm.doAjaxRequest(env.ajax.updateItem, 50);
|
||||
}
|
||||
ac.onUpdateItem = function (response)
|
||||
ac.onUpdateItem = function (env, response)
|
||||
{
|
||||
//sbm.debug('onUpdateItem', response);
|
||||
let frm = $frm.item;
|
||||
ac.clearItem();
|
||||
if (!response.success) return;
|
||||
let cfg = response.config || {};
|
||||
ac.clearItem(env, cfg);
|
||||
let item = response.assetCategory;
|
||||
$('.AssetCategoryExists', frm).val(1);
|
||||
$('.AssetCategoryId', frm).val(item.id);
|
||||
$('.AssetCategoryType', frm).val(item.typeCode).prop('disabled', true);
|
||||
$('.AssetCategoryCode', frm).val(item.code);
|
||||
$('.AssetCategoryDescription', frm).val(item.descBrief);
|
||||
$('.AssetCategoryNotes', frm).val(item.notes);
|
||||
$('.AssetCategoryStatus', frm).val(item.statusCode).prop('disabled', true);
|
||||
sbm.clearControlErrors();
|
||||
$dlg.item.dialog('option', 'title', sbm.dlg.title.updateItem);
|
||||
ac.openAssetCategoryDlg();
|
||||
let $frm = env.$frm.item;
|
||||
sbm.populateFormValues(cfg, $frm, item.field.value);
|
||||
let $ctrls = $('.sbm-input,.sbm-textarea,.sbm-select', $frm);
|
||||
$ctrls.filter('.AssetCategoryId').val(item.id);
|
||||
$ctrls.filter('.AssetCategoryExists').val(1);
|
||||
sbm.selectOrAdd($ctrls.filter('.AssetCategoryType'), item.typeCode, item.typeDesc);
|
||||
sbm.selectOrAdd($ctrls.filter('.AssetCategoryStatus'), item.statusCode, item.field.value.Status);
|
||||
ac.openItemDlg(env, cfg, sbm.dlg.title.updateItem);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
ac.storeItem = function ()
|
||||
ac.storeItem = function (env)
|
||||
{
|
||||
sbm.ajax.storeItem = sbm.ajax.storeItem || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/StoreItem', formId: 'frmAssetCategory', callbackFn: ac.onStoreItem };
|
||||
sbm.doAjaxRequest(sbm.ajax.storeItem, 50);
|
||||
env.ajax.storeItem = env.ajax.storeItem || { url: sbm.url.base + 'Assets/AssetCategory/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { ac.onStoreItem(env, response); } };
|
||||
sbm.doAjaxRequest(env.ajax.storeItem, 50);
|
||||
}
|
||||
ac.onStoreItem = function (response)
|
||||
ac.onStoreItem = function (env, response)
|
||||
{
|
||||
//sbm.debug('onStoreItem', response);
|
||||
sbm.refreshControlValues(response.controlValues);
|
||||
if (!response.success) return;
|
||||
$dlg.item.dialog('close');
|
||||
|
||||
env.$dlg.item.dialog('close');
|
||||
var item = response.assetCategory;
|
||||
var $item = $('#' + ac.getItemId(item), $pnl.table);
|
||||
if (!$item.length)
|
||||
if (env.prmEdit)
|
||||
{
|
||||
$item = ac.getItemTemplate();
|
||||
$('table tbody', $pnl.table).prepend($item).show();
|
||||
ac.onItemEdited(env, item);
|
||||
}
|
||||
ac.populateItem($item, item);
|
||||
else if (env.$pnl.table.length)
|
||||
{
|
||||
env.$pnl.msgs.hide().empty();
|
||||
var $item = $('#' + ac.getItemId(item), env.$pnl.table);
|
||||
if (!$item.length)
|
||||
{
|
||||
$item = ac.getItemTemplate();
|
||||
$('table tbody', env.$pnl.table).prepend($item).show();
|
||||
}
|
||||
}
|
||||
ac.populateItem(env, $item, item);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/* Params: type, search, fnSuccess. */
|
||||
sbm.fn.selectAssetCategory = function (prm)
|
||||
{
|
||||
//sbm.debug('selectAssetCategory', prm);
|
||||
let env = ac.env.select;
|
||||
env.prmSelect = prm;
|
||||
env.$frm.filter.find('.FilterAssetCategoryType').val('');
|
||||
env.$frm.filter.find('.FilterSearch').val(prm.search || '');
|
||||
env.$pnl.table.find('tbody tr').remove();
|
||||
sbm.openDialog(env.$dlg.select, 1000, 800);
|
||||
if (env.$pnl.items.length) setTimeout(function () { ac.refreshResults(env); }, 250);
|
||||
}
|
||||
ac.selectItemRow = function (env, $item, item)
|
||||
{
|
||||
//sbm.debug('selectItemRow', env, $item, item);
|
||||
env.$pnl.table.find('tr').removeClass('sbm-sel');
|
||||
$item.addClass('sbm-sel');
|
||||
env.prmSelect.item = item;
|
||||
}
|
||||
ac.selectItem = function (env)
|
||||
{
|
||||
//sbm.debug('selectItem', env, env.prmSelect.item);
|
||||
env.$dlg.select.dialog('close');
|
||||
env.prmSelect.fnSuccess(env.prmSelect.item);
|
||||
delete env.prmSelect;
|
||||
}
|
||||
|
||||
/* Params: id, fnSuccess. */
|
||||
sbm.fn.editAssetCategory = function (prm)
|
||||
{
|
||||
//sbm.debug('editAssetCategory', prm);
|
||||
let env = ac.env.select;
|
||||
env.prmEdit = prm;
|
||||
sbm.debug(env, prm);
|
||||
ac.updateItem(env, prm.id);
|
||||
}
|
||||
ac.onItemEdited = function (env, item)
|
||||
{
|
||||
//sbm.debug('ac.onItemEdited', env, item);
|
||||
env.prmEdit.fnSuccess(item);
|
||||
delete env.prmEdit;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
ac.initEnv = function ($pnlItems)
|
||||
{
|
||||
let env = { data: {}, ajax: {}, $pnl: {}, $frm: {}, $ctrl: {}, $dlg: {} };
|
||||
|
||||
env.$pnl.items = $($pnlItems);
|
||||
env.$pnl.header = env.$pnl.items.find('.sbm-panel-header');
|
||||
env.$pnl.bgr = env.$pnl.header.find('.sbm-burger');
|
||||
env.$pnl.mnu = env.$pnl.bgr.find('ul.sbm-dropdown-menu');
|
||||
env.$pnl.table = env.$pnl.items.find('.sbm-panel-item-table');
|
||||
env.$pnl.msgs = env.$pnl.table.find('.sbm-panel-messages');
|
||||
env.$pnl.tmpls = env.$pnl.items.find('.sbm-panel-item-template');
|
||||
|
||||
env.$frm.filter = $('#frmAssetCategoryFilter').on('input', '.FilterSearch', function () { ac.refreshResults(250); });
|
||||
|
||||
env.$frm.itemId = $('#frmAssetCategoryId');
|
||||
var opt = sbm.dlgOpts();
|
||||
opt.dialogClass += " sbm-AssetCategory";
|
||||
env.$dlg.item = $('#dlgAssetCategory').dialog(opt);
|
||||
env.$frm.item = $('#frmAssetCategory').on('input', '.sbm-input, .sbm-textarea', function () { sbm.clearControlError(this); }).on('change', '.sbm-select', function () { sbm.clearControlError(this); });
|
||||
|
||||
var opt = sbm.dlgOpts();
|
||||
opt.dialogClass += " sbm-AssetCategory";
|
||||
opt.buttons[sbm.lbl.ok] = function () { ac.selectItem(env); };
|
||||
opt.buttons[sbm.lbl.cancel] = function () { delete env.prmSelect; $(this).dialog('close'); };
|
||||
env.$dlg.select = $('#dlgAssetCategorySelect').dialog(opt);
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
$(function ()
|
||||
{
|
||||
$pnl.items = $('.sbm-panel.AssetCategories');
|
||||
$pnl.header = $('.sbm-panel-header', $pnl.items);
|
||||
$pnl.bgr = $('.sbm-burger', $pnl.header);
|
||||
$pnl.mnu = $('ul.sbm-dropdown-menu', $pnl.bgr);
|
||||
$pnl.filter = $('.sbm-panel-filter', $pnl.items);
|
||||
$pnl.table = $('.sbm-panel-item-table', $pnl.items);
|
||||
$pnl.msgs = $('.sbm-panel-messages', $pnl.items);
|
||||
$pnl.tmpls = $('.sbm-panel-item-template', $pnl.items);
|
||||
|
||||
$frm.filter = $('#frmAssetCategoryFilter');
|
||||
$('.FilterSearch', $frm.filter).on('input', function () { ac.refreshResults(250); });
|
||||
|
||||
$frm.itemId = $('#frmAssetCategoryId');
|
||||
var opt = sbm.dlgOpts();
|
||||
opt.buttons[sbm.lbl.save] = function () { ac.storeItem(); };
|
||||
opt.buttons[sbm.lbl.cancel] = function () { $(this).dialog('close'); };
|
||||
$dlg.item = $('#dlgAssetCategory').dialog(opt);
|
||||
$frm.item = $('#frmAssetCategory');
|
||||
$($frm.item).on('input', '.sbm-input, .sbm-textarea', function () { sbm.clearControlError(this); }).on('change', '.sbm-select', function () { sbm.clearControlError(this); });
|
||||
|
||||
setTimeout(ac.refreshResults, 250);
|
||||
ac.env.maint = ac.initEnv('.sbm-panel.AssetCategories');
|
||||
if (ac.env.maint.$pnl.items.length) setTimeout(function () { ac.refreshResults(ac.env.maint); }, 250);
|
||||
ac.env.select = ac.initEnv('#dlgAssetCategorySelect');
|
||||
if (ac.env.select.$pnl.items.length) setTimeout(function () { ac.refreshConfig(ac.env.select); }, 250);
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
@@ -214,6 +214,7 @@
|
||||
$frm.itemId = $('#frmAssetId');
|
||||
$frm.categories = $('#frmCategories');
|
||||
var opt = sbm.dlgOpts();
|
||||
opt.dialogClass += " sbm-Asset";
|
||||
opt.buttons[sbm.lbl.save] = function () { ac.storeItem(); };
|
||||
opt.buttons[sbm.lbl.cancel] = function () { $(this).dialog('close'); };
|
||||
$dlg.item = $('#dlgAsset').dialog(opt);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// Config.
|
||||
env.mode = response.mode;
|
||||
env.config = response.config;
|
||||
env.configCmd = response.configCmd;
|
||||
env.configItemNew = response.configItemNew;
|
||||
env.data.commodityTypes = response.commodityTypes;
|
||||
env.data.statuses = response.statuses;
|
||||
env.data.defaultStatusCode = response.defaultStatusCode;
|
||||
@@ -55,7 +55,7 @@
|
||||
env.$pnl.bgr.invisible();
|
||||
env.$pnl.mnu.empty();
|
||||
env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.refresh, function () { co.refreshResults(env); }, 'sbm-refresh'));
|
||||
env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.configCmd); }, 'sbm-add'));
|
||||
env.$pnl.mnu.append(co.getFilterMenuOption(env, sbm.lbl.create, function () { co.createItem(env, env.configItemNew); }, 'sbm-add'));
|
||||
env.$pnl.bgr.toggleVisibility(!!$('.sbm-dropdown-item', env.$pnl.mnu).length);
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@
|
||||
var items = response.commodities || [];
|
||||
if (!items.length)
|
||||
return env.$pnl.msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
|
||||
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
|
||||
$table.append(co.populateItem(env, co.getItemTemplate(env), items[itemIdx]));
|
||||
for (const item of items)
|
||||
$table.append(co.populateItem(env, co.getItemTemplate(env), item));
|
||||
}
|
||||
co.populateItem = function (env, $item, item)
|
||||
{
|
||||
@@ -72,10 +72,10 @@
|
||||
$item.prop('id', co.getItemId(item));
|
||||
let cfg = env.config;
|
||||
if (cfg) sbm.populateItemValues(cfg, $item, item.field.value);
|
||||
let prefix = cfg.column.prefix;
|
||||
$('.' + prefix + 'Status', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase());
|
||||
if (!env.mode.search)
|
||||
{
|
||||
let prefix = cfg.column.prefix;
|
||||
$('.' + prefix + 'Status', $item).text(item.statusDesc).removeStatusClasses().addClass('sbm-status-' + item.statusCode.toLowerCase());
|
||||
// Actions.
|
||||
var $bgr = $('.sbm-burger', $item).hide();
|
||||
let $mnu = $('ul.sbm-dropdown-menu', $bgr).empty();
|
||||
@@ -182,9 +182,7 @@
|
||||
//--------------------------------------------------------------
|
||||
co.storeItem = function (env)
|
||||
{
|
||||
env.ajax.storeItem = env.ajax.storeItem || {
|
||||
url: sbm.url.base + 'Commodity/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { co.onStoreItem(env, response); }
|
||||
};
|
||||
env.ajax.storeItem = env.ajax.storeItem || {url: sbm.url.base + 'Commodity/Ajax/StoreItem', formSel: env.$frm.item, callbackFn: function (response) { co.onStoreItem(env, response); }};
|
||||
sbm.doAjaxRequest(env.ajax.storeItem, 50);
|
||||
}
|
||||
co.onStoreItem = function (env, response)
|
||||
@@ -256,7 +254,7 @@
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
co.initCommodityEnv = function ($pnlItems)
|
||||
co.initEnv = function ($pnlItems)
|
||||
{
|
||||
let env = { data: {}, ajax: {}, $pnl: {}, $frm: {}, $ctrl: {}, $dlg: {} };
|
||||
|
||||
@@ -288,12 +286,13 @@
|
||||
//--------------------------------------------------------------
|
||||
$(function ()
|
||||
{
|
||||
co.env.maint = co.initCommodityEnv('.sbm-panel.Commodities');
|
||||
co.env.maint = co.initEnv('.sbm-panel.Commodities');
|
||||
if (co.env.maint.$pnl.items.length) setTimeout(function () { co.refreshResults(co.env.maint); }, 250);
|
||||
co.env.select = co.initCommodityEnv('#dlgCommoditySelect');
|
||||
co.env.select = co.initEnv('#dlgCommoditySelect');
|
||||
if (co.env.select.$pnl.items.length) setTimeout(function () { co.refreshConfig(co.env.select); }, 250);
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------
|
||||
}(window, window.document));
|
||||
|
||||
/* The End */
|
||||
Reference in New Issue
Block a user