Files
Saxonite/SaxoniteCoreWebAdmin/Admin/Controllers/OrganisationController-Members-Ajax.cs
T
2022-05-19 13:41:22 +01:00

471 lines
21 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Net.Core.Web.Admin.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Admin.Controllers
{
//=======================================================================
// Controller: Organisation - Members - Ajax
//=======================================================================
partial class OrganisationController
{
//-------------------------------------------------------------------
// Member data.
private class MemberData_List : AjaxResponse_Data.ItemData_Base
{
// User.
public String UserAccountId { get; set; }
public bool? Self { get; set; } = null;
public String EmailAddress { get; set; }
public String DisplayName { get; set; }
public String UserStatusCode { get; set; }
public String UserStatusDesc { get; set; }
public bool? UserActive { get { return UserStatusCode.EqualsCI(SacsSystem.GetStatusCode(SaStatus.Active)) ? true : (bool?)null; } }
// Organisation.
public String OrganisationId { get; set; }
public String OrganisationName { get; set; }
// Organisation user.
public int RoleCount { get; set; }
public bool? Member { get; set; } = null;
}
private class MemberData_Full : MemberData_List
{
// Organisation user.
public List<String> RoleCodes { get; } = new List<string>();
}
private void PopulateMemberResponseData(MemberData_List data, SaxUserOrganisation userOrganisation, SaxUserAccount userAccount, SaxOrganisation organisation)
{
data.Id = SysId.ToString(userOrganisation.Id);
// User.
data.UserAccountId = SysId.ToString(userAccount.Id);
if (userAccount.Id.Equals(UserAccountId)) data.Self = true;
data.EmailAddress = userAccount.EmailAddress;
data.DisplayName = userAccount.GetDisplayName();
data.UserStatusCode = userAccount.StatusCode;
data.UserStatusDesc = userAccount.StatusDesc;
// Organisation.
data.OrganisationId = SysId.ToString(organisation.Id);
data.OrganisationName = organisation.Name;
// Organisation user:
data.RoleCount = userOrganisation.OrganisationRoleCount - 1;
data.StatusCode = userOrganisation.StatusCode;
data.StatusDesc = userOrganisation.StatusDesc;
if (userOrganisation.GetOrganisationRoles().ToList().Exists(item => item == Sax.OrganisationRole.Member))
data.Member = true;
}
private void PopulateMemberResponseData(MemberData_Full data, SaxUserOrganisation userOrganisation, SaxUserAccount userAccount, SaxOrganisation organisation)
{
PopulateMemberResponseData(data as MemberData_List, userOrganisation, userAccount, organisation);
// Organisation user:
// Exclude 'Member' role.
foreach (Sax.OrganisationRole organisationRole in userOrganisation.GetOrganisationRoles().ToList().FindAll(item => item != Sax.OrganisationRole.Member))
data.RoleCodes.Add(OrganisationRoleCodes.GetCodeForType(organisationRole));
}
//-------------------------------------------------------------------
// Get Organisation Member List ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_MemberList : AjaxResponse_Data
{
// Construction.
public AjaxResponse_MemberList(SaxModel_Admin model) : base(model) { }
// Member list.
public List<MemberData_List> Members { get; } = new List<MemberData_List>();
// Reference data.
public List<CodeDesc> MemberRoles { get; } = new List<CodeDesc>();
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
public String DefaultStatusCode { get; set; }
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Organisation/Ajax/GetMemberList")]
public IActionResult Ajax_GetMemberList(Model_OrganisationMembers model)
{
String fn = GetType().Name + ".Ajax_GetMemberList";
String messageTitle = Localiser["organisation.caption.members"];
AjaxResponse_MemberList responseData = new AjaxResponse_MemberList(model);
// Validate session.
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Organisation Id filter is mandatory.
SysId organisationId = model.Filter.OrganisationId.ToSysId();
if (!SysId.IsValid(organisationId))
{
SaLogger.Warn(fn + " Request to retrieve members without valid organisation Id.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
}
// Reference data - organisation roles.
// Exclude 'Member' as this is added automatically when stored.
foreach (TypeCodeDesc organisationRole in OrganisationRoleCodes.FindAll(item => item.Type != (int)Sax.OrganisationRole.Member))
responseData.MemberRoles.Add(organisationRole.Code, Localiser.GetOrganisationRoleCaption((Sax.OrganisationRole)organisationRole.Type));
// Reference data - statuses.
foreach (SaStatus status in SaxUserOrganisation.ValidStatuses.FindAll(item => item != SaStatus.Deleted))
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SaxUserOrganisation.DefaultStatus);
// Get organisation members.
GetOrganisationMembers(model, organisationId, responseData.Members);
if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Members.Count;
// Complete response.
responseData.SetPaging(model);
responseData.Success = true;
return Json(responseData);
}
private void GetOrganisationMembers(SaxModel_Admin model, SysId organisationId, List<MemberData_List> members)
{
// Item filter.
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
prmUserOrganisation.OrganisationIdsIncluded.Add(organisationId);
prmUserOrganisation.OrganisationMembersOnly = true;
prmUserOrganisation.UserAccountStatusCat = SaxUserAccount.StatusCat.NotDeleted;
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.NotDeleted;
model.Paging.ItemTotal = (ulong)AccountMgr.GetUserOrganisationCount(prmUserOrganisation);
model.PopulatePagingTo(prmUserOrganisation.ResultsPaging);
// Item columns.
ColumnDfn colId = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Id);
ColumnDfn colUserAccountId = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.UserAccountId);
ColumnDfn colUserEmailAddress = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.User_EmailAddress);
ColumnDfn colUserDisplayName = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.User_DisplayName);
ColumnDfn colUserStatus = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.User_Status);
ColumnDfn colOrganisationId = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationId);
ColumnDfn colOrganisationName = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Organisation_Name);
ColumnDfn colRoleCodes = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationRoleCodes);
ColumnDfn colRoleCount = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.OrganisationRoleCount);
ColumnDfn colStatus = AccountMgr.GetUserOrganisationColumnDfn(SaxUserOrganisation.Column.Status);
List<ColumnDfn> columns = new List<ColumnDfn>()
{
colId, colUserAccountId,
colUserEmailAddress, colUserDisplayName, colUserStatus,
colOrganisationId, colOrganisationName,
colRoleCodes, colRoleCount,
colStatus
};
// Query items.
using (DbResultSet resultSet = AccountMgr.ExecuteUserOrganisationQuery(columns, prmUserOrganisation))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
MemberData_List memberData = new MemberData_List()
{
Id = values.GetString(colId.DataName),
// User.
UserAccountId = values.GetString(colUserAccountId.DataName),
EmailAddress = values.GetString(colUserEmailAddress.DataName),
DisplayName = AccountMgr.GetUserOrganisationDataValue(colUserDisplayName, values).ToString(),
UserStatusCode = values.GetString(colUserStatus.DataName),
UserStatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colUserStatus.DataName)),
// Organisation.
OrganisationId = values.GetString(colOrganisationId.DataName),
OrganisationName = values.GetString(colOrganisationName.DataName),
// Role count - 1 to ignore 'Member' role.
RoleCount = (int)values.GetLong(colRoleCount.DataName) - 1,
StatusCode = values.GetString(colStatus.DataName),
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)),
Member = (values.GetLong(colRoleCount.DataName) > 0) ? true : (bool?)null
};
members.Add(memberData);
}
}
}
//-------------------------------------------------------------------
// Get Organisation Member ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_Member : AjaxResponse_Data
{
// Construction.
public AjaxResponse_Member(SaxModel_Admin model) : base(model) { }
// Member details.
public MemberData_Full Member { get; } = new MemberData_Full();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Organisation/Ajax/GetMember")]
public IActionResult Ajax_GetMember(Model_OrganisationMembers model)
{
String fn = GetType().Name + ".Ajax_GetItem";
String messageTitle = Localiser["organisation.caption.member"];
AjaxResponse_Member responseData = new AjaxResponse_Member(model);
// Validate session.
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{
// Identify item.
SysId userOrganisationId = model.UserOrganisationId.ToSysId();
if (!SysId.IsValid(userOrganisationId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
// Retrieve item.
SaxUserOrganisation userOrganisation = AccountMgr.GetUserOrganisationById(userOrganisationId);
disposableItems.Add(userOrganisation);
if (userOrganisation == null)
{
SaLogger.Warn(fn + " Failed to retrieve User Organisation for Id: '" + model.UserOrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Retrieve User Account.
SaxUserAccount userAccount = AccountMgr.GetUserAccountById(userOrganisation.UserAccountId);
disposableItems.Add(userAccount);
if (userAccount == null)
{
SaLogger.Warn(fn + " Failed to retrieve user account for Id: '" + userOrganisation.UserAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Retrieve Organisation.
SaxOrganisation organisation = AccountMgr.GetOrganisationById(userOrganisation.OrganisationId);
disposableItems.Add(organisation);
if (organisation == null)
{
SaLogger.Warn(fn + " Failed to retrieve organisation for Id: '" + userOrganisation.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Construct response.
PopulateMemberResponseData(responseData.Member, userOrganisation, userAccount, organisation);
}
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
// Store Organisation Member ajax request.
//-------------------------------------------------------------------
[HttpPost]
[Route("Organisation/Ajax/StoreMember")]
public IActionResult Ajax_StoreMember(Model_OrganisationMembers model)
{
String fn = GetType().Name + ".Ajax_StoreMember";
String messageTitle = Localiser["organisation.caption.member"];
AjaxResponse_Member responseData = new AjaxResponse_Member(model);
// Validate session.
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Validate item properties.
model.ValidateOrganisationMemberData(responseData);
if (responseData.HasControlErrors())
return Json(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{
// User account.
SysId userAccountId = model.MemberUserAccountId.ToSysId();
SaxUserAccount userAccount = null;
if (!SysId.IsValid(userAccountId) && !StringUtil.IsEmpty(model.MemberUserEmailAddress))
{
userAccount = AccountMgr.GetUserAccountByEmailAddress(model.MemberUserEmailAddress);
disposableItems.Add(userAccount);
userAccountId = userAccount?.Id ?? new SysId();
}
if (!SysId.IsValid(userAccountId))
{
SaLogger.Warn(fn + " User Account must be identified");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.incomplete"]));
}
// Organisation.
SysId organisationId = model.MemberOrganisationId.ToSysId();
SaxOrganisation organisation = null;
if (!SysId.IsValid(organisationId))
{
SaLogger.Warn(fn + " Organisation Id must be specified");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.incomplete"]));
}
// Retrieve existing item.
SysId userOrganisationId = model.UserOrganisationId.ToSysId();
SaxUserOrganisation userOrganisation = AccountMgr.GetUserOrganisationById(userOrganisationId);
disposableItems.Add(userOrganisation);
if (userOrganisation == null && SysId.IsValid(userOrganisationId))
{
SaLogger.Warn(fn + " Failed to retrieve user organisation for Id: '" + userOrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
if (userOrganisation != null && (!userOrganisation.UserAccountId.Equals(userAccountId) || !userOrganisation.OrganisationId.Equals(organisationId)))
{
// Either User Account and/or Organisation Ids don't match.
SaLogger.Warn(fn + " Inconsistent user organisation properties. UserAccountId: " + userOrganisation.UserAccountId + " vs " + userAccountId + ". OrganisationId: " + userOrganisation.OrganisationId + " vs " + organisationId + ".");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// User Organisation not identified.
if (userOrganisation == null)
{
// See whether user has an 'interest' in the organisation.
SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params();
prmUserOrganisation.UserAccountIdsIncluded.Add(userAccountId);
prmUserOrganisation.OrganisationIdsIncluded.Add(organisationId);
prmUserOrganisation.OrganisationMembersOnly = false;
prmUserOrganisation.StatusCat = SaxUserOrganisation.StatusCat.Any;
userOrganisation = AccountMgr.GetUserOrganisation(prmUserOrganisation);
if (userOrganisation != null)
userOrganisation.Status = SaStatus.Active;
else
// Organisation not found for user.
userOrganisation = AccountMgr.CreateUserOrganisation(userAccountId, organisationId);
disposableItems.Add(userOrganisation);
}
// Retrieve associated items.
if (userAccount == null)
{
userAccount = AccountMgr.GetUserAccountById(userAccountId);
disposableItems.Add(userAccount);
}
if (organisation == null)
{
organisation = AccountMgr.GetOrganisationById(organisationId);
disposableItems.Add(organisation);
}
// Populate item properties.
if (model.MemberRoleCodes != null)
userOrganisation.OrganisationRoles = SaxUserOrganisation.GetOrganisationRolesFromCodes(model.GetMemberRoleCodes());
userOrganisation.AddOrganisationRole(Sax.OrganisationRole.Member);
if (model.MemberStatusCode != null)
userOrganisation.Status = model.MemberStatus;
// Store item.
if (!SysId.IsValid(userOrganisation.Id))
{
if (!AccountMgr.InsertUserOrganisation(userOrganisation, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to insert user organisation: " + AccountMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
}
}
else
{
if (!AccountMgr.UpdateUserOrganisation(userOrganisation, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to update user organisation [Id:" + SysId.ToString(userOrganisation.Id) + "]: " + AccountMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
}
}
// Construct response.
PopulateMemberResponseData(responseData.Member, userOrganisation, userAccount, organisation);
}
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
// Remove Organisation Member ajax request.
//-------------------------------------------------------------------
[HttpPost]
[Route("Organisation/Ajax/RemoveMember")]
public IActionResult Ajax_RemoveMember(Model_OrganisationMembers model)
{
String fn = GetType().Name + ".Ajax_RemoveMember";
String messageTitle = Localiser["organisation.caption.member"];
AjaxResponse_Member responseData = new AjaxResponse_Member(model);
// Validate session.
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{
// Organisation.
SysId organisationId = model.OrganisationId.ToSysId();
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
if (organisation == null)
{
SaLogger.Warn(fn + " Failed to retrieve Organisation for Id: '" + model.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.incomplete"]));
}
disposableItems.Add(organisation);
// User Organisation.
SysId userOrganisationId = model.UserOrganisationId.ToSysId();
SaxUserOrganisation userOrganisation = AccountMgr.GetUserOrganisationById(userOrganisationId);
disposableItems.Add(userOrganisation);
if (userOrganisation == null)
{
SaLogger.Warn(fn + " Failed to retrieve user organisation for Id: '" + userOrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
if (!userOrganisation.OrganisationId.Equals(organisation.Id))
{
SaLogger.Warn(fn + " Inconsistent user organisation properties. OrganisationId: " + userOrganisation.OrganisationId + " vs " + organisation.Id + ".");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.data.inconsistent"]));
}
// User Account.
SaxUserAccount userAccount = AccountMgr.GetUserAccountById(userOrganisation.UserAccountId);
disposableItems.Add(userAccount);
if (userAccount == null)
{
SaLogger.Warn(fn + " Failed to retrieve user account for Id: '" + userOrganisation.UserAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Remove all roles and store.
userOrganisation.ClearOrganisationRoles();
// Store item.
if (!SysId.IsValid(userOrganisation.Id))
{
if (!AccountMgr.InsertUserOrganisation(userOrganisation, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to insert user organisation: " + AccountMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
}
}
else
{
if (!AccountMgr.UpdateUserOrganisation(userOrganisation, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to update user organisation [Id:" + SysId.ToString(userOrganisation.Id) + "]: " + AccountMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + AccountMgr.ErrorStateMessage));
}
}
// Construct response.
PopulateMemberResponseData(responseData.Member, userOrganisation, userAccount, organisation);
}
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
}
//=======================================================================
}