diff --git a/server/AyaNova/Controllers/DataListController.cs b/server/AyaNova/Controllers/DataListController.cs index e1903f4c..07f3921d 100644 --- a/server/AyaNova/Controllers/DataListController.cs +++ b/server/AyaNova/Controllers/DataListController.cs @@ -68,12 +68,11 @@ namespace AyaNova.Api.Controllers if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); - var UserId = UserIdFromContext.Id(HttpContext.Items); var UserRoles = UserRolesFromContext.Roles(HttpContext.Items); try { - ApiDataListResponse r = await DataListFetcher.GetResponseAsync(listOptions.DataListKey, ct, listOptions, UserId, UserRoles, log); + ApiDataListResponse r = await DataListFetcher.GetResponseAsync(listOptions.DataListKey, ct, listOptions, UserRoles, log); return Ok(r); } catch (System.UnauthorizedAccessException) diff --git a/server/AyaNova/Controllers/ReportController.cs b/server/AyaNova/Controllers/ReportController.cs index b35e3ac7..bdd8924d 100644 --- a/server/AyaNova/Controllers/ReportController.cs +++ b/server/AyaNova/Controllers/ReportController.cs @@ -183,14 +183,7 @@ namespace AyaNova.Api.Controllers //====================================================================================================== - public class ObjectReportDataParameter - { - public AyaType ObjectType { get; set; } - public long[] SelectedRowIds { get; set; } - public string DataListKey { get; set; } - public string ListView { get; set; }//optional, if null or empty will use default list view built into DataList - - } + /// /// Get data from id list in format used by report designer @@ -215,20 +208,22 @@ namespace AyaNova.Api.Controllers if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); - Newtonsoft.Json.Linq.JArray reportData = null; - if (reportDataParam.SelectedRowIds.Length > 0) - { - //pre-selected id values - reportData = await biz.GetReportData(reportDataParam.ObjectType, reportDataParam.SelectedRowIds); - } - else - { - //get from datalist values - //get the list of id's from the data list view - var rowIds = await AyaNova.DataList.DataListFetcher.GetIdListResponseAsync(reportDataParam.DataListKey, reportDataParam.ListView, ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items), log); - //now get the report data - reportData = await biz.GetReportData(reportDataParam.ObjectType, rowIds); - } + // Newtonsoft.Json.Linq.JArray reportData = null; + // if (reportDataParam.SelectedRowIds.Length > 0) + // { + // //pre-selected id values + // reportData = await biz.GetReportData(reportDataParam.ObjectType, reportDataParam.SelectedRowIds); + // } + // else + // { + // //get from datalist values + // //get the list of id's from the data list view + // var rowIds = await AyaNova.DataList.DataListFetcher.GetIdListResponseAsync(reportDataParam.DataListKey, reportDataParam.ListView, ct, UserIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items), log); + // //now get the report data + // reportData = await biz.GetReportData(reportDataParam.ObjectType, rowIds); + // } + + var reportData=await biz.GetReportData(reportDataParam); if (reportData == null) return BadRequest(new ApiErrorResponse(biz.Errors)); @@ -257,7 +252,7 @@ namespace AyaNova.Api.Controllers var httpConnectionFeature = HttpContext.Features.Get(); var API_URL = $"http://127.0.0.1:{httpConnectionFeature.LocalPort}/api/v8/"; - var result = await biz.RenderReport(reportParam.ReportId, reportParam.ObjectIdArray, API_URL); + var result = await biz.RenderReport(reportParam, API_URL); if (result == null) return BadRequest(new ApiErrorResponse(biz.Errors)); else @@ -265,43 +260,39 @@ namespace AyaNova.Api.Controllers } - public class RenderReportParameter - { - public long ReportId { get; set; } - public long[] ObjectIdArray { get; set; } - } + - [HttpGet("render-test")] - [AllowAnonymous] - public async Task GetTestReport([FromRoute] string test) - { - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + // [HttpGet("render-test")] + // [AllowAnonymous] + // public async Task GetTestReport([FromRoute] string test) + // { + // if (!serverState.IsOpen) + // return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); - string outputFile = FileUtil.NewRandomTempFilesFolderFileName; + // string outputFile = FileUtil.NewRandomTempFilesFolderFileName; - switch (test) - { - case "chrome-reddit-to-pdf": - //first test, just render a web page to pdf and return it - //return PhysicalFile(filePath, mimetype, dbObject.DisplayFileName); - outputFile += ".pdf"; - //http://www.puppeteersharp.com/api/index.html - //https://github.com/hardkoded/puppeteer-sharp - await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision); - var browser = await Puppeteer.LaunchAsync(new LaunchOptions - { - Headless = true - }); - var page = await browser.NewPageAsync(); - await page.GoToAsync("https://github.com/hardkoded/puppeteer-sharp"); + // switch (test) + // { + // case "chrome-reddit-to-pdf": + // //first test, just render a web page to pdf and return it + // //return PhysicalFile(filePath, mimetype, dbObject.DisplayFileName); + // outputFile += ".pdf"; + // //http://www.puppeteersharp.com/api/index.html + // //https://github.com/hardkoded/puppeteer-sharp + // await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision); + // var browser = await Puppeteer.LaunchAsync(new LaunchOptions + // { + // Headless = true + // }); + // var page = await browser.NewPageAsync(); + // await page.GoToAsync("https://github.com/hardkoded/puppeteer-sharp"); - await page.PdfAsync(outputFile); - return PhysicalFile(outputFile, "application/pdf"); - } - return NotFound(test); - } + // await page.PdfAsync(outputFile); + // return PhysicalFile(outputFile, "application/pdf"); + // } + // return NotFound(test); + // } diff --git a/server/AyaNova/DataList/DataListFetcher.cs b/server/AyaNova/DataList/DataListFetcher.cs index ecc50190..9fd2545e 100644 --- a/server/AyaNova/DataList/DataListFetcher.cs +++ b/server/AyaNova/DataList/DataListFetcher.cs @@ -13,7 +13,7 @@ namespace AyaNova.DataList { internal static class DataListFetcher { - internal static async Task GetResponseAsync(string DataListKey, AyContext ct, ListOptions listOptions, long UserId, AuthorizationRoles UserRoles, ILogger log) + internal static async Task GetResponseAsync(string DataListKey, AyContext ct, ListOptions listOptions, AuthorizationRoles UserRoles, ILogger log) { var DataList = DataListFactory.GetAyaDataList(DataListKey); @@ -53,7 +53,7 @@ namespace AyaNova.DataList var qOrderBy = string.Empty; //WHERE CLAUSE - FILTER - qWhere = DataListSqlFilterCriteriaBuilder.DataFilterToSQLCriteria(DataList.FieldDefinitions, ListViewArray, UserId); + qWhere = DataListSqlFilterCriteriaBuilder.DataFilterToSQLCriteria(DataList.FieldDefinitions, ListViewArray); //ORDER BY CLAUSE - SORT //BUILD ORDER BY @@ -202,7 +202,7 @@ namespace AyaNova.DataList //Get a list of id's for reporting - internal static async Task GetIdListResponseAsync(string dataListKey, string listView, AyContext ct, long userId, AuthorizationRoles userRoles, ILogger log) + internal static async Task GetIdListResponseAsync(string dataListKey, string listView, AyContext ct, AuthorizationRoles userRoles, ILogger log) { var DataList = DataListFactory.GetAyaDataList(dataListKey); @@ -242,7 +242,7 @@ namespace AyaNova.DataList var qOrderBy = string.Empty; //WHERE CLAUSE - FILTER - qWhere = DataListSqlFilterCriteriaBuilder.DataFilterToSQLCriteria(DataList.FieldDefinitions, ListViewArray, userId); + qWhere = DataListSqlFilterCriteriaBuilder.DataFilterToSQLCriteria(DataList.FieldDefinitions, ListViewArray); //ORDER BY CLAUSE - SORT //BUILD ORDER BY @@ -271,7 +271,7 @@ namespace AyaNova.DataList while (dr.Read()) { - // retList.Add(dr.GetInt64(0)); + // retList.Add(dr.GetInt64(0)); // //INSERT REMAINING FIELDS FROM TEMPLATE INTO THE RETURN ROWS LIST foreach (string TemplateField in ListViewFieldList) { @@ -296,10 +296,10 @@ namespace AyaNova.DataList { var ordinal = SelectBuild.map[f.SqlIdColumnName]; if (!await dr.IsDBNullAsync(ordinal)) - retList.Add(dr.GetInt64(ordinal)); + retList.Add(dr.GetInt64(ordinal)); } - } + } } } } diff --git a/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs b/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs index 81fb86a0..ede17767 100644 --- a/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs +++ b/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs @@ -10,7 +10,7 @@ namespace AyaNova.DataList { public static class DataListSqlFilterCriteriaBuilder { - public static string DataFilterToSQLCriteria(List objectFieldsList, JArray listViewArray, long userId) + public static string DataFilterToSQLCriteria(List objectFieldsList, JArray listViewArray) { if (listViewArray == null || listViewArray.Count == 0) @@ -120,7 +120,7 @@ namespace AyaNova.DataList } //Append this filter's criteria - sb.Append(DataFilterToColumnCriteria(columnNameToFilter, DataTypeToFilter, opType, val, tagList, userId)); + sb.Append(DataFilterToColumnCriteria(columnNameToFilter, DataTypeToFilter, opType, val, tagList)); ThisIsTheFirstFilterItemForThisColumn = false; @@ -158,7 +158,7 @@ namespace AyaNova.DataList /// /// Translate DataFilter to Postgres friendly SQL criteria /// - private static string DataFilterToColumnCriteria(string SqlColumnNameToFilter, UiFieldDataType DataType, string sOperator, string sValue, List sTags, long userId)//, bool IsCompound) + private static string DataFilterToColumnCriteria(string SqlColumnNameToFilter, UiFieldDataType DataType, string sOperator, string sValue, List sTags)//, bool IsCompound) { bool TagFilter = sTags.Count < 0; StringBuilder sb = new StringBuilder(); diff --git a/server/AyaNova/biz/ReportBiz.cs b/server/AyaNova/biz/ReportBiz.cs index a76fcac5..31415d8a 100644 --- a/server/AyaNova/biz/ReportBiz.cs +++ b/server/AyaNova/biz/ReportBiz.cs @@ -253,20 +253,27 @@ namespace AyaNova.Biz //REPORT DATA //Data fetched to return to report designer for Client report design usage - public async Task GetReportData(AyaType objectType, long[] objectidarray) + public async Task GetReportData(ObjectReportDataParameter reportDataParam, AuthorizationRoles overrideRoles = AuthorizationRoles.NoRole) { var log = AyaNova.Util.ApplicationLogging.CreateLogger("ReportBiz::GetReportData"); AuthorizationRoles effectiveRoles = CurrentUserRoles; - if (!AyaNova.Api.ControllerHelpers.Authorized.HasReadFullRole(effectiveRoles, objectType)) + if (overrideRoles != AuthorizationRoles.NoRole) + effectiveRoles = overrideRoles; + + if (!AyaNova.Api.ControllerHelpers.Authorized.HasReadFullRole(effectiveRoles, reportDataParam.ObjectType)) { - AddError(ApiErrorCode.NOT_AUTHORIZED, null, $"User not authorized for {objectType} type object"); + AddError(ApiErrorCode.NOT_AUTHORIZED, null, $"User not authorized for {reportDataParam.ObjectType} type object"); return null; } - //Get data - log.LogDebug($"Instantiating biz object handler for {objectType}"); - var biz = BizObjectFactory.GetBizObject(objectType, ct); - log.LogDebug($"Fetching data for {objectidarray.Length} {objectType} items"); - return await ((IReportAbleObject)biz).GetReportData(objectidarray); + + //Do we need to rehydrate the ID List from a DataList? + if (reportDataParam.SelectedRowIds.Length == 0) + reportDataParam.SelectedRowIds = await AyaNova.DataList.DataListFetcher.GetIdListResponseAsync(reportDataParam.DataListKey, reportDataParam.ListView, ct, effectiveRoles, log); + + log.LogDebug($"Instantiating biz object handler for {reportDataParam.ObjectType}"); + var biz = BizObjectFactory.GetBizObject(reportDataParam.ObjectType, ct); + log.LogDebug($"Fetching data for {reportDataParam.SelectedRowIds.Length} {reportDataParam.ObjectType} items"); + return await ((IReportAbleObject)biz).GetReportData(reportDataParam.SelectedRowIds); } @@ -279,12 +286,12 @@ namespace AyaNova.Biz so the route just calls the biz object which handles processing, getting data, checking rights and then making the report and either attaching it to an email (maybe I do need that temp server folder after all) or return to route to return to Client end */ - public async Task RenderReport(long id, long[] objectidarray, string apiUrl, long overrideUserId = 0) + public async Task RenderReport(RenderReportParameter reportParam, string apiUrl, AuthorizationRoles overrideRoles = AuthorizationRoles.NoRole) { var log = AyaNova.Util.ApplicationLogging.CreateLogger("ReportBiz::RenderReport"); //get report, vet security, see what we need before init in case of issue - var report = await ct.Report.FirstOrDefaultAsync(z => z.Id == id); + var report = await ct.Report.FirstOrDefaultAsync(z => z.Id == reportParam.ReportId); if (report == null) { AddError(ApiErrorCode.NOT_FOUND, "id"); @@ -292,18 +299,9 @@ namespace AyaNova.Biz } AuthorizationRoles effectiveRoles = CurrentUserRoles; - if (overrideUserId != 0) - { - var effectiveUser = await ct.User.FirstOrDefaultAsync(z => z.Id == overrideUserId); - if (effectiveUser == null) - { - var msg = $"Override user id specifies user that doesn't exist({overrideUserId}) cannot generate report {report.Name}"; - log.LogError(msg); - AddError(ApiErrorCode.NOT_FOUND, "UserId", msg); - return null; - } - effectiveRoles = effectiveUser.Roles; - } + if (overrideRoles != AuthorizationRoles.NoRole) + effectiveRoles = overrideRoles; + if (!AyaNova.Api.ControllerHelpers.Authorized.HasReadFullRole(effectiveRoles, report.ObjectType)) { @@ -313,10 +311,7 @@ namespace AyaNova.Biz //Get data - log.LogDebug($"Instantiating biz object handler for {report.ObjectType}"); - var biz = BizObjectFactory.GetBizObject(report.ObjectType, ct); - log.LogDebug($"Fetching data for {objectidarray.Length} {report.ObjectType} items"); - var data = (await ((IReportAbleObject)biz).GetReportData(objectidarray)).ToString(); + var ReportData = await GetReportData(new ObjectReportDataParameter() { ObjectType = report.ObjectType, SelectedRowIds = reportParam.SelectedRowIds, DataListKey = reportParam.DataListKey, ListView = reportParam.ListView }); //initialization log.LogDebug("Initializing report system"); @@ -359,7 +354,7 @@ namespace AyaNova.Biz //TODO: CUSTOM HELPERS //compile and run handlebars template - var compileScript = $"let reportData=ayPreRender({data});Handlebars.compile({report.Template})(reportData);"; + var compileScript = $"let reportData=ayPreRender({ReportData});Handlebars.compile({report.Template})(reportData);"; var resultHTML = await page.EvaluateExpressionAsync(compileScript); //render report as HTML diff --git a/server/AyaNova/models/dto/ReportingModels.cs b/server/AyaNova/models/dto/ReportingModels.cs new file mode 100644 index 00000000..ee74b041 --- /dev/null +++ b/server/AyaNova/models/dto/ReportingModels.cs @@ -0,0 +1,20 @@ +using AyaNova.Biz; +namespace AyaNova.Models +{ + public class ObjectReportDataParameter + { + public AyaType ObjectType { get; set; } + public long[] SelectedRowIds { get; set; } + public string DataListKey { get; set; } + public string ListView { get; set; }//optional, if null or empty will use default list view built into DataList + + } + + public class RenderReportParameter + { + public long ReportId { get; set; } + public long[] SelectedRowIds { get; set; } + public string DataListKey { get; set; } + public string ListView { get; set; }//optional, if null or empty will use default list view built into DataList + } +}