Files
Saxonite/SaxoniteCoreWebOnline/Online/Controllers/SupportController-Ajax-Feedback.cs
T
2023-01-18 10:47:27 +00:00

359 lines
16 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Saxonite.Net.Core.Web.Online.Models;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Controllers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Saxonite.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Saxonite.Net.Standard.Base.App;
using static Saxonite.Net.Standard.Base.App.Sax.Config;
using static Saxonite.Net.Standard.Base.Bus.SaxArticle;
using Saxonite.Net.Standard.Base.Bus.Support;
using static Saxonite.Net.Standard.Base.App.Sax;
namespace Saxonite.Net.Core.Web.Online.Controllers
{
//=======================================================================
// Online Support Controller - Feedback - Ajax actions.
//=======================================================================
partial class SupportController
{
//-------------------------------------------------------------------
// Data definitions.
private class UserReportResponseListData : AjaxResponse_Data.ItemData_Base
{
// Account Id only populated while account names are being queried, then nulled.
public long? UserAccountId { get; set; }
public String UserDisplayName { get; set; }
public String ReportType { get; set; }
public String ReportTitle { get; set; }
public String RecordedOn { get; set; }
}
private class UserReportResponseItemData : UserReportResponseListData
{
public String Report { get; set; }
}
private void PopulateUserReportResponseListData(Model_Support model, SaxUserReport userReport, SaxUserAccount userAccount, UserReportResponseListData data)
{
data.Id = model.EncryptId(userReport.Id);
data.UserDisplayName = userAccount.GetDisplayName();
data.ReportType = Localiser.GetUserReportTypeCaption(userReport.ReportType);
data.ReportTitle = userReport.Title;
data.RecordedOn = model.FormatDateForDisplay(userReport.RecordedOn);
}
private void PopulateUserReportResponseItemData(Model_Support model, SaxUserReport userReport, SaxUserAccount userAccount, UserReportResponseItemData data)
{
PopulateUserReportResponseListData(model, userReport, userAccount, data);
data.Report = userReport.Report;
data.CreatedOnFmt = model.FormatDateForDisplay(userReport.CreateStamp.On);
data.StatusCode = userReport.StatusCode;
data.StatusDesc = userReport.StatusDesc;
}
//-------------------------------------------------------------------
// Support - Get User Reports.
//-------------------------------------------------------------------
private class AjaxResponse_UserReportsData : AjaxResponse_Data
{
// Construction.
public AjaxResponse_UserReportsData(SaxModel_Online model) : base(model) { }
// Reference data.
public List<ItemCodeDesc> ReportTypes { get; } = new List<ItemCodeDesc>();
// User Report list.
public List<UserReportResponseListData> Reports { get; } = new List<UserReportResponseListData>();
}
// Ajax request.
[HttpPost]
[Route("Support/Ajax/GetUserReports")]
public IActionResult GetUserReports(Model_Support model)
{
String fn = GetType().Name + ".GetUserReports";
AjaxResponse_UserReportsData responseData = new AjaxResponse_UserReportsData(model);
String messageTitle = Localiser["support.caption.user.reports"];
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Reference data - Report types.
List<Sax.UserReportType> validReportTypes = new List<Sax.UserReportType>(EnumUtil.GetValues<Sax.UserReportType>());
foreach (TypeCodeDesc reportType in UserReportTypeCodes)
{
if (!validReportTypes.Contains((Sax.UserReportType)reportType.Type)) continue;
responseData.ReportTypes.Add(new AjaxResponse_Data.ItemCodeDesc() { Code = reportType.Code, Desc = Localiser.GetUserReportTypeCaption((Sax.UserReportType)reportType.Type) });
}
// Item filter.
SaxUserReport.Params prmUserReport = new SaxUserReport.Params();
prmUserReport.UserAccountIdsIncluded.Add(SessionUserAccountId);
prmUserReport.StatusCat = SaxUserReport.StatusCat.NotDeleted;
model.Paging.ItemTotal = (ulong)SupportMgr.GetUserReportCount(prmUserReport);
model.PopulatePagingTo(prmUserReport.ResultsPaging);
// Item columns.
ColumnDfn colId = SupportMgr.GetUserReportColumnDfn(SaxUserReport.Column.Id);
ColumnDfn colUserAccountId = SupportMgr.GetUserReportColumnDfn(SaxUserReport.Column.UserAccountId);
ColumnDfn colReportType = SupportMgr.GetUserReportColumnDfn(SaxUserReport.Column.ReportType);
ColumnDfn colReportTitle = SupportMgr.GetUserReportColumnDfn(SaxUserReport.Column.Title);
ColumnDfn colRecordedOn = SupportMgr.GetUserReportColumnDfn(SaxUserReport.Column.RecordedOn);
ColumnDfn colStatus = SupportMgr.GetUserReportColumnDfn(SaxUserReport.Column.Status);
List<ColumnDfn> columns = new List<ColumnDfn>()
{
colId,
colUserAccountId, colReportType, colReportTitle,colRecordedOn,
colStatus,
};
// Sort columns.
prmUserReport.SortColumns.Add(colRecordedOn);
// User account details must be queried separately - different database!
HashSet<SysId> userAccountIds = new HashSet<SysId>();
// Query items.
using (DbResultSet resultSet = SupportMgr.ExecuteUserReportQuery(columns, prmUserReport))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
SysId userAccountId = new SysId(values.GetLong(colUserAccountId.DataName));
userAccountIds.Add(userAccountId);
Sax.UserReportType reportType = (Sax.UserReportType)values.GetLong(colReportType.DataName);
UserReportResponseListData userReportData = new UserReportResponseListData()
{
Id = model.EncryptId(new SysId(values.GetLong(colId.DataName))),
UserAccountId = SysId.ToLong(userAccountId),
ReportType = values.GetString(colReportType.DataName),
ReportTitle = values.GetString(colReportTitle.DataName),
RecordedOn = model.FormatDateForDisplay(values.GetDate(colRecordedOn.DataName)),
StatusCode = values.GetString(colStatus.DataName),
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
};
responseData.Reports.Add(userReportData);
}
}
if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Reports.Count;
// Query and populate User Account details.
if (userAccountIds.Any())
{
// User Account columns.
ColumnDfn colUserAccount_Id = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.Id);
ColumnDfn colUserAccount_Title = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.Title);
ColumnDfn colUserAccount_FirstName = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.FirstName);
ColumnDfn colUserAccount_LastName = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.LastName);
List<ColumnDfn> userAccountCols = new List<ColumnDfn>() { colUserAccount_Id, colUserAccount_Title, colUserAccount_FirstName, colUserAccount_LastName };
// User Account filter.
SaxUserAccount.Params prmUserAccount = new SaxUserAccount.Params();
prmUserAccount.IdsIncluded.AddRange(userAccountIds);
prmUserAccount.StatusCat = SaxUserAccount.StatusCat.Any;
// Query user accounts and populate properties to report list.
using (DbResultSet resultSet = AccountMgr.ExecuteUserAccountQuery(columns, prmUserAccount))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
SysId userAccountId = new SysId(values.GetLong(colUserAccount_Id.DataName));
String title = values.GetString(colUserAccount_Title.DataName);
String firstName = values.GetString(colUserAccount_FirstName.DataName);
String lastName = values.GetString(colUserAccount_LastName.DataName);
foreach (UserReportResponseListData userReportData in responseData.Reports.FindAll(item => item.UserAccountId.Equals(userAccountId)))
{
userReportData.UserDisplayName = SaxUserAccount.GetDisplayName(title, firstName, lastName);
userReportData.UserAccountId = null;
}
}
}
// Clear any remaining User Account Ids.
foreach (UserReportResponseListData userReportData in responseData.Reports.FindAll(item => item.UserAccountId != null))
userReportData.UserAccountId = null;
}
// Complete response.
responseData.SetPaging(model);
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
// Get User Report ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_UserReport : AjaxResponse_Data
{
// Construction.
public AjaxResponse_UserReport(SaxModel_Online model) : base(model) { }
// Sport details.
public UserReportResponseItemData Report { get; } = new UserReportResponseItemData();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Support/Ajax/GetUserReport")]
public IActionResult Ajax_GetUserReport(Model_Support model)
{
String fn = GetType().Name + ".Ajax_GetUserReport";
String messageTitle = Localiser["support.caption.user.report"];
AjaxResponse_UserReport responseData = new AjaxResponse_UserReport(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<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{
// Identify item.
SysId userReportId = model.ExtractSysId(model.UserReport.Id);
if (!SysId.IsValid(userReportId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
// Retrieve item.
SaxUserReport userReport = SupportMgr.GetUserReportById(userReportId);
disposableItems.Add(userReport);
if (userReport == null)
{
SaLogger.Warn(fn + " Failed to retrieve User Report for Id: '" + model.UserReport.Id + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Retrieve user.
SaxUserAccount userAccount = AccountMgr.GetUserAccountById(userReport.UserAccountId);
disposableItems.Add(userAccount);
if (userAccount == null)
{
SaLogger.Warn(fn + " Failed to retrieve User Account for Id: '" + userReport.UserAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Construct response.
PopulateUserReportResponseItemData(model, userReport, userAccount, responseData.Report);
responseData.Success = true;
}
return Json(responseData);
}
//-------------------------------------------------------------------
// Store User Report ajax request.
//-------------------------------------------------------------------
[HttpPost]
[Route("Support/Ajax/StoreUserReport")]
public IActionResult Ajax_StoreUserReport(Model_Support model)
{
String fn = GetType().Name + ".Ajax_StoreUserReport";
String messageTitle = Localiser["support.caption.user.report"];
AjaxResponse_UserReport responseData = new AjaxResponse_UserReport(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
if (!SessionData_Online.User.Roles.Exists(item => item.Role == Sax.UserRole.SystemReviewer)) return Forbid();
RefreshModel(model);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{
// Validate item properties.
model.ValidateUserReportData(responseData);
if (responseData.HasControlErrors())
return Json(responseData);
// Validate User Report Id against 'Exists' flag.
SysId userReportId = model.ExtractSysId(model.UserReport.Id);
bool userReportExists = StringUtil.ToBool(model.UserReport.Exists);
if (userReportExists && !SysId.IsValid(userReportId))
{
SaLogger.Warn(fn + " Id not specified for existing User Report.");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
if (!userReportExists && SysId.IsValid(userReportId))
{
SaLogger.Warn(fn + " Id specified for new User Report: '" + model.UserReport.Id + "'");
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
// Retrieve user.
SysId userAccountId = SessionUserAccountId;
SaxUserAccount userAccount = AccountMgr.GetUserAccountById(userAccountId);
disposableItems.Add(userAccount);
if (userAccount == null)
{
SaLogger.Warn(fn + " Failed to retrieve User Account for Id: '" + userAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Retrieve existing item.
SaxUserReport userReport = SupportMgr.GetUserReportById(userReportId);
disposableItems.Add(userReport);
if (userReport == null && SysId.IsValid(userReportId))
{
SaLogger.Warn(fn + " Failed to retrieve User Report for Id: '" + model.UserReport.Id + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Validate User Report properties.
if (userReport != null)
{
if (!userReport.UserAccountId.Equals(userAccountId))
{
SaLogger.Warn(fn + " Inconsistent User Account Id specified for User Report. Expected: " + userReport.UserAccountId + ". Found: " + userAccountId);
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
}
// If User Report doesn't exist, create a new one.
if (userReport == null)
{
userReport = SupportMgr.CreateUserReport(userAccountId);
disposableItems.Add(userReport);
}
// Populate item properties.
if (model.UserReport.ReportType != null)
userReport.ReportType = model.GetReportType();
if (model.UserReport.Title != null)
userReport.Title = model.UserReport.Title;
if (model.UserReport.Report != null)
userReport.Report = model.UserReport.Report;
// Store item.
if (!SysId.IsValid(userReport.Id))
{
if (!SupportMgr.InsertUserReport(userReport, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to insert user report: " + SupportMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"]));
}
}
else
{
if (!SupportMgr.UpdateUserReport(userReport, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to update user report [Id:" + SysId.ToString(userReport.Id) + "]: " + SupportMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"]));
}
}
// Construct response.
PopulateUserReportResponseItemData(model, userReport, userAccount, responseData.Report);
responseData.Success = true;
}
return Json(responseData);
}
//-------------------------------------------------------------------
}
//=======================================================================
}