This commit is contained in:
2021-01-30 15:29:21 +00:00
parent 9f91b74543
commit 6be01deba6
8 changed files with 122 additions and 59 deletions

View File

@@ -8,8 +8,6 @@ using AyaNova.Biz;
using AyaNova.DataList;
using System.Threading.Tasks;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using EnumsNET;
namespace AyaNova.Api.Controllers

View File

@@ -47,10 +47,10 @@ namespace AyaNova.Api.Controllers
/// Export to file
/// </summary>
/// <param name="format">Valid values are: "csv","json"</param>
/// <param name="dataListSelection"></param>
/// <param name="selectedRequest"></param>
/// <returns>downloadable export file name</returns>
[HttpPost("render/{format}")]
public async Task<IActionResult> RenderExport([FromRoute] string format, [FromBody] DataListSelectedProcessingOptions dataListSelection)
public async Task<IActionResult> RenderExport([FromRoute] string format, [FromBody] DataListSelectedRequest selectedRequest)
{
if (!serverState.IsOpen)
@@ -58,10 +58,10 @@ namespace AyaNova.Api.Controllers
if (!ModelState.IsValid)
return BadRequest(new ApiErrorResponse(ModelState));
if (dataListSelection.IsEmpty)
if (selectedRequest.IsEmpty)
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "DataListSelection is required"));
if (!Authorized.HasReadFullRole(HttpContext.Items, dataListSelection.ObjectType))
if (!Authorized.HasReadFullRole(HttpContext.Items, selectedRequest.ObjectType))
return StatusCode(403, new ApiNotAuthorizedResponse());
if (string.IsNullOrWhiteSpace(format))
@@ -70,17 +70,17 @@ namespace AyaNova.Api.Controllers
if (format != "csv" && format != "json")
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_INVALID_VALUE, null, "format not valid, must be 'csv' or 'json'"));
await dataListSelection.RehydrateIdList(ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items));
if (dataListSelection.SelectedRowIds.Length == 0)
await selectedRequest.RehydrateIdList(ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items));
if (selectedRequest.SelectedRowIds.Length == 0)
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "List of ids"));
log.LogDebug($"Instantiating biz object handler for {dataListSelection.ObjectType}");
var biz = BizObjectFactory.GetBizObject(dataListSelection.ObjectType, ct);
log.LogDebug($"Fetching data for {dataListSelection.SelectedRowIds.Length} {dataListSelection.ObjectType} items");
log.LogDebug($"Instantiating biz object handler for {selectedRequest.ObjectType}");
var biz = BizObjectFactory.GetBizObject(selectedRequest.ObjectType, ct);
log.LogDebug($"Fetching data for {selectedRequest.SelectedRowIds.Length} {selectedRequest.ObjectType} items");
// var TheData = await ((IExportAbleObject)biz).GetJSONExportData(dataListSelection.SelectedRowIds);
string baseFileName = FileUtil.StringToSafeFileName($"{dataListSelection.ObjectType.ToString().ToLowerInvariant()}-{format}-{FileUtil.GetSafeDateFileName()}");
string baseFileName = FileUtil.StringToSafeFileName($"{selectedRequest.ObjectType.ToString().ToLowerInvariant()}-{format}-{FileUtil.GetSafeDateFileName()}");
// string outputRandomFileNameNoExtension = StringUtil.ReplaceLastOccurrence(FileUtil.NewRandomFileName, ".", "");
string outputSourceFileName = baseFileName + "." + format;
@@ -93,7 +93,7 @@ namespace AyaNova.Api.Controllers
case "csv":
using (var w = new ChoCSVWriter(outputSourceFullPath).WithFirstLineHeader())
{
var dat = await ((IExportAbleObject)biz).GetExportData(dataListSelection.SelectedRowIds);
var dat = await ((IExportAbleObject)biz).GetExportData(selectedRequest.SelectedRowIds);
w.Write(ToDynamicList(dat));
}
break;
@@ -101,7 +101,7 @@ namespace AyaNova.Api.Controllers
using (StreamWriter file = System.IO.File.CreateText(outputSourceFullPath))
using (JsonTextWriter writer = new JsonTextWriter(file))
{
var dat = await ((IExportAbleObject)biz).GetExportData(dataListSelection.SelectedRowIds);
var dat = await ((IExportAbleObject)biz).GetExportData(selectedRequest.SelectedRowIds);
dat.WriteTo(writer);
}
break;

View File

@@ -193,37 +193,37 @@ namespace AyaNova.Api.Controllers
/// <summary>
/// Batch DELETE list of object id's specified
/// </summary>
/// <param name="dataListSelection"></param>
/// <param name="selectedRequest"></param>
/// <returns>Job Id</returns>
[HttpPost("batch-delete")]
public async Task<IActionResult> BatchDeleteObjects([FromBody] DataListSelectedProcessingOptions dataListSelection)
public async Task<IActionResult> BatchDeleteObjects([FromBody] DataListSelectedRequest selectedRequest)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
if (!ModelState.IsValid)
return BadRequest(new ApiErrorResponse(ModelState));
if (dataListSelection.IsEmpty)
if (selectedRequest.IsEmpty)
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "DataListSelection is required"));
if (!Authorized.HasDeleteRole(HttpContext.Items, dataListSelection.ObjectType))
if (!Authorized.HasDeleteRole(HttpContext.Items, selectedRequest.ObjectType))
return StatusCode(403, new ApiNotAuthorizedResponse());
await dataListSelection.RehydrateIdList(ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items));
if (dataListSelection.SelectedRowIds.Length == 0)
await selectedRequest.RehydrateIdList(ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items));
if (selectedRequest.SelectedRowIds.Length == 0)
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "List of ids"));
var JobName = $"LT:BatchDeleteJob - LT:{dataListSelection.ObjectType} ({dataListSelection.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}";
var JobName = $"LT:BatchDeleteJob - LT:{selectedRequest.ObjectType} ({selectedRequest.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}";
JObject o = JObject.FromObject(new
{
idList = dataListSelection.SelectedRowIds
idList = selectedRequest.SelectedRowIds
});
OpsJob j = new OpsJob();
j.Name = JobName;
j.ObjectType = dataListSelection.ObjectType;
j.ObjectType = selectedRequest.ObjectType;
j.JobType = JobType.BatchCoreObjectOperation;
j.SubType = JobSubType.Delete;
j.Exclusive = false;

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@@ -14,6 +13,8 @@ using AyaNova.Biz;
using AyaNova.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using EnumsNET;
using AyaNova.DataList;
namespace AyaNova.Api.Controllers
{
@@ -184,18 +185,45 @@ namespace AyaNova.Api.Controllers
/// <summary>
/// Get data from id list in format used by report designer
/// </summary>
/// <param name="reportDataParam">Data required for report</param>
/// <param name="selectedRequest">Data required for report</param>
/// <param name="apiVersion">From route path</param>
/// <returns></returns>
[HttpPost("data")]
public async Task<IActionResult> GetReportData([FromBody] DataListSelectedProcessingOptions reportDataParam, ApiVersion apiVersion)
public async Task<IActionResult> GetReportData([FromBody] DataListSelectedRequest selectedRequest, ApiVersion apiVersion)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
ReportBiz biz = ReportBiz.GetBiz(ct, HttpContext);
if (!ModelState.IsValid)
return BadRequest(new ApiErrorResponse(ModelState));
var reportData = await biz.GetReportData(reportDataParam);
//-------------------------------
var UserRoles = UserRolesFromContext.Roles(HttpContext.Items);
var UserId = UserIdFromContext.Id(HttpContext.Items);
DataListSavedColumnViewBiz viewbiz = DataListSavedColumnViewBiz.GetBiz(ct, HttpContext);
var SavedView = await viewbiz.GetAsync(UserId, selectedRequest.DataListKey, true);
DataListSavedFilter SavedFilter = null;
if (selectedRequest.FilterId != 0)
{
DataListSavedFilterBiz filterbiz = DataListSavedFilterBiz.GetBiz(ct, HttpContext);
SavedFilter = await filterbiz.GetAsync(selectedRequest.FilterId, false);
}
var DataList = DataListFactory.GetAyaDataList(selectedRequest.DataListKey);
if (DataList == null)
return BadRequest(new ApiErrorResponse(ApiErrorCode.NOT_FOUND, "DataListKey", $"DataList \"{selectedRequest.DataListKey}\" specified does not exist"));
//check rights
if (!UserRoles.HasAnyFlags(DataList.AllowedRoles))
return StatusCode(403, new ApiNotAuthorizedResponse());
//hydrate the saved view and filter
DataListSelectedProcessingOptions dataListSelectedOptions = new DataListSelectedProcessingOptions(selectedRequest, DataList, SavedView, SavedFilter, UserId, UserRoles);
//------------------------
var reportData = await biz.GetReportData(dataListSelectedOptions);
if (reportData == null)
return BadRequest(new ApiErrorResponse(biz.Errors));
else
@@ -206,11 +234,11 @@ namespace AyaNova.Api.Controllers
/// <summary>
/// Render Report
/// </summary>
/// <param name="reportParam">report id and object id values for object type specified in report template</param>
/// <param name="reportRequest">report id and object id values for object type specified in report template</param>
/// <param name="apiVersion">From route path</param>
/// <returns>downloadable pdf name</returns>
[HttpPost("render")]
public async Task<IActionResult> RenderReport([FromBody] DataListReportProcessingOptions reportParam, ApiVersion apiVersion)
public async Task<IActionResult> RenderReport([FromBody] DataListReportRequest reportRequest, ApiVersion apiVersion)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
@@ -224,7 +252,7 @@ namespace AyaNova.Api.Controllers
var API_URL = $"http://127.0.0.1:{httpConnectionFeature.LocalPort}/api/v8/";
try
{
var result = await biz.RenderReport(reportParam, API_URL);
var result = await biz.RenderReport(reportRequest, API_URL);
if (string.IsNullOrWhiteSpace(result))
return BadRequest(new ApiErrorResponse(biz.Errors));

View File

@@ -80,43 +80,43 @@ namespace AyaNova.Api.Controllers
/// Batch add tags to list of object id's specified
/// </summary>
/// <param name="tag"></param>
/// <param name="dataListSelection"></param>
/// <param name="selectedRequest"></param>
/// <returns>Job Id</returns>
[HttpPost("batch-add/{tag}")]
public async Task<IActionResult> BatchAdd([FromRoute] string tag, [FromBody] DataListSelectedProcessingOptions dataListSelection)
public async Task<IActionResult> BatchAdd([FromRoute] string tag, [FromBody] DataListSelectedRequest selectedRequest)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
if (!ModelState.IsValid)
return BadRequest(new ApiErrorResponse(ModelState));
if (dataListSelection.IsEmpty)
if (selectedRequest.IsEmpty)
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "DataListSelection is required"));
if (!dataListSelection.ObjectType.HasAttribute(typeof(CoreBizObjectAttribute)))
if (!selectedRequest.ObjectType.HasAttribute(typeof(CoreBizObjectAttribute)))
return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Not a taggable object type"));
if (!Authorized.HasModifyRole(HttpContext.Items, dataListSelection.ObjectType))
if (!Authorized.HasModifyRole(HttpContext.Items, selectedRequest.ObjectType))
return StatusCode(403, new ApiNotAuthorizedResponse());
tag = TagBiz.NormalizeTag(tag);
if (string.IsNullOrWhiteSpace(tag))
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "tag required"));
await dataListSelection.RehydrateIdList(ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items));
if (dataListSelection.SelectedRowIds.Length == 0)
await selectedRequest.RehydrateIdList(ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items));
if (selectedRequest.SelectedRowIds.Length == 0)
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "List of ids"));
var JobName = $"LT:BatchJob LT:Add LT:Tag \"{tag}\" LT:{dataListSelection.ObjectType} ({dataListSelection.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}";
var JobName = $"LT:BatchJob LT:Add LT:Tag \"{tag}\" LT:{selectedRequest.ObjectType} ({selectedRequest.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}";
JObject o = JObject.FromObject(new
{
idList = dataListSelection.SelectedRowIds,
idList = selectedRequest.SelectedRowIds,
tag = tag
});
OpsJob j = new OpsJob();
j.Name = JobName;
j.ObjectType = dataListSelection.ObjectType;
j.ObjectType = selectedRequest.ObjectType;
j.JobType = JobType.BatchCoreObjectOperation;
j.SubType = JobSubType.TagAdd;
j.Exclusive = false;
@@ -170,43 +170,43 @@ namespace AyaNova.Api.Controllers
/// Batch remove tags to list of object id's specified
/// </summary>
/// <param name="tag"></param>
/// <param name="dataListSelection"></param>
/// <param name="selectedRequest"></param>
/// <returns>Job Id</returns>
[HttpPost("batch-remove/{tag}")]
public async Task<IActionResult> BatchRemove([FromRoute] string tag, [FromBody] DataListSelectedProcessingOptions dataListSelection)
public async Task<IActionResult> BatchRemove([FromRoute] string tag, [FromBody] DataListSelectedRequest selectedRequest)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
if (!ModelState.IsValid)
return BadRequest(new ApiErrorResponse(ModelState));
if (dataListSelection.IsEmpty)
if (selectedRequest.IsEmpty)
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "DataListSelection is required"));
if (!dataListSelection.ObjectType.HasAttribute(typeof(CoreBizObjectAttribute)))
if (!selectedRequest.ObjectType.HasAttribute(typeof(CoreBizObjectAttribute)))
return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Not a taggable object type"));
if (!Authorized.HasModifyRole(HttpContext.Items, dataListSelection.ObjectType))
if (!Authorized.HasModifyRole(HttpContext.Items, selectedRequest.ObjectType))
return StatusCode(403, new ApiNotAuthorizedResponse());
tag = TagBiz.NormalizeTag(tag);
if (string.IsNullOrWhiteSpace(tag))
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "tag"));
await dataListSelection.RehydrateIdList(ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items));
if (dataListSelection.SelectedRowIds.Length == 0)
await selectedRequest.RehydrateIdList(ct, UserRolesFromContext.Roles(HttpContext.Items), log, UserIdFromContext.Id(HttpContext.Items));
if (selectedRequest.SelectedRowIds.Length == 0)
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, null, "List of ids"));
var JobName = $"LT:BatchJob LT:Remove LT:Tag \"{tag}\" LT:{dataListSelection.ObjectType} ({dataListSelection.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}";
var JobName = $"LT:BatchJob LT:Remove LT:Tag \"{tag}\" LT:{selectedRequest.ObjectType} ({selectedRequest.SelectedRowIds.LongLength}) LT:User {UserNameFromContext.Name(HttpContext.Items)}";
JObject o = JObject.FromObject(new
{
idList = dataListSelection.SelectedRowIds,
idList = selectedRequest.SelectedRowIds,
tag = tag
});
OpsJob j = new OpsJob();
j.Name = JobName;
j.ObjectType = dataListSelection.ObjectType;
j.ObjectType = selectedRequest.ObjectType;
j.JobType = JobType.BatchCoreObjectOperation;
j.SubType = JobSubType.TagRemove;
j.Exclusive = false;
@@ -266,7 +266,7 @@ namespace AyaNova.Api.Controllers
/// <param name="dataListSelection"></param>
/// <returns>Job Id</returns>
[HttpPost("batch-replace/{fromTag}")]
public async Task<IActionResult> BatchReplace([FromRoute] string fromTag, [FromQuery] string toTag, [FromBody] DataListSelectedProcessingOptions dataListSelection)
public async Task<IActionResult> BatchReplace([FromRoute] string fromTag, [FromQuery] string toTag, [FromBody] DataListSelectedRequest dataListSelection)
{
if (!serverState.IsOpen)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));

View File

@@ -236,13 +236,12 @@ namespace AyaNova.DataList
// Get a list of id's of the datalist results for reporting
//
//
//internal static async Task<long[]> GetIdListResponseAsync(string dataListKey, string listView, string metaListView, AyContext ct, AuthorizationRoles userRoles, ILogger log, long userId)
internal static async Task<long[]> GetIdListResponseAsync(AyContext ct, DataListSelectedProcessingOptions dataListSelectionOptions, AuthorizationRoles userRoles, ILogger log, long userId)
internal static async Task<long[]> GetIdListResponseAsync(AyContext ct, DataListSelectedProcessingOptions dataListSelectionOptions,IDataListProcessing DataList, AuthorizationRoles userRoles, ILogger log, long userId)
{
var DataList = DataListFactory.GetAyaDataList(dataListSelectionOptions.DataListKey);
//was the name not found as a list?
if (DataList == null)
throw new System.ArgumentOutOfRangeException($"DataList \"{dataListSelectionOptions.DataListKey}\" specified does not exist");
// var DataList = DataListFactory.GetAyaDataList(dataListSelectionOptions.DataListKey);
// //was the name not found as a list?
// if (DataList == null)
// throw new System.ArgumentOutOfRangeException($"DataList \"{dataListSelectionOptions.DataListKey}\" specified does not exist");

View File

@@ -22,7 +22,7 @@ namespace AyaNova.Models
}
}
TODO: recode this to fulfil requirements of datalistfetcher in the same way as
///TODO: recode this to fulfil requirements of datalistfetcher in the same way as
//DataListTableProcessingOptions constructor
//clean out datalistfetcher comments and similar afterwards
public async Task RehydrateIdList(AyContext ct, AuthorizationRoles userRoles, Microsoft.Extensions.Logging.ILogger log, long userId)
@@ -32,3 +32,41 @@ TODO: recode this to fulfil requirements of datalistfetcher in the same way as
}
}
}
/*
internal DataListTableProcessingOptions(
DataListTableRequest request,
IDataListProcessing dataList,
DataListSavedColumnView savedView,
DataListSavedFilter savedFilter,
long userId,
AuthorizationRoles userRoles)
{
//set some values from request
Limit = request.Limit;
Offset = request.Offset;
base.ClientCriteria = request.ClientCriteria;
base.DataListKey = request.DataListKey;
//SET COLUMNS
Columns = JsonConvert.DeserializeObject<List<string>>(savedView.Columns);
//SET SORTBY
base.SortBy = JsonConvert.DeserializeObject<Dictionary<string, string>>(savedView.Sort);
//SET FILTER
if (request.FilterId != 0 && savedFilter != null)
base.Filter = JsonConvert.DeserializeObject<List<DataListFilterOption>>(savedFilter.Filter);
//ADD STATIC SERVER FILTERS
List<DataListFilterOption> StaticServerFilterOptions = new List<DataListFilterOption>();
if (dataList is IDataListInternalCriteria)
StaticServerFilterOptions = ((IDataListInternalCriteria)dataList).DataListInternalCriteria(userId, userRoles, request.ClientCriteria);
//Add the internal filters into the listoptions existing filters
//NOTE: There is currently no overlap between internal filtered columns and filters coming from the client
foreach (DataListFilterOption dfo in StaticServerFilterOptions)
base.Filter.Add(dfo);
}
*/

View File

@@ -3,7 +3,7 @@ namespace AyaNova.Models
{
//Request version of selection request used by report and bulk ops
//handles posts from client
public class DataListSelectedRequest : DataListProcessingBase
public class DataListSelectedRequest : DataListRequestBase
{
public AyaType ObjectType { get; set; }
public long[] SelectedRowIds { get; set; }