using DocumentFormat.OpenXml.Spreadsheet; using Microsoft.AspNetCore.Mvc; using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; using Sarand.BusinessMgr.Web.Control.Components; using Sarand.BusinessMgr.Web.Control.Models.Account; 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 System; using System.Collections.Generic; using System.Linq; namespace Sarand.BusinessMgr.Web.Control.Controllers.Account { //======================================================================= partial class UserAccountController { //------------------------------------------------------------------- // Definitions. // User data. private class UserListData : AjaxResponse_Data.ItemData_Base { public String EmailAddress { get; set; } public String DisplayName { get; set; } public String Title { get; set; } public String FirstName { get; set; } public String LastName { get; set; } public String Phone { get; set; } public String LastLoginOn { get; set; } public String LastLoginAt { get; set; } } private class UserItemData : UserListData { public String Initials { get; set; } public String PhoneMain { get; set; } public String PhoneMobile { get; set; } public String PhoneAlt { get; set; } } private void PopulateUserResponseListData(SbmModel_Control model, UserListData data, SbmcUserAccount user) { data.Id = SysId.ToString(user.Id); data.EmailAddress = user.EmailAddress; data.DisplayName = user.GetDisplayName(); data.Title = user.Title; data.FirstName = user.FirstName; data.LastName = user.LastName; data.Phone = StringUtil.OnBlank(user.PhoneMain, user.PhoneMobile, user.PhoneAlt); data.LastLoginOn = model.FormatDateForDisplay(user.LastLoginAt); data.LastLoginAt = model.FormatDateTimeForDisplay(user.LastLoginAt); data.StatusCode = user.StatusCode; data.StatusDesc = user.StatusDesc; } private void PopulateUserResponseItemData(SbmModel_Control model, UserItemData data, SbmcUserAccount user) { PopulateUserResponseListData(model, data, user); data.Initials = user.Initials; data.PhoneMain = user.PhoneMain; data.PhoneMobile = user.PhoneMobile; data.PhoneAlt = user.PhoneAlt; } //------------------------------------------------------------------- // Get User List ajax request. //------------------------------------------------------------------- private class AjaxResponse_UserList : AjaxResponse_Data { // Construction. public AjaxResponse_UserList(SbmModel_Control model) : base(model) { } // User list. public List Users { get; } = new List(); // Reference data. public List Statuses { get; } = new List(); public List StatusesCreate { get; } = new List(); public String StatusCodeDefault { get; set; } } //------------------------------------------------------------------- [HttpPost] [Route("Account/UserAccount/Ajax/GetList")] [Route("Account/UserAccount/Ajax/GetUsers")] [Route("Account/UserAccount/Ajax/GetUserList")] public IActionResult Ajax_GetUserList(Model_UserAccount model) { String messageTitle = Localiser["label.users"]; AjaxResponse_UserList responseData = new AjaxResponse_UserList(model); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); // Reference data - statuses. foreach (SaStatus status in SbmcUserAccount.ValidStatuses) { responseData.Statuses.Add(new AjaxResponse_Data.ItemCodeDesc(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status))); if (status != SaStatus.Deleted) responseData.StatusesCreate.Add(new AjaxResponse_Data.ItemCodeDesc(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status))); } responseData.StatusCodeDefault = SacsSystem.GetStatusCode(SbmcUserAccount.DefaultStatus); // Item filter. SbmcUserAccount.Params prmUserAccount = new SbmcUserAccount.Params(); prmUserAccount.Search = model.Filter.Search; prmUserAccount.StatusCat = model.Filter.GetStatusCat(); model.Paging.ItemTotal = (ulong)ControlAccountMgr.GetUserAccountCount(prmUserAccount); model.PopulatePagingTo(prmUserAccount.ResultsPaging); // Item columns. ColumnDfn colId = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.Id); ColumnDfn colEmail = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.EmailAddress); ColumnDfn colTitle = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.Title); ColumnDfn colFirstName = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.FirstName); ColumnDfn colLastName = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.LastName); ColumnDfn colPhoneMain = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.PhoneMain); ColumnDfn colPhoneMobile = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.PhoneMobile); ColumnDfn colPhoneAlt = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.PhoneAlt); ColumnDfn colLastLogin = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.LastLoginAt); ColumnDfn colStatus = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.Status); List columns = new List() { colId, colEmail, colTitle, colFirstName, colLastName, colPhoneMain, colPhoneMobile, colPhoneAlt, colLastLogin, colStatus }; // Query items. using (DbResultSet resultSet = ControlAccountMgr.ExecuteUserAccountQuery(columns, prmUserAccount)) { while (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) { NamedValue.Map values = resultSet.GetRecordValues(); UserListData userData = new UserListData() { Id = values.GetString(colId.DataName), EmailAddress = values.GetString(colEmail.DataName), Title = values.GetString(colTitle.DataName), FirstName = values.GetString(colFirstName.DataName), LastName = values.GetString(colLastName.DataName), Phone = StringUtil.OnBlank(values.GetString(colPhoneMain.DataName), values.GetString(colPhoneMobile.DataName), values.GetString(colPhoneAlt.DataName)), LastLoginOn = model.FormatDateForDisplay(values.GetDateTime(colLastLogin.DataName)), LastLoginAt = model.FormatDateTimeForDisplay(values.GetDateTime(colLastLogin.DataName)), StatusCode = values.GetString(colStatus.DataName), StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)) }; userData.DisplayName = SbmcUserAccount.GetDisplayName(userData.FirstName, userData.LastName); responseData.Users.Add(userData); } } if (model.Paging.IsPaged) model.Paging.ItemCount = (ushort)responseData.Users.Count; // Complete response. responseData.SetPaging(model); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Get User ajax request. //------------------------------------------------------------------- private class AjaxResponse_User : AjaxResponse_Data { // Construction. public AjaxResponse_User(SbmModel_Control model) : base(model) { } // User details. public UserItemData user { get; } = new UserItemData(); } //------------------------------------------------------------------- [HttpPost] [Route("Account/UserAccount/Ajax/GetItem")] [Route("Account/UserAccount/Ajax/GetUser")] public IActionResult Ajax_GetUser(Model_UserAccount model) { String messageTitle = Localiser["label.user"]; AjaxResponse_User responseData = new AjaxResponse_User(model); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposables = new DisposableCollection()) { // Identify item. SysId userAccountId = SysId.ToSysId(model.User.Id); if (!SysId.IsValid(userAccountId)) return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); // Retrieve item. SbmcUserAccount user = ControlAccountMgr.GetUserAccountById(userAccountId); if (user == null) { SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve user for Id: '" + userAccountId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Construct response. PopulateUserResponseItemData(model, responseData.user, user); responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- // Get User by email ajax request. //------------------------------------------------------------------- [HttpPost] [Route("Account/UserAccount/Ajax/GetUserByEmail")] public IActionResult Ajax_GetUserByEmail(Model_UserAccount model) { String messageTitle = Localiser["label.user"]; AjaxResponse_User responseData = new AjaxResponse_User(model); StoreSessionData = false; // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposables = new DisposableCollection()) { // Identify user. if (StringUtil.IsEmpty(model.Filter.EmailAddress)) { SaLogger.Warn($"{SysUtil.Fn} Attempt to get user details with blank email."); return Json(responseData); } // Retrieve user. SbmcUserAccount user = ControlAccountMgr.GetUserAccountByEmailAddress(model.Filter.EmailAddress); if (user == null) { SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve user for Email: " + model.Filter.EmailAddress); return Json(responseData); } // Construct response. PopulateUserResponseItemData(model, responseData.user, user); responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- // Store User ajax request. //------------------------------------------------------------------- [HttpPost] [Route("Account/UserAccount/Ajax/StoreItem")] [Route("Account/UserAccount/Ajax/StoreUser")] public IActionResult Ajax_StoreUser(Model_UserAccount model) { String messageTitle = Localiser["label.user"]; AjaxResponse_User responseData = new AjaxResponse_User(model); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); // Validate item Id. SysId userAccountId = SysId.ToSysId(model.User.Id); if (StringUtil.ToBool(model.User.Exists) && !SysId.IsValid(userAccountId)) { SaLogger.Warn($"{SysUtil.Fn} User Id not supplied for existing item."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } if (!StringUtil.ToBool(model.User.Exists) && SysId.IsValid(userAccountId)) { SaLogger.Warn($"{SysUtil.Fn} User Id supplied for new item."); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"])); } // Validate item properties. model.ValidateUserData(responseData); if (responseData.HasControlErrors()) return Json(responseData); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposables = new DisposableCollection()) { // Retrieve existing item. SbmcUserAccount user = ControlAccountMgr.GetUserAccountById(userAccountId); if (user == null && SysId.IsValid(userAccountId)) { SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve user for Id: '" + model.User.Id + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Create new item if required. if (user == null) { user = ControlAccountMgr.CreateUserAccount(); if (model.User.EmailAddress != null) user.EmailAddress = model.User.EmailAddress; } // Populate item properties. if (model.User.Title != null) user.Title = model.User.Title; if (model.User.FirstName != null) user.FirstName = model.User.FirstName; if (model.User.Initials != null) user.Initials = model.User.Initials; if (model.User.LastName != null) user.LastName = model.User.LastName; if (model.User.PhoneMain != null) user.PhoneMain = model.User.PhoneMain; if (model.User.PhoneMobile != null) user.PhoneMobile = model.User.PhoneMobile; if (model.User.PhoneAlt != null) user.PhoneAlt = model.User.PhoneAlt; if (model.User.StatusCode != null) user.Status = model.User.GetStatus(); // Store item. if (!SysId.IsValid(user.Id)) { if (!ControlAccountMgr.InsertUserAccount(user, DbUpdateInfo)) { SaLogger.Warn($"{SysUtil.Fn} Failed to insert user: " + ControlAccountMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + ControlAccountMgr.ErrorStateMessage)); } responseData.SetNotification(messageTitle, Localiser["msg.item.created"]); } else { if (!ControlAccountMgr.UpdateUserAccount(user, DbUpdateInfo)) { SaLogger.Warn($"{SysUtil.Fn} Failed to update user [Id:" + SysId.ToString(user.Id) + "]: " + ControlAccountMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + ControlAccountMgr.ErrorStateMessage)); } responseData.SetNotification(messageTitle, Localiser["msg.item.updated"]); } // Construct response. PopulateUserResponseItemData(model, responseData.user, user); responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- // Send User Emails ajax request. //------------------------------------------------------------------- [HttpPost] [Route("Account/UserAccount/Ajax/SendEmails")] public IActionResult Ajax_SendEmails(Model_UserAccount model) { String messageTitle = Localiser["label.emails"]; AjaxResponse_User responseData = new AjaxResponse_User(model); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposables = new DisposableCollection()) { // Retrieve user. SysId userAccountId = SysId.ToSysId(model.User.Id); SbmcUserAccount userAccount = ControlAccountMgr.GetUserAccountById(userAccountId); if (userAccount == null) { SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve user for Id: '" + model.User.Id + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Email types to send. bool sendAcountActivationPortal = StringUtil.ToBool(model.UserEmailAcountActivationPortal); bool sendRequestPasswordPortal = StringUtil.ToBool(model.UserEmailRequestPasswordPortal); bool sendRequestPasswordControl = StringUtil.ToBool(model.UserEmailRequestPasswordControl); if (!sendAcountActivationPortal && !sendRequestPasswordPortal && !sendRequestPasswordControl) return Json(responseData.SetMessage(messageTitle, Localiser["msg.validation.select.option"])); // Send emails. int emailsSentCount = 0; if (sendAcountActivationPortal) { //if (!OrganisationController.SendAccountActivatedEmail(this, userAccount)) return Json(responseData.SetMessage(messageTitle, "Failed to send Online Account Activation email.")); //emailsSentCount++; } if (sendRequestPasswordPortal) { if (!SecurityController.SendRequestPasswordEmail(this, userAccount, true)) return Json(responseData.SetMessage(messageTitle, "Failed to send Online Request Password email.")); emailsSentCount++; } if (sendRequestPasswordControl) { if (!SecurityController.SendRequestPasswordEmail(this, userAccount, false)) return Json(responseData.SetMessage(messageTitle, "Failed to send Control Request Password email.")); emailsSentCount++; } // Construct response. PopulateUserResponseItemData(model, responseData.user, userAccount); responseData.SetNotification(messageTitle, "Emails sent: " + emailsSentCount); responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }