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 - Ajax - Members //======================================================================= partial class OrganisationController { //------------------------------------------------------------------- // Member data. private class MemberListData : 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 MemberItemData : MemberListData { // Organisation user. public List RoleCodes { get; } = new List(); } private void PopulateMemberResponseListData(MemberListData data, SaxUserOrganisation userOrganisation, SaxUserAccount userAccount, SaxOrganisation organisation) { data.Id = SysId.ToString(userOrganisation.Id); // User. data.UserAccountId = SysId.ToString(userAccount.Id); if (userAccount.Id.Equals(SessionUserAccountId)) 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 PopulateMemberResponseItemData(MemberItemData data, SaxUserOrganisation userOrganisation, SaxUserAccount userAccount, SaxOrganisation organisation) { PopulateMemberResponseListData(data, 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 Members { get; } = new List(); // Reference data. public List MemberRoles { get; } = new List(); public List Statuses { get; } = new List(); 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["caption.organisation.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, false); 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 members, bool inactiveOnly) { // Item filter. SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params(); prmUserOrganisation.OrganisationIdsIncluded.Add(organisationId); prmUserOrganisation.OrganisationMembersOnly = true; prmUserOrganisation.UserAccountStatusCat = inactiveOnly ? SaxUserAccount.StatusCat.InactiveOnly : 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 columns = new List() { 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(); MemberListData memberData = new MemberListData() { 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 MemberItemData Member { get; } = new MemberItemData(); } //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/GetMember")] public IActionResult Ajax_GetMember(Model_OrganisationMembers model) { String fn = GetType().Name + ".Ajax_GetItem"; String messageTitle = Localiser["caption.organisation.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 disposableItems = new DisposableCollection()) { // 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. PopulateMemberResponseItemData(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["caption.organisation.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 disposableItems = new DisposableCollection()) { // 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. PopulateMemberResponseItemData(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["caption.organisation.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 disposableItems = new DisposableCollection()) { // 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. PopulateMemberResponseItemData(responseData.Member, userOrganisation, userAccount, organisation); } responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }