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 { public String Id { get; set; } public String UserAccountId { get; set; } public String EmailAddress { get; set; } public String DisplayName { get; set; } public String OrganisationId { get; set; } public String OrganisationName { get; set; } public List RoleCodes { get; } = new List(); public int RoleCount { get; set; } public String StatusCode { get; set; } public String StatusDesc { get; set; } } private class MemberData_Full : MemberData_List { } private void PopulateMemberResponseData(MemberData_List data, SaxUserOrganisation userOrganisation, SaxUserAccount userAccount, SaxOrganisation organisation) { data.Id = SysId.ToString(userOrganisation.Id); data.UserAccountId = SysId.ToString(userAccount.Id); data.EmailAddress = userAccount.EmailAddress; data.DisplayName = userAccount.GetDisplayName(); data.OrganisationId = SysId.ToString(organisation.Id); data.OrganisationName = organisation.Name; // Exclude 'Member' role. foreach (Sax.OrganisationRole organisationRole in userOrganisation.GetOrganisationRoles().ToList().FindAll(item => item != Sax.OrganisationRole.Member)) data.RoleCodes.Add(OrganisationRoleCodes.GetCodeForType(organisationRole)); data.RoleCount = userOrganisation.OrganisationRoleCount - 1; data.StatusCode = userOrganisation.StatusCode; data.StatusDesc = userOrganisation.StatusDesc; } private void PopulateMemberResponseData(MemberData_Full data, SaxUserOrganisation userOrganisation, SaxUserAccount userAccount, SaxOrganisation organisation) { PopulateMemberResponseData(data as MemberData_List, userOrganisation, userAccount, organisation); } //------------------------------------------------------------------- // 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["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 members) { // Item filter. SaxUserOrganisation.Params prmUserOrganisation = new SaxUserOrganisation.Params(); prmUserOrganisation.OrganisationIdsIncluded.Add(organisationId); prmUserOrganisation.OrganisationMembersOnly = true; prmUserOrganisation.UserAccountStatusCat = SaxUserAccount.StatusCat.AwaitingOnly; 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 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, 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), UserAccountId = values.GetString(colUserAccountId.DataName), EmailAddress = values.GetString(colUserEmailAddress.DataName), DisplayName = AccountMgr.GetUserOrganisationDataValue(colUserDisplayName, values).ToString(), 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)) }; 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 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. 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 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. PopulateMemberResponseData(responseData.Member, userOrganisation, userAccount, organisation); } responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }