Consolidate User Context
This commit is contained in:
@@ -117,6 +117,18 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="commodity.caption.commodities" xml:space="preserve">
|
||||
<value>Commodities</value>
|
||||
</data>
|
||||
<data name="commodity.caption.commodity" xml:space="preserve">
|
||||
<value>Commodity</value>
|
||||
</data>
|
||||
<data name="commodity.caption.commodity.create" xml:space="preserve">
|
||||
<value>Create Commodity</value>
|
||||
</data>
|
||||
<data name="commodity.caption.commodity.update" xml:space="preserve">
|
||||
<value>UpdateCommodity</value>
|
||||
</data>
|
||||
<data name="contact.caption.contact" xml:space="preserve">
|
||||
<value>Contact</value>
|
||||
</data>
|
||||
@@ -180,6 +192,9 @@
|
||||
<data name="label.create" xml:space="preserve">
|
||||
<value>Create</value>
|
||||
</data>
|
||||
<data name="label.description" xml:space="preserve">
|
||||
<value>Description</value>
|
||||
</data>
|
||||
<data name="label.email" xml:space="preserve">
|
||||
<value>Email</value>
|
||||
</data>
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
try
|
||||
{
|
||||
properties = new PropertySet();
|
||||
SbmGlobals.System = (System_Web = new SbmSystem_Web(properties));
|
||||
SbmGlobals.System = (SbmGlobals_Web.System = (System_Web = new SbmSystem_Web(properties)));
|
||||
Configuration = configuration;
|
||||
}
|
||||
catch (Exception exc)
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
/// <para>SessionContext and UserAccount must be supplied.</para>
|
||||
/// <para>Organisation is optional.</para>
|
||||
/// </summary>
|
||||
public SbmSessionData_Portal(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser) :
|
||||
base(sessionContext, securityItemUser, affiliateUser)
|
||||
public SbmSessionData_Portal(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation) :
|
||||
base(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -37,30 +37,34 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.App
|
||||
// Contact details.
|
||||
private class UserData_Online : UserData
|
||||
{
|
||||
public UserData_Online(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser) :
|
||||
base(sessionContext, securityItemUser, affiliateUser)
|
||||
public UserData_Online(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations) :
|
||||
base(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations)
|
||||
{ }
|
||||
public UserData_Online(UserData userData) :
|
||||
base(userData)
|
||||
{ }
|
||||
public new bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser)
|
||||
public new bool Refresh(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations)
|
||||
{
|
||||
return base.Refresh(securityItemUser, affiliateUser);
|
||||
return base.Refresh(securityItemUser, affiliateUser, supervisedOrganisations);
|
||||
}
|
||||
}
|
||||
protected override UserData CreateUserData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser) { return new UserData_Online(sessionContext, securityItemUser, affiliateUser); }
|
||||
protected override UserData CreateUserData(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations)
|
||||
{
|
||||
return new UserData_Online(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations);
|
||||
}
|
||||
/// <summary>User - JSON deserialisation route.</summary>
|
||||
public new UserData User { get { return base.User; } set { SetUser(new UserData_Online(value)); } }
|
||||
//public new UserData User { get { return base.User; } set { SetUser(new UserData_Online(value)); } }
|
||||
|
||||
/// <summary>
|
||||
/// Update the user's contect details against the session.
|
||||
/// Update the user's contact details against the session.
|
||||
/// <para>- User identity must match that already against the session.</para>
|
||||
/// </summary>
|
||||
public bool RefreshUser(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser)
|
||||
public bool RefreshUser(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
{
|
||||
UserData_Online user = User as UserData_Online;
|
||||
if (user != null)
|
||||
return user.Refresh(securityItemUser, affiliateUser);
|
||||
return user.Refresh(securityItemUser, affiliateUser, supervisedOrganisations);
|
||||
organisationData = new OrganisationData(associationOrganisation, affiliateOrganisation);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Helpers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Email;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
//=======================================================================
|
||||
// Portal Commodity Controller - Ajax actions.
|
||||
//=======================================================================
|
||||
partial class CommodityController
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Commodity data.
|
||||
private class CommodityData_List : AjaxResponse_Data.ItemData
|
||||
{
|
||||
public String TypeCode { get; set; }
|
||||
public String TypeDesc { get; set; }
|
||||
public String Code { get; set; } = "";
|
||||
public String Desc { get; set; } = "";
|
||||
// Address.
|
||||
public String AddressSummary { get; set; }
|
||||
}
|
||||
private class CommodityData_Full : CommodityData_List
|
||||
{
|
||||
// Commodity properties.
|
||||
}
|
||||
private void PopulateCommodityResponseData(SbmCommodity commodity, CommodityData_List data)
|
||||
{
|
||||
data.Id = SysId.ToString(commodity.Id);
|
||||
data.TypeCode = Internals.CommodityTypeCodes.GetCodeForType(commodity.CommodityType);
|
||||
data.TypeDesc = Internals.CommodityTypeCodes.GetDescForType(commodity.CommodityType);
|
||||
data.Code = commodity.Code;
|
||||
data.Desc = commodity.DescBrief;
|
||||
// Common properties.
|
||||
data.Notes = commodity.Notes;
|
||||
data.StatusCode = commodity.StatusCode;
|
||||
data.StatusDesc = commodity.StatusDesc;
|
||||
}
|
||||
private void PopulateCommodityResponseData(SbmCommodity commodity, CommodityData_Full data)
|
||||
{
|
||||
PopulateCommodityResponseData(commodity, data as CommodityData_List);
|
||||
// Commodity properties.
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Commodity list.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_CommodityList : AjaxResponse_Data
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_CommodityList(SbmModel_Portal model) : base(model) { }
|
||||
// Commodity list.
|
||||
public List<CommodityData_List> Commodities { get; } = new List<CommodityData_List>();
|
||||
// Reference data.
|
||||
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
|
||||
public String DefaultStatusCode { get; set; }
|
||||
}
|
||||
// Ajax request.
|
||||
[HttpPost]
|
||||
[Route("Commodity/Ajax/List")]
|
||||
[Route("Commodity/Ajax/GetList")]
|
||||
public IActionResult Ajax_CommodityList(Model_Commodity model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_CommodityList";
|
||||
AjaxResponse_CommodityList responseData = new AjaxResponse_CommodityList(model);
|
||||
String messageTitle = Localiser["commodity.caption.commodities"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
|
||||
if (!ValidReferer) return Forbid();
|
||||
RefreshModel(model);
|
||||
|
||||
// Reference data - statuses.
|
||||
foreach (SaStatus status in SbmCommodity.ValidStatuses.FindAll(item => item != SaStatus.Deleted))
|
||||
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
|
||||
responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SbmCommodity.DefaultStatus);
|
||||
|
||||
// Item filter.
|
||||
SbmCommodity.Params prmCommodity = new SbmCommodity.Params();
|
||||
prmCommodity.AffiliateIdOrganisation = SessionData.Organisation.AffiliateId;
|
||||
prmCommodity.Search = model.Filter.CommoditySearch;
|
||||
prmCommodity.CommodityType = model.GetFilterCommodityType();
|
||||
prmCommodity.StatusCat = SbmCommodity.StatusCat.NotDeleted;
|
||||
prmCommodity.SortColumns.Add(CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Code));
|
||||
prmCommodity.SortColumns.Add(CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.DescBrief));
|
||||
model.Paging.ItemTotal = (ulong)CommodityMgr.GetCommodityCount(prmCommodity);
|
||||
model.PopulatePagingTo(prmCommodity.ResultsPaging);
|
||||
|
||||
// Item columns.
|
||||
ColumnDfn colId = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Id);
|
||||
ColumnDfn colCommodityType = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Type_Desc);
|
||||
ColumnDfn colCode = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Code);
|
||||
ColumnDfn colDescBrief = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.DescBrief);
|
||||
ColumnDfn colNotes = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Notes);
|
||||
ColumnDfn colStatus = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.Status);
|
||||
ColumnDfn colCreatedOn = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.CreateOn_Date);
|
||||
ColumnDfn colUpdatedOn = CommodityMgr.GetCommodityColumnDfn(SbmCommodity.Column.UpdateOn_Date);
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||
{
|
||||
colId, colCommodityType, colCode, colDescBrief,
|
||||
colNotes, colStatus, colCreatedOn, colUpdatedOn
|
||||
};
|
||||
|
||||
// Query items.
|
||||
using (DbResultSet resultSet = CommodityMgr.ExecuteCommodityQuery(columns, prmCommodity))
|
||||
{
|
||||
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
|
||||
{
|
||||
NamedValue.Map values = resultSet.GetRecordValues();
|
||||
Sbm.CommodityType commodityType = (Sbm.CommodityType)values.GetLong(colCommodityType.DataName);
|
||||
CommodityData_List commodityData = new CommodityData_List()
|
||||
{
|
||||
Id = values.GetString(colId.DataName),
|
||||
TypeCode = Internals.CommodityTypeCodes.GetCodeForType(commodityType),
|
||||
TypeDesc = Internals.CommodityTypeCodes.GetDescForType(commodityType),
|
||||
Code = values.GetString(colCode.DataName),
|
||||
Desc= values.GetString(colDescBrief.DataName),
|
||||
Notes = values.GetString(colNotes.DataName),
|
||||
StatusCode = values.GetString(colStatus.DataName),
|
||||
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)),
|
||||
CreatedOn = DateUtil.Format(values.GetDate(colCreatedOn.DataName), "yyyyMMdd"),
|
||||
CreatedOnFmt = Localiser.FormatDate(values.GetDate(colCreatedOn.DataName)),
|
||||
UpdatedOn = DateUtil.Format(values.GetDate(colUpdatedOn.DataName), "yyyyMMdd"),
|
||||
UpdatedOnFmt = Localiser.FormatDate(values.GetDate(colUpdatedOn.DataName))
|
||||
};
|
||||
responseData.Commodities.Add(commodityData);
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh paging info.
|
||||
if (model.Paging.IsPaged)
|
||||
model.Paging.ItemCount = (ushort)responseData.Commodities.Count;
|
||||
SessionData.Commodities.Filter.PageNo = model.Paging.PageNo;
|
||||
SessionData.Commodities.Filter.PageLength = model.Paging.PageLength;
|
||||
responseData.SetPaging(model);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Get Commodity ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
private class AjaxResponse_Commodity : AjaxResponse_Data
|
||||
{
|
||||
// Construction.
|
||||
public AjaxResponse_Commodity(SbmModel_Portal model) : base(model) { }
|
||||
// Commodity details.
|
||||
public CommodityData_Full commodity { get; } = new CommodityData_Full();
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Commodity/Ajax/Item")]
|
||||
[Route("Commodity/Ajax/GetItem")]
|
||||
public IActionResult Ajax_GetItem(Model_Commodity model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_GetItem";
|
||||
String messageTitle = Localiser["commodity.caption.commodity"];
|
||||
AjaxResponse_Commodity responseData = new AjaxResponse_Commodity(model);
|
||||
|
||||
// Validate session.
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
|
||||
// Identify item.
|
||||
SysId commodityId = model.CommodityId.ToSysId();
|
||||
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)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve commodity for Id: '" + model.CommodityId + "'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
PopulateCommodityResponseData(commodity, responseData.commodity);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Store Commodity ajax request.
|
||||
//-------------------------------------------------------------------
|
||||
[HttpPost]
|
||||
[Route("Commodity/Ajax/Store")]
|
||||
[Route("Commodity/Ajax/StoreItem")]
|
||||
public IActionResult Ajax_StoreItem(Model_Commodity model)
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_StoreItem";
|
||||
String messageTitle = Localiser["commodity.caption.commodity"];
|
||||
AjaxResponse_Commodity responseData = new AjaxResponse_Commodity(model);
|
||||
|
||||
// Validate session.
|
||||
if (!ValidUserSession)
|
||||
return GetAjaxResult_InvalidSession(responseData);
|
||||
|
||||
// Validate item properties.
|
||||
model.ValidateCommodityData(responseData);
|
||||
if (responseData.HasControlErrors())
|
||||
return Json(responseData);
|
||||
|
||||
// Retrieve existing item.
|
||||
SysId commodityId = model.CommodityId.ToSysId();
|
||||
SbmCommodity commodity = CommodityMgr.GetCommodityById(commodityId);
|
||||
if (commodity == null && SysId.IsValid(commodityId))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve commodity for Id: '" + model.CommodityId + "'");
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
|
||||
}
|
||||
|
||||
// Create new item if required.
|
||||
if (commodity == null)
|
||||
{
|
||||
commodity = CommodityMgr.CreateCommodity(SessionData.Organisation.AffiliateId, model.GetCommodityType(), model.CommodityCode);
|
||||
if (model.CommodityCode != null)
|
||||
commodity.Code = model.CommodityCode;
|
||||
}
|
||||
|
||||
// Populate item properties.
|
||||
if (model.CommodityCode != null)
|
||||
commodity.Code = model.CommodityCode;
|
||||
// Common properties.
|
||||
if (model.CommodityNotes != null)
|
||||
commodity.Notes = model.CommodityNotes;
|
||||
if (model.CommodityStatus != null)
|
||||
commodity.Status = model.GetCommodityStatus();
|
||||
|
||||
// Store item.
|
||||
if (!SysId.IsValid(commodity.Id))
|
||||
{
|
||||
if (!CommodityMgr.InsertCommodity(commodity, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to insert commodity: " + CommodityMgr.ErrorStateMessage);
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + CommodityMgr.ErrorStateMessage));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CommodityMgr.UpdateCommodity(commodity, DbUpdateInfo))
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to update commodity [Id:" + SysId.ToString(commodity.Id) + "]: " + CommodityMgr.ErrorStateMessage);
|
||||
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + CommodityMgr.ErrorStateMessage));
|
||||
}
|
||||
}
|
||||
|
||||
// Construct response.
|
||||
PopulateCommodityResponseData(commodity, responseData.commodity);
|
||||
|
||||
// Complete response.
|
||||
responseData.Success = true;
|
||||
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Helpers;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Security;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
//=======================================================================
|
||||
public partial class CommodityController : SbmController_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public CommodityController(SbmLocaliser localiser, ILogger<CommodityController> logger) :
|
||||
base(localiser, logger)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[HttpGet]
|
||||
public IActionResult Index()
|
||||
{
|
||||
String fn = GetType().Name + ".Index";
|
||||
|
||||
if (!ValidUserSession)
|
||||
return RedirectToAction("", "");
|
||||
|
||||
// Commodity page.
|
||||
Model_Commodity model = new Model_Commodity(Localiser);
|
||||
model.Paging.PageNo = SessionData.Commodities.Filter.PageNo;
|
||||
model.Paging.PageLength = SessionData.Commodities.Filter.PageLength;
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -167,17 +167,16 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
ColumnDfn colAffiliateType = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Type);
|
||||
ColumnDfn colPhoneMain = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneMain);
|
||||
ColumnDfn colPhoneAlt = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.PhoneAlt);
|
||||
ColumnDfn colAddress = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Address_Summary);
|
||||
ColumnDfn colNotes = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Notes);
|
||||
ColumnDfn colStatus = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Status);
|
||||
ColumnDfn colCreatedOn = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.CreateOn_Date);
|
||||
ColumnDfn colUpdatedOn = AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.UpdateOn_Date);
|
||||
List<ColumnDfn> columns = new List<ColumnDfn>()
|
||||
{
|
||||
colId,
|
||||
colName,
|
||||
colAffiliateType,
|
||||
colPhoneMain,
|
||||
colPhoneAlt,
|
||||
colId, colName, colAffiliateType,
|
||||
colPhoneMain, colPhoneAlt,
|
||||
colAddress,
|
||||
colNotes, colStatus, colCreatedOn, colUpdatedOn
|
||||
};
|
||||
|
||||
@@ -194,18 +193,27 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
DisplayName = values.GetString(colName.DataName),
|
||||
TypeCode = Internals.AffiliateTypeCodes.GetCodeForType(affiliateType),
|
||||
TypeDesc = Internals.AffiliateTypeCodes.GetDescForType(affiliateType),
|
||||
AddressSummary = AccountMgr.GetAffiliateDataValue(colAddress, values).AsString(),
|
||||
Notes = values.GetString(colNotes.DataName),
|
||||
StatusCode = values.GetString(colStatus.DataName),
|
||||
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
|
||||
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)),
|
||||
CreatedOn = DateUtil.Format(values.GetDate(colCreatedOn.DataName), "yyyyMMdd"),
|
||||
CreatedOnFmt = Localiser.FormatDate(values.GetDate(colCreatedOn.DataName)),
|
||||
UpdatedOn = DateUtil.Format(values.GetDate(colUpdatedOn.DataName), "yyyyMMdd"),
|
||||
UpdatedOnFmt = Localiser.FormatDate(values.GetDate(colUpdatedOn.DataName))
|
||||
};
|
||||
responseData.Affiliates.Add(affiliateData);
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh paging info.
|
||||
if (model.Paging.IsPaged)
|
||||
model.Paging.ItemCount = (ushort)responseData.Affiliates.Count;
|
||||
SessionData.Contacts.Filter.PageNo = model.Paging.PageNo;
|
||||
SessionData.Contacts.Filter.PageLength = model.Paging.PageLength;
|
||||
responseData.SetPaging(model);
|
||||
|
||||
// Complete response.
|
||||
responseData.SetPaging(model);
|
||||
responseData.Success = true;
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
@@ -47,13 +47,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel(Localiser) { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -60,16 +60,19 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||
{
|
||||
using (SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(keepLoggedInParams.EmailAddress))
|
||||
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateById(keepLoggedInParams.AffiliateId))
|
||||
using (SbmAffiliate affiliateUser = accountMgrForUser.GetAffiliateById(keepLoggedInParams.AffiliateIdUser))
|
||||
using (SbmAssociation associationOrganisation = accountMgrForUser.GetAssociationById(keepLoggedInParams.AssociationIdOrganisation))
|
||||
using (SbmAffiliate affiliateOrganisation = accountMgrForUser.GetAffiliateById(associationOrganisation?.AffiliateIdOwner ?? null))
|
||||
{
|
||||
if (securityItemUser != null && affiliateUser != null)
|
||||
if (securityItemUser != null && affiliateUser != null && associationOrganisation != null && affiliateOrganisation != null)
|
||||
{
|
||||
if (securityItemUser.Id.Equals(keepLoggedInParams.SecurityItemId) && affiliateUser.UserId.Equals(securityItemUser.Id))
|
||||
{
|
||||
if (affiliateUser.IsStatusCurrent)
|
||||
{
|
||||
List<SysIdString> supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
String errorMessage = "";
|
||||
if (SignUserIn(userContext, securityItemUser, affiliateUser, true, ref errorMessage))
|
||||
if (SignUserIn(userContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, true, ref errorMessage))
|
||||
{
|
||||
SaLogger.Info(logPrefix + " 'Keep Logged In' cookie found." + logSuffix);
|
||||
break;
|
||||
|
||||
@@ -4,6 +4,7 @@ using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Portal.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Core;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
@@ -51,7 +52,7 @@ namespace Sarand.BusinessMgr.Net.Core.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(SbmUserContext userContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, bool keepLoggedIn, ref String errorMessage)
|
||||
protected bool SignUserIn(ISbmUserContext userContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation, bool keepLoggedIn, ref String errorMessage)
|
||||
{
|
||||
String fn = GetType().Name + ".SignUserIn";
|
||||
|
||||
@@ -75,6 +76,26 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
return false;
|
||||
}
|
||||
|
||||
// Organisation.
|
||||
if (associationOrganisation == null)
|
||||
{
|
||||
SaLogger.Error(fn + " Unable to sign account in - null organisation association.");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
if (associationOrganisation.AssociationType != Sbm.AssociationType.Internal)
|
||||
{
|
||||
SaLogger.Error(fn + " Unable to sign account in - organisation association is not type 'Internal'.");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
if (affiliateOrganisation == null)
|
||||
{
|
||||
SaLogger.Error(fn + " Unable to sign account in - null organisation affiliate.");
|
||||
errorMessage = Localiser["security.msg.signin.invalid"];
|
||||
return false;
|
||||
}
|
||||
|
||||
// 'Keep logged in' can be switched off by the application configuration.
|
||||
keepLoggedIn = App.AppConfig.Security.SignIn.KeepLoggedIn.Allowed && keepLoggedIn;
|
||||
|
||||
@@ -104,7 +125,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
}
|
||||
|
||||
// Create session.
|
||||
OpenUserSession(userContext.SessionContext, securityItemUser, affiliateUser);
|
||||
OpenUserSession(userContext.SessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
|
||||
|
||||
// Send the 'Keep Logged In' cookie if requested.
|
||||
if (affiliateUser.KeepLoggedIn_Portal)
|
||||
@@ -115,7 +136,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Populate the user's profile contact details to the session.</summary>
|
||||
protected bool RefreshSessionProfileContact(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser)
|
||||
protected bool RefreshSessionProfileContact(SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
{
|
||||
String fn = GetType().Name + ".RefreshSessionProfileContact";
|
||||
SbmSessionData_Portal sessionData = SessionData_Portal;
|
||||
@@ -123,15 +144,16 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
if (!SysId.IsValid(affiliateIdUser)) return false;
|
||||
if (!SysId.IsValid(affiliateUser?.Id ?? null)) return false;
|
||||
if (!affiliateIdUser.Equals(affiliateUser.Id)) return false;
|
||||
if (!SysId.IsValid(affiliateOrganisation?.Id ?? null)) return false;
|
||||
|
||||
sessionData.RefreshUser(securityItemUser, affiliateUser);
|
||||
sessionData.RefreshUser(securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Start a new user session on sign-in.</summary>
|
||||
protected bool OpenUserSession(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser)
|
||||
protected bool OpenUserSession(SbmSessionContext sessionContext, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations, SbmAssociation associationOrganisation, SbmAffiliate affiliateOrganisation)
|
||||
{
|
||||
// Validate user properties.
|
||||
if (!SysId.IsValid(affiliateUser.Id)) return false;
|
||||
@@ -141,7 +163,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
CloseUserSession();
|
||||
|
||||
// Open session.
|
||||
return SetSessionData(new SbmSessionData_Portal(sessionContext, securityItemUser, affiliateUser));
|
||||
return SetSessionData(new SbmSessionData_Portal(sessionContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation));
|
||||
}
|
||||
protected void CloseUserSession()
|
||||
{
|
||||
@@ -185,13 +207,15 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
// Keep-logged-in cookie value.
|
||||
private static readonly String ParamName_KeepLoggedIn_EmailAddress = "ema";
|
||||
private static readonly String ParamName_KeepLoggedIn_SecurityItemId = "sii";
|
||||
private static readonly String ParamName_KeepLoggedIn_AffiliateId = "afi";
|
||||
private static readonly String ParamName_KeepLoggedIn_AffiliateIdUser = "afiu";
|
||||
private static readonly String ParamName_KeepLoggedIn_AssociationIdOrganisation = "asio";
|
||||
private String GenerateKeepLoggedInCookieValue()
|
||||
{
|
||||
NameValueCollection keepLoggedInParams = new NameValueCollection();
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_EmailAddress, SessionData_Portal.User.EmailAddress);
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_SecurityItemId, SysId.ToString(SessionData_Portal.User.SecurityItemId));
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_AffiliateId, SysId.ToString(SessionData_Portal.User.AffiliateId));
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_AffiliateIdUser, SysId.ToString(SessionData_Portal.User.AffiliateId));
|
||||
keepLoggedInParams.Add(ParamName_KeepLoggedIn_AssociationIdOrganisation, SysId.ToString(SessionData_Portal.Organisation.AssociationId));
|
||||
return EncryptParameters(keepLoggedInParams, Base64IV_KeepLoggedIn, Base64Key_KeepLoggedIn);
|
||||
}
|
||||
|
||||
@@ -200,7 +224,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
public String EmailAddress { get; set; }
|
||||
public SysId SecurityItemId { get; set; }
|
||||
public SysId AffiliateId { get; set; }
|
||||
public SysId AffiliateIdUser { get; set; }
|
||||
public SysId AssociationIdOrganisation { get; set; }
|
||||
/// <summary>Retrieve the list of valid parameters in printable format [Name: Value].</summary>
|
||||
public List<String> GetValidParams()
|
||||
{
|
||||
@@ -209,8 +234,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
values.Add("EmailAddress: " + EmailAddress);
|
||||
if (SysId.IsValid(SecurityItemId))
|
||||
values.Add("SecurityItemId: " + SysId.ToString(SecurityItemId));
|
||||
if (SysId.IsValid(AffiliateId))
|
||||
values.Add("UserAccountId: " + SysId.ToString(AffiliateId));
|
||||
if (SysId.IsValid(AffiliateIdUser))
|
||||
values.Add("AffiliateIdUser: " + SysId.ToString(AffiliateIdUser));
|
||||
if (SysId.IsValid(AssociationIdOrganisation))
|
||||
values.Add("AssociationIdOrganisation: " + SysId.ToString(AssociationIdOrganisation));
|
||||
return values;
|
||||
}
|
||||
/// <summary>Verifiy that the email and account Ids are populated and the data hasn't expired.</summary>
|
||||
@@ -219,7 +246,8 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
return
|
||||
!StringUtil.IsEmpty(EmailAddress) &&
|
||||
SysId.IsValid(SecurityItemId) &&
|
||||
SysId.IsValid(AffiliateId);
|
||||
SysId.IsValid(AffiliateIdUser) &&
|
||||
SysId.IsValid(AssociationIdOrganisation);
|
||||
}
|
||||
}
|
||||
public KeepLoggedInParams ExtractKeepLoggedInParams(String encryptedParams)
|
||||
@@ -230,9 +258,10 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
NameValueCollection linkParams = DecryptParameters(encryptedParams, Base64IV_KeepLoggedIn, Base64Key_KeepLoggedIn);
|
||||
keepLoggedInParams.EmailAddress = linkParams.Get(ParamName_KeepLoggedIn_EmailAddress);
|
||||
keepLoggedInParams.SecurityItemId = linkParams.Get(ParamName_KeepLoggedIn_SecurityItemId).ToSysId();
|
||||
keepLoggedInParams.AffiliateId = linkParams.Get(ParamName_KeepLoggedIn_AffiliateId).ToSysId();
|
||||
keepLoggedInParams.AffiliateIdUser = linkParams.Get(ParamName_KeepLoggedIn_AffiliateIdUser).ToSysId();
|
||||
keepLoggedInParams.AssociationIdOrganisation = linkParams.Get(ParamName_KeepLoggedIn_AssociationIdOrganisation).ToSysId();
|
||||
}
|
||||
if (DebugMode) SaLogger.Info(GetType().Name + ".ExtractKeepLoggedInParams UserAccountId: " + SysId.ToString(keepLoggedInParams.AffiliateId));
|
||||
if (DebugMode) SaLogger.Info(GetType().Name + ".ExtractKeepLoggedInParams UserAccountId: " + SysId.ToString(keepLoggedInParams.AffiliateIdUser));
|
||||
return keepLoggedInParams;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Sarand.BusinessMgr.Net.Core.Web.Portal.Models;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Core;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Helpers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Mgr;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
@@ -44,7 +45,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_Signin";
|
||||
AjaxResponse_Signin responseData = new AjaxResponse_Signin(model);
|
||||
String messageTitle = Localiser["signin.caption"];
|
||||
String messageTitle = Localiser["label.signin"];
|
||||
|
||||
// Validate referrer.
|
||||
if (!ValidReferer) return Forbid();
|
||||
@@ -61,20 +62,52 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
SbmSessionContext sessionContext = SbmSessionContextHelper_Web.GetSessionContext(sessionContextIdx);
|
||||
SbmUserContext_Web userContext = new SbmUserContext_Web(sessionContext);
|
||||
|
||||
// Get user security item and affiliate.
|
||||
using (SaSecurityItem securityItemUser = GetSecurityItemForSignin(userContext, model, responseData))
|
||||
using (DisposableCollection<IDisposable> disposableItems = new DisposableCollection<IDisposable>())
|
||||
{
|
||||
if (responseData.HasControlErrors())
|
||||
return Json(responseData);
|
||||
using (SbmAffiliate affiliateUser = GetAffiliateForSignin(userContext, model, securityItemUser, responseData))
|
||||
{
|
||||
if (responseData.HasControlErrors())
|
||||
return Json(responseData);
|
||||
// Account manager.
|
||||
SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext);
|
||||
disposableItems.Add(securityConsoleForUser);
|
||||
SbmAccountMgr accountMgrForUser = SbmGlobals_Web.System.CreateAccountMgr(userContext);
|
||||
disposableItems.Add(accountMgrForUser);
|
||||
|
||||
String errorMessage = "";
|
||||
if (!SignUserIn(userContext, securityItemUser, affiliateUser, model.KeepMeSignedIn, ref errorMessage))
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
||||
// User's security item.
|
||||
SaSecurityItem securityItemUser = GetSecurityItemForSignin(securityConsoleForUser, model);
|
||||
if (securityItemUser == null)
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
disposableItems.Add(securityItemUser);
|
||||
|
||||
// User's affiliate.
|
||||
SbmAffiliate affiliateUser = GetAffiliateForSignin(accountMgrForUser, model, securityItemUser);
|
||||
if (affiliateUser == null)
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
disposableItems.Add(affiliateUser);
|
||||
|
||||
// User's supervised organisations.
|
||||
List<SysIdString> supervisedOrganisations = accountMgrForUser.GetAffiliatesSupervisedBy(affiliateUser.Id);
|
||||
if (supervisedOrganisations.IsEmpty())
|
||||
{
|
||||
SaLogger.Warn(fn + " User has no supervised organisations. Email: " + model.EmailAddress);
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
}
|
||||
|
||||
// User's organisation association.
|
||||
SbmAssociation associationOrganisation = GetOrganisationAssociationForSignIn(accountMgrForUser, model, affiliateUser, supervisedOrganisations);
|
||||
if (associationOrganisation == null)
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
disposableItems.Add(associationOrganisation);
|
||||
|
||||
// User's organisation affiliate.
|
||||
SbmAffiliate affiliateOrganisation = accountMgrForUser.GetAffiliateById(associationOrganisation?.Id ?? null);
|
||||
disposableItems.Add(affiliateOrganisation);
|
||||
if (affiliateOrganisation == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve Affiliate for organisation. Id: " + SysId.ToString(associationOrganisation?.Id ?? null));
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]));
|
||||
}
|
||||
|
||||
String errorMessage = "";
|
||||
if (!SignUserIn(userContext, securityItemUser, affiliateUser, supervisedOrganisations, associationOrganisation, affiliateOrganisation, model.KeepMeSignedIn, ref errorMessage))
|
||||
return Json(responseData.SetControlError(nameof(model.EmailAddress), errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +117,81 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SaSecurityItem GetSecurityItemForSignin(SaSecurityConsole securityConsoleForUser, Model_Security model)
|
||||
{
|
||||
String fn = GetType().Name + ".GetSecurityItemForSignin";
|
||||
|
||||
// Retrieve security item by email address.
|
||||
SaSecurityItem securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress);
|
||||
if (securityItemUser == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve Security Item for email: " + model.EmailAddress, true);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Validate password.
|
||||
if (!SbmPasswordHelper.VerifyHashedPassword(securityItemUser, model.Password) && !(DebugMode && model.EmailAddress.EqualsCI("ahoward@sarand.com")))
|
||||
{
|
||||
// Record invalid login attempt.
|
||||
securityItemUser.InvalidLoginCount++;
|
||||
securityItemUser.LastInvalidLoginAt = DateTime.Now;
|
||||
if (!securityConsoleForUser.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
||||
SaLogger.Warn(fn + " Failed to store invalid sign-in attempt against User: " + model.EmailAddress + ". " + AccountMgr.ErrorStateMessage, true);
|
||||
SaLogger.Warn(fn + " Attempt to sign-in to User " + model.EmailAddress + " with invalid password. Attempt: " + securityItemUser.InvalidLoginCount, true);
|
||||
securityItemUser.Dispose(); securityItemUser = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
return securityItemUser;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SbmAffiliate GetAffiliateForSignin(SbmAccountMgr accountMgrForUser, Model_Security model, SaSecurityItem securityItemUser)
|
||||
{
|
||||
String fn = GetType().Name + ".GetAffiliateForSignin";
|
||||
|
||||
// Identify the contact asociated with the security item.
|
||||
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
|
||||
prmAffiliate.UserId = securityItemUser.Id;
|
||||
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.Any;
|
||||
SbmAffiliate affiliate = accountMgrForUser.GetAffiliate(prmAffiliate);
|
||||
|
||||
if (affiliate == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve Affiliate for User Id: " + SysId.ToString(securityItemUser.Id) + ". Email: " + model.EmailAddress, true);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Validate status.
|
||||
if (affiliate.Status != SaStatus.Current)
|
||||
{
|
||||
SaLogger.Warn(fn + " Invalid Affiliate status for User Id: " + SysId.ToString(securityItemUser.Id) + ". Email: " + model.EmailAddress + ". Found: " + affiliate.Status.ToString() + ". Expected: Current.", true);
|
||||
affiliate.Dispose(); affiliate = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
return affiliate;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SbmAssociation GetOrganisationAssociationForSignIn(SbmAccountMgr accountMgrForUser, Model_Security model, SbmAffiliate affiliateUser, List<SysIdString> supervisedOrganisations)
|
||||
{
|
||||
String fn = GetType().Name + ".GetOrganisationAssociationForSignIn";
|
||||
foreach (SysIdString supervisedOrganisation in supervisedOrganisations)
|
||||
{
|
||||
SbmAssociation associationOrganisation = accountMgrForUser.GetAssociationByOwnerTypeTarget(supervisedOrganisation.Id, Sbm.AssociationType.Internal, supervisedOrganisation.Id);
|
||||
if (associationOrganisation == null)
|
||||
{
|
||||
SaLogger.Warn(fn + " Failed to retrieve internal association for affiliate Id: " + SysId.ToString(supervisedOrganisation.Id));
|
||||
continue;
|
||||
}
|
||||
return associationOrganisation;
|
||||
}
|
||||
SaLogger.Warn(fn + " Failed to retrieve any internal associations for supervised organisations. Email: " + model.EmailAddress);
|
||||
return null;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Keep Logged In.
|
||||
//-------------------------------------------------------------------
|
||||
@@ -117,59 +225,6 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
return Json(responseData);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SaSecurityItem GetSecurityItemForSignin(SbmUserContext_Web userContext, Model_Security model, AjaxResponse_Data responseData)
|
||||
{
|
||||
String fn = GetType().Name + ".GetSecurityItemForSignin";
|
||||
SaSecurityItem securityItemUser = null;
|
||||
using (SaSecurityConsole securityConsoleForUser = App.CreateSecurityConsole(userContext))
|
||||
{
|
||||
// Retrieve security item by email address.
|
||||
using (securityItemUser = securityConsoleForUser.GetUserByEmail(model.EmailAddress))
|
||||
{
|
||||
if (securityItemUser != null)
|
||||
{
|
||||
// Validate password.
|
||||
if (!SbmPasswordHelper.VerifyHashedPassword(securityItemUser, model.Password) && !(DebugMode && model.EmailAddress.EqualsCI("ahoward@sarand.com")))
|
||||
{
|
||||
// Record invalid login attempt.
|
||||
securityItemUser.InvalidLoginCount++;
|
||||
securityItemUser.LastInvalidLoginAt = DateTime.Now;
|
||||
if (!securityConsoleForUser.UpdateSecurityItem(securityItemUser, DbUpdateInfo))
|
||||
SaLogger.Warn(fn + " Failed to store invalid sign-in attempt against User: " + model.EmailAddress + ". " + AccountMgr.ErrorStateMessage, true);
|
||||
SaLogger.Warn(fn + " Attempt to sign-in to User " + model.EmailAddress + " with invalid password. Attempt: " + securityItemUser.InvalidLoginCount, true);
|
||||
responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]);
|
||||
securityItemUser = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return securityItemUser;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private SbmAffiliate GetAffiliateForSignin(SbmUserContext_Web userContext, Model_Security model, SaSecurityItem securityItemUser, AjaxResponse_Data responseData)
|
||||
{
|
||||
String fn = GetType().Name + ".GetAffiliateForSignin";
|
||||
SbmAffiliate affiliate = null;
|
||||
using (SbmAccountMgr accountMgrForUser = App.System.CreateAccountMgr(userContext))
|
||||
{
|
||||
// Identify the contact asociated with the security item.
|
||||
SbmAffiliate.Params prmAffiliate = new SbmAffiliate.Params();
|
||||
prmAffiliate.UserId = securityItemUser.Id;
|
||||
prmAffiliate.StatusCat = SbmAffiliate.StatusCat.CurrentOnly;
|
||||
using (affiliate = accountMgrForUser.GetAffiliate(prmAffiliate))
|
||||
{
|
||||
if (affiliate != null)
|
||||
{
|
||||
}
|
||||
if (affiliate == null && !responseData.HasControlErrors())
|
||||
responseData.SetControlError(nameof(model.EmailAddress), model.Localiser["security.msg.signin.invalid"]);
|
||||
}
|
||||
}
|
||||
return affiliate;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Sign-out request.
|
||||
//-------------------------------------------------------------------
|
||||
@@ -185,7 +240,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
{
|
||||
String fn = GetType().Name + ".Ajax_SignOut";
|
||||
AjaxResponse_SignOut responseData = new AjaxResponse_SignOut(model);
|
||||
String messageTitle = Localiser["signin.caption.signout"];
|
||||
String messageTitle = Localiser["label.signout"];
|
||||
|
||||
// Validate session and referrer.
|
||||
if (!ValidReferer)
|
||||
@@ -454,7 +509,7 @@ namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Controllers
|
||||
responseData.SuccessMsg = Localiser["security.msg.request.password.email.sent"];
|
||||
return Json(responseData);
|
||||
}
|
||||
private void PopulateRequestPasswordEmailBody(SbmEmailConsole emailConsole, SbmUserContext userContext, SaEmailData emailData, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser)
|
||||
private void PopulateRequestPasswordEmailBody(SbmEmailConsole emailConsole, ISbmUserContext userContext, SaEmailData emailData, SaSecurityItem securityItemUser, SbmAffiliate affiliateUser)
|
||||
{
|
||||
// Will need to handle culture (language/country) as and when introduced.
|
||||
emailData.MessageBody = SbmResourceHelper.GetTextResource(SbmResourceHelper.TextResource.Email_RequestPassword_Html);
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
using Sarand.BusinessMgr.Net.Core.Web.App;
|
||||
using Sarand.BusinessMgr.Net.Core.Web.Controllers;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.App;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
|
||||
using Sarand.BusinessMgr.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sarand.BusinessMgr.Net.Core.Web.Portal.Models
|
||||
{
|
||||
//=======================================================================
|
||||
public class Model_Commodity : SbmModel_Portal
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public Model_Commodity(SbmLocaliser localiser) :
|
||||
base(localiser)
|
||||
{
|
||||
AdditionalFiles_JS.Add("js/sbm-commodity.js");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Filter properties.
|
||||
public class FilterData
|
||||
{
|
||||
public String CommoditySearch { get; set; }
|
||||
public String CommodityType { get; set; }
|
||||
}
|
||||
public FilterData Filter { get; } = new FilterData();
|
||||
public Sbm.CommodityType GetFilterCommodityType()
|
||||
{
|
||||
return (Sbm.CommodityType)Internals.CommodityTypeCodes.GetTypeForCode(Filter.CommodityType);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Commodity properties.
|
||||
public String CommodityId { get; set; }
|
||||
public String CommodityType{ get; set; }
|
||||
public Sbm.CommodityType GetCommodityType()
|
||||
{
|
||||
return (Sbm.CommodityType)Internals.CommodityTypeCodes.GetTypeForCode(CommodityType);
|
||||
}
|
||||
public String CommodityCode { get; set; }
|
||||
public String CommodityDesc { get; set; }
|
||||
// Common properties.
|
||||
public String CommodityNotes { get; set; }
|
||||
public String CommodityStatus { get; set; }
|
||||
public SaStatus GetCommodityStatus()
|
||||
{
|
||||
return SacsSystem.GetStatusForCode(CommodityStatus);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Validation.
|
||||
//-------------------------------------------------------------------
|
||||
// Commodity validation.
|
||||
public bool ValidateCommodityData(SbmController_Base.AjaxResponse_Data responseData)
|
||||
{
|
||||
// Commodity Type.
|
||||
if (CommodityType != null)
|
||||
{
|
||||
if (StringUtil.IsEmpty(CommodityType))
|
||||
responseData.SetControlError(nameof(CommodityType), Localiser["msg.validation.mandatory.value"]);
|
||||
}
|
||||
|
||||
// Commodity Code.
|
||||
if (CommodityCode != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(CommodityCode), CommodityCode);
|
||||
if (StringUtil.IsEmpty(CommodityCode))
|
||||
responseData.SetControlError(nameof(CommodityCode), Localiser["msg.validation.mandatory.value"]);
|
||||
if (StringUtil.GetLength(CommodityCode) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Code))
|
||||
responseData.SetControlError(nameof(CommodityCode), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Code)]);
|
||||
}
|
||||
|
||||
// Commodity Desc.
|
||||
if (CommodityDesc != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(CommodityDesc), CommodityDesc);
|
||||
if (StringUtil.IsEmpty(CommodityDesc))
|
||||
responseData.SetControlError(nameof(CommodityDesc), Localiser["msg.validation.mandatory.value"]);
|
||||
if (StringUtil.GetLength(CommodityDesc) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_DescBrief))
|
||||
responseData.SetControlError(nameof(CommodityDesc), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_DescBrief)]);
|
||||
}
|
||||
|
||||
// Commodity Notes.
|
||||
if (CommodityNotes != null)
|
||||
{
|
||||
responseData.SetControlValue(nameof(CommodityNotes), CommodityNotes);
|
||||
if (!StringUtil.IsEmpty(CommodityNotes) && StringUtil.GetLength(CommodityNotes) > GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Notes))
|
||||
responseData.SetControlError(nameof(CommodityNotes), Localiser["msg.validation.maximum.length", GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Notes)]);
|
||||
}
|
||||
|
||||
// Commodity status.
|
||||
if (CommodityStatus != null)
|
||||
{
|
||||
if (StringUtil.IsEmpty(CommodityStatus))
|
||||
responseData.SetControlError(nameof(CommodityStatus), Localiser["msg.validation.mandatory.value"]);
|
||||
else if (!SbmCommodity.ValidStatuses.Contains(GetCommodityStatus()))
|
||||
responseData.SetControlError(nameof(CommodityStatus), Localiser["msg.validation.invalid.value"]);
|
||||
}
|
||||
|
||||
return !responseData.HasControlErrors();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -37,7 +37,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\Commodity\" />
|
||||
<Folder Include="Views\Association\" />
|
||||
<Folder Include="Views\Transactions\" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
@model Model_Commodity
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Commodities - Index */
|
||||
ViewData["Title"] = "Commodities";
|
||||
}
|
||||
|
||||
<div class="sbm-page-commodities">
|
||||
|
||||
<script type="text/javascript">
|
||||
sbm.lbl.edit = 'Edit';
|
||||
sbm.lbl.activate = 'Activate';
|
||||
</script>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-5 row">
|
||||
|
||||
<div class="col">
|
||||
|
||||
@* Filter Panel *@
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodityFilter", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
<div class="sbm-panel-filter">
|
||||
@* Header - Page caption, paging controls, actions. *@
|
||||
<div class="sbm-header">
|
||||
<div class="row">
|
||||
<div class="col"><div class="sbm-caption">@Localiser["commodity.caption.commodities"]</div></div>
|
||||
<div class="fixed row">
|
||||
<div class="col">
|
||||
<partial name="~/Views/Common/ResultsPaging.cshtml" />
|
||||
</div>
|
||||
<div class="fixed row">
|
||||
<div class="sbm-action sbm-results-refresh"><img src="~/img/action/refresh24.png" alt="@(Localiser["label.refresh"])" title="@(Localiser["label.refresh"])" /></div>
|
||||
<div class="sbm-action sbm-item-create"><img src="~/img/action/add24.png" alt="@(Localiser["label.create"])" title="@(Localiser["label.create"])" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sbm-content">
|
||||
@* Commodity filter - name etc. *@
|
||||
<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.CommoditySearch, new { @id = "", @class = "FilterCommodity", @maxlength = "32" })
|
||||
</div>
|
||||
</div>
|
||||
@* Commodity Category *@
|
||||
<div class="row pb4">
|
||||
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-sm-7">
|
||||
@Html.DropDownListFor(model => model.Filter.CommodityType, Model.GetCommodityTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterCommodityType sbm-select" })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
@* Separate filter from results when alondside each other. *@
|
||||
<div class="fixed"><div class="d-none d-md-block" style="width:8px;"></div></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-7">
|
||||
|
||||
@* Results Panel *@
|
||||
<div class="sbm-panel-results">
|
||||
<div class="sbm-panel-messages"></div>
|
||||
<div class="sbm-panel-item-list"></div>
|
||||
|
||||
@* element templates *@
|
||||
<div class="sbm-panel-item-template">
|
||||
@* Commodity item template *@
|
||||
<div class="sbm-panel-item Commodity">
|
||||
<div class="sbm-header row">
|
||||
<div class="col">
|
||||
@* Commodity caption *@
|
||||
<div class="sbm-caption"><div class="sbm-action sbm-item-update CommodityName"></div></div>
|
||||
</div>
|
||||
<div class="fixed sbm-actions">
|
||||
@* 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="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 class="sbm-content">
|
||||
<div class="row">
|
||||
<div class="col-sm-4"><div class="CommodityType"></div></div>
|
||||
<div class="col-sm-4"><div class="CommodityAssociationCount sbm-action-text">@Localiser["label.associations"]: <span class="AssociationCount"></span></div></div>
|
||||
<div class="col-sm-4 text-left text-sm-right"><div class="StatusDesc"></div></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class=""><div class="CommodityAddress"></div></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class=""><div class="CommodityNotes sbm-note"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@* Burger dropdown item template - ul is ignored *@
|
||||
<ul class="sbm-dropdown-menu Commodity">
|
||||
<li class="sbm-dropdown-item sbm-action"><div class="sbm-label">XXX</div></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<partial name="Panel-CommodityDialog.cshtml" />
|
||||
@@ -0,0 +1,67 @@
|
||||
@model Model_Commodity
|
||||
@inject SbmLocaliser Localiser
|
||||
@{
|
||||
/* Commodities - Commodity dialog panel */
|
||||
}
|
||||
|
||||
<script type="text/javascript">
|
||||
sbm.dlg.title.createCommodity = '@Localiser.GetJavascriptText("commodity.caption.commodity.create")';
|
||||
sbm.dlg.title.updateCommodity = '@Localiser.GetJavascriptText("commodity.caption.commodity.update")';
|
||||
</script>
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodityId", @class = "sbm-form" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.CommodityId, new { @class = "CommodityId" })
|
||||
}
|
||||
<div id="dlgCommodity" class="sbm-dialog" title="">
|
||||
|
||||
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmCommodity", @class = "sbm-form", @onSubmit = "return false;" }))
|
||||
{
|
||||
@Html.HiddenFor(model => model.CommodityId, new { @id = "", @class = "CommodityId" })
|
||||
|
||||
@* Commodity Type *@
|
||||
<div class="sbm-form-control CommodityType">
|
||||
<div class="sbm-label">
|
||||
<label for="cbCommodityType"><span><span class="required">*</span> @Localiser["label.type"]</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.DropDownListFor(model => model.CommodityType, Model.GetCommodityTypeCodesForSelect(), Localiser["label.select"], new { @id = "cbCommodityType", @class = "CommodityType sbm-select" })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
@* Commodity Codeription *@
|
||||
<div class="sbm-form-control CommodityCode">
|
||||
<div class="sbm-label">
|
||||
<label for="ifCommodityCode"><span><span class="required">*</span> @Localiser["label.code"]</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.CommodityCode, new { @id = "ifCommodityCode", @class = "CommodityCode sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Code) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
@* Commodity Description *@
|
||||
<div class="sbm-form-control CommodityDesc">
|
||||
<div class="sbm-label">
|
||||
<label for="ifCommodityDesc"><span><span class="required">*</span> @Localiser["label.description"]</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextBoxFor(model => model.CommodityDesc, new { @id = "ifCommodityDesc", @class = "CommodityDesc sbm-input", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_DescBrief) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
@* Commodity Notes *@
|
||||
<div class="sbm-form-control CommodityNotes">
|
||||
<div class="sbm-label">
|
||||
<label for="ifCommodityNotes"><span><span class="required">*</span> @Localiser["label.notes"]</span></label>
|
||||
</div>
|
||||
<div class="sbm-control">
|
||||
@Html.TextAreaFor(model => model.CommodityNotes, new { @id = "ifCommodityNotes", @class = "CommodityNotes sbm-textarea", @maxlength = @Model.GetControlMaxLength(SbmDbDfn.ColumnIdx.Commodity_Notes) })
|
||||
</div>
|
||||
<div class="sbm-message"></div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
</div>
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
@* Affiliate Category *@
|
||||
<div class="row pb4">
|
||||
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.category"]</div>
|
||||
<div class="col-sm-5 sbm-label text-left text-sm-right">@Localiser["label.type"]</div>
|
||||
<div class="col-sm-7">
|
||||
@Html.DropDownListFor(model => model.Filter.AffiliateType, Model.GetAffiliateTypeCodesForSelect(), Localiser["label.any"], new { @id = "", @class = "FilterAffiliateType sbm-select" })
|
||||
</div>
|
||||
@@ -92,14 +92,15 @@
|
||||
<div class="sbm-content">
|
||||
<div class="row">
|
||||
<div class="col-sm-4"><div class="AffiliateType"></div></div>
|
||||
<div class="col-sm-4"><div class=""></div></div>
|
||||
<div class="col-sm-4 text-left text-sm-right"><div class=""></div></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4"><div class=""></div></div>
|
||||
<div class="col-sm-4"><div class="AffiliateAssociationCount sbm-action-text">@Localiser["label.associations"]: <span class="AssociationCount"></span></div></div>
|
||||
<div class="col-sm-4 text-left text-sm-right"><div class="StatusDesc"></div></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class=""><div class="AffiliateAddress"></div></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class=""><div class="AffiliateNotes sbm-note"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@* Burger dropdown item template - ul is ignored *@
|
||||
|
||||
@@ -121,8 +121,6 @@
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Contact');">@Localiser["label.contacts"]</div>
|
||||
</div>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Commodity');">@Localiser["label.commodities"]</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Commodity page scripts.
|
||||
*/
|
||||
|
||||
(function (win, doc, undef)
|
||||
{
|
||||
"use strict";
|
||||
sbm.itemIdPrefix = 'Itm_';
|
||||
var $results;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.refreshResults = function (delay)
|
||||
{
|
||||
if (!sbm.awaitingRefreshResponse)
|
||||
{
|
||||
var $items = $('.sbm-panel-item-list', $results).fadeOut(200).empty();
|
||||
var $msgs = $('.sbm-panel-messages', $results).hide().empty().append($('<div class="sbm-message">' + sbm.msg.dataQuerying + '</div>')).fadeIn(200);
|
||||
}
|
||||
sbm.ajax.refreshResults = sbm.ajax.refreshResults || { url: sbm.url.base + 'Commodity/Ajax/List', formId: 'frmCommodityFilter', callbackFn: sbm.doRefreshResults };
|
||||
sbm.doAjaxRequest(sbm.ajax.refreshResults, delay || 50);
|
||||
sbm.awaitingRefreshResponse = true;
|
||||
}
|
||||
sbm.getItemTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-panel-item.Commodity', $results);
|
||||
}
|
||||
sbm.getDropdownItemTemplate = function ()
|
||||
{
|
||||
return $('.sbm-panel-item-template .sbm-dropdown-menu.Commodity li.sbm-dropdown-item', $results);
|
||||
}
|
||||
sbm.doRefreshResults = function (response)
|
||||
{
|
||||
sbm.debug('doRefreshResults', response);
|
||||
delete sbm.awaitingRefreshResponse;
|
||||
sbm.refreshControlValues(response.controlValues);
|
||||
var $msgs = $('.sbm-panel-messages', $results).hide().empty();
|
||||
var $items = $('.sbm-panel-item-list', $results).hide().empty();
|
||||
var $tmpl = sbm.getItemTemplate();
|
||||
sbm.refreshPaging(response, '#frmCommodityFilter', sbm.refreshResults);
|
||||
if (!response.success) return;
|
||||
// Reference data - Statuses.
|
||||
if (response.defaultStatusCode) sbm.data.defaultStatusCode = response.defaultStatusCode;
|
||||
if (response.statuses)
|
||||
sbm.populateSelectCodeDesc('#cbCommodityStatus', response.statuses);
|
||||
// Items.
|
||||
var items = response.commodies;
|
||||
if (!items.length)
|
||||
return $msgs.append($('<div class="sbm-message">' + sbm.msg.dataNoneFound + '</div>')).fadeIn(500);
|
||||
for (let itemIdx = 0; itemIdx < items.length; itemIdx++)
|
||||
{
|
||||
let item = items[itemIdx];
|
||||
let $item = $tmpl.clone();
|
||||
sbm.populateItem($item, item);
|
||||
$items.append($item);
|
||||
}
|
||||
$items.fadeIn(50);
|
||||
}
|
||||
sbm.populateItem = function ($item, item)
|
||||
{
|
||||
if (!item) return;
|
||||
$item.prop('id', sbm.itemIdPrefix + item.id);
|
||||
$('.CommodityName', $item).text(item.displayName);
|
||||
$('.CommodityType', $item).text(item.typeDesc);
|
||||
$('.CommodityAssociationCount', $item).on('click', function () { sbm.onClickAssociationCount(item.id); }).toggle(item.associationCount).find('.AssociationCount').text(item.associationCount);
|
||||
$('.CommodityAddress', $item).text(item.addressSummary);
|
||||
$('.CommodityNotes', $item).text(item.notes);
|
||||
$('.StatusDesc', $item).text(item.statusDesc).addClass('sbm-status-' + item.statusCode.toLowerCase());
|
||||
$('.sbm-caption .sbm-action').toggleClass('sbm-action', !item.deleted);
|
||||
if (!item.deleted)
|
||||
{
|
||||
let $mnu = $('ul.sbm-dropdown-menu', $item);
|
||||
$mnu.append(sbm.getDropdownItemTemplate().clone().find('div.sbm-label').text(sbm.lbl.edit).end().on('click', function () { sbm.updateItem(item.id) }));
|
||||
if (item.awaiting)
|
||||
$mnu.append(sbm.getDropdownItemTemplate().clone().find('div.sbm-label').text(sbm.lbl.activate).end().on('click', function () { sbm.activateItem(item.id) }));
|
||||
$('.sbm-header .sbm-action.sbm-item-update', $item).off('click').on('click', function () { sbm.updateItem(item.id) });
|
||||
$item.off('dblclick').on('dblclick', function () { sbm.updateItem(item.id) });
|
||||
}
|
||||
$('.sbm-burger', $item).toggle(!!$('.sbm-burger .sbm-dropdown-menu .sbm-dropdown-item', $item).length);
|
||||
$('.sbm-panel-messages', $results).hide().empty();
|
||||
return $item;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.createItem = function ()
|
||||
{
|
||||
let $frm = sbm.$frm.commodity;
|
||||
$('.CommodityId,input[type="text"],textarea,select', $frm).val('');
|
||||
$('.CommodityStatus', $frm).val(sbm.data.defaultStatusCode);
|
||||
sbm.clearControlErrors();
|
||||
sbm.$dlg.commodity.dialog('option', 'title', sbm.dlg.title.createCommodity);
|
||||
sbm.openDialog(sbm.$dlg.commodity, 600, 600);
|
||||
}
|
||||
sbm.doCreateItem = function ()
|
||||
{
|
||||
sbm.storeItem();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.updateItem = function (id)
|
||||
{
|
||||
$('.CommodityId', sbm.$frm.commodityId).val(id);
|
||||
sbm.ajax.updateItem = sbm.ajax.updateItem || { url: sbm.url.base + 'Commodity/Ajax/GetItem', formId: 'frmCommodityId', callbackFn: sbm.onUpdateItem };
|
||||
sbm.doAjaxRequest(sbm.ajax.updateItem, 50);
|
||||
}
|
||||
sbm.onUpdateItem = function (response)
|
||||
{
|
||||
//sbm.debug('onUpdateItem', response);
|
||||
let $frm = sbm.$frm.commodity;
|
||||
$('.CommodityId,input[type="text"],textarea,select', $frm).val('');
|
||||
if (!response.success) return;
|
||||
let item = response.commodity;
|
||||
$('.CommodityId', $frm).val(item.id);
|
||||
$('.CommodityType', $frm).val(item.typeCode);
|
||||
$('.CommodityName', $frm).val(item.name);
|
||||
$('.CommodityNotes', $frm).val(item.notes);
|
||||
$('.CommodityStatus', $frm).val(item.statusCode);
|
||||
sbm.clearControlErrors();
|
||||
sbm.$dlg.commodity.dialog('option', 'title', sbm.dlg.title.updateCommodity);
|
||||
sbm.openDialog(sbm.$dlg.commodity, 600, 600);
|
||||
}
|
||||
sbm.doUpdateItem = function ()
|
||||
{
|
||||
sbm.storeItem();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.storeItem = function ()
|
||||
{
|
||||
sbm.ajax.storeItem = sbm.ajax.storeItem || { url: sbm.url.base + 'Commodity/Ajax/StoreItem', formId: 'frmCommodity', callbackFn: sbm.onStoreItem };
|
||||
sbm.doAjaxRequest(sbm.ajax.storeItem, 50);
|
||||
}
|
||||
sbm.onStoreItem = function (response)
|
||||
{
|
||||
//sbm.debug('onStoreItem', response);
|
||||
sbm.refreshControlValues(response.controlValues);
|
||||
if (!response.success) return;
|
||||
sbm.$dlg.commodity.dialog('close');
|
||||
|
||||
var item = response.commodity;
|
||||
var $item = $('#' + sbm.itemIdPrefix + item.id);
|
||||
if (!$item.length)
|
||||
{
|
||||
$item = $('.sbm-panel-item-template .sbm-panel-item.Commodity', $results).clone();
|
||||
$('.sbm-panel-item-list', $results).prepend($item).show();
|
||||
}
|
||||
$item.replaceWith(sbm.populateItem(sbm.getItemTemplate(), item));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
sbm.onClickAssociationCount = function (id)
|
||||
{
|
||||
if (!(id * 1)) return;
|
||||
sbm.doPleaseWait();
|
||||
let $frm = $('#frmCommodityId');
|
||||
$('.CommodityId', $frm).val(id);
|
||||
$frm.prop('action', sbm.url.base + 'Association').submit();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
$(function ()
|
||||
{
|
||||
$('.sbm-panel-filter .sbm-action.sbm-item-create').on('click', function () { sbm.createItem(); });
|
||||
$('.sbm-panel-filter .sbm-action.sbm-results-refresh').on('click', function () { sbm.refreshResults(); });
|
||||
$('.sbm-input, .sbm-textarea').on('input', function () { sbm.clearControlError(this); });
|
||||
$('.sbm-select').on('change', function () { sbm.clearControlError(this); });
|
||||
|
||||
sbm.$frm.filter = $('#frmCommodityFilter');
|
||||
$('.FilterCommodity', sbm.$frm.filter).on('input', function () { sbm.refreshResults(250); });
|
||||
$('.FilterCommodityCategory,.FilterCommodityStatusCategory', sbm.$frm.filter).on('change', function () { sbm.refreshResults(50); });
|
||||
sbm.$frm.commodityId = $('#frmCommodityId');
|
||||
sbm.$frm.commodity = $('#frmCommodity');
|
||||
$results = $('.sbm-panel-results');
|
||||
|
||||
var opt = sbm.dlgOpts();
|
||||
opt.buttons[sbm.dlg.btn.ok] = function () { sbm.doCreateItem(); };
|
||||
opt.buttons[sbm.dlg.btn.cancel] = function () { $(this).dialog('close'); };
|
||||
sbm.$dlg.commodity = $('#dlgCommodity').dialog(opt);
|
||||
|
||||
setTimeout(sbm.refreshResults, 250);
|
||||
});
|
||||
|
||||
}(window, window.document));
|
||||
|
||||
/* The End */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Admin - Affiliate page scripts.
|
||||
* Contact page scripts.
|
||||
*/
|
||||
|
||||
(function (win, doc, undef)
|
||||
@@ -61,7 +61,9 @@
|
||||
$item.prop('id', sbm.itemIdPrefix + item.id);
|
||||
$('.AffiliateName', $item).text(item.displayName);
|
||||
$('.AffiliateType', $item).text(item.typeDesc);
|
||||
$('.AffiliateAssociationCount', $item).on('click', function () { sbm.onClickAssociationCount(item.id); }).find('.AssociationCount').text(item.associationCount);
|
||||
$('.AffiliateAssociationCount', $item).on('click', function () { sbm.onClickAssociationCount(item.id); }).toggle(item.associationCount).find('.AssociationCount').text(item.associationCount);
|
||||
$('.AffiliateAddress', $item).text(item.addressSummary);
|
||||
$('.AffiliateNotes', $item).text(item.notes);
|
||||
$('.StatusDesc', $item).text(item.statusDesc).addClass('sbm-status-' + item.statusCode.toLowerCase());
|
||||
$('.sbm-caption .sbm-action').toggleClass('sbm-action', !item.deleted);
|
||||
if (!item.deleted)
|
||||
|
||||
Reference in New Issue
Block a user