This commit is contained in:
2021-01-27 18:53:13 +00:00
parent c59cc5969c
commit b90ab0b35c
9 changed files with 110 additions and 97 deletions

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using AyaNova.Models;
using AyaNova.Biz; using AyaNova.Biz;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -33,10 +34,13 @@ namespace AyaNova.DataList
public Dictionary<string, string> DefaultSortBy { get; set; } public Dictionary<string, string> DefaultSortBy { get; set; }
//set defaults if not provided in listOptions //set defaults if not provided in listOptions
public void SetListOptionDefaultsIfNecessary(DataListOptions listOptions) public void SetListOptionDefaultsIfNecessary(DataListBase listOptions)
{ {
if (listOptions.Columns.Count == 0) if(listOptions is DataListTableOptions){//if this doesn't work then just ditch this method in favor of local code, it's not really saving much
listOptions.Columns = DefaultColumns; if (((DataListTableOptions)listOptions).Columns.Count == 0)
((DataListTableOptions)listOptions).Columns = DefaultColumns;
}
if (listOptions.SortBy.Count == 0) if (listOptions.SortBy.Count == 0)
listOptions.SortBy = DefaultSortBy; listOptions.SortBy = DefaultSortBy;
} }

View File

@@ -18,27 +18,27 @@ namespace AyaNova.DataList
// Get the data list data requested // Get the data list data requested
// //
// //
internal static async Task<ApiDataListResponse> GetResponseAsync(AyContext ct, DataListOptions listOptions, AuthorizationRoles userRoles, ILogger log, long userId) internal static async Task<ApiDataListResponse> GetResponseAsync(AyContext ct, DataListTableOptions dataListTableOptions, AuthorizationRoles userRoles, ILogger log, long userId)
{ {
var DataList = DataListFactory.GetAyaDataList(listOptions.DataListKey); var DataList = DataListFactory.GetAyaDataList(dataListTableOptions.DataListKey);
//was the name not found as a list? //was the name not found as a list?
if (DataList == null) if (DataList == null)
throw new System.ArgumentOutOfRangeException($"DataList \"{listOptions.DataListKey}\" specified does not exist"); throw new System.ArgumentOutOfRangeException($"DataList \"{dataListTableOptions.DataListKey}\" specified does not exist");
//check rights //check rights
if (!userRoles.HasAnyFlags(DataList.AllowedRoles)) if (!userRoles.HasAnyFlags(DataList.AllowedRoles))
throw new System.UnauthorizedAccessException("User roles insufficient for this datalist"); throw new System.UnauthorizedAccessException("User roles insufficient for this datalist");
DataList.SetListOptionDefaultsIfNecessary(listOptions); DataList.SetListOptionDefaultsIfNecessary(dataListTableOptions);
//STATIC filter options from server //STATIC filter options from server
List<DataListFilterOption> StaticServerFilterOptions = null; List<DataListFilterOption> StaticServerFilterOptions = null;
if (DataList is IAyaDataListServerCriteria) if (DataList is IAyaDataListServerCriteria)
StaticServerFilterOptions = ((IAyaDataListServerCriteria)DataList).DataListServerCriteria(userId, userRoles, listOptions); StaticServerFilterOptions = ((IAyaDataListServerCriteria)DataList).DataListServerCriteria(userId, userRoles, dataListTableOptions);
// //Get the public field key names in a list from the listview // //Get the public field key names in a list from the listview
@@ -46,12 +46,12 @@ namespace AyaNova.DataList
//Get the combination of all unique fields from both StaticServerFilterOptions and listOptions //Get the combination of all unique fields from both StaticServerFilterOptions and listOptions
//NOTE: this assumes no list options filter colums that don't exist in listoptions.columns //NOTE: this assumes no list options filter colums that don't exist in listoptions.columns
var AllUniqueFieldKeysRequiredForQuery = listOptions.Columns.Union(StaticServerFilterOptions.Select(z => z.Column).ToList()).ToList(); var AllUniqueFieldKeysRequiredForQuery = dataListTableOptions.Columns.Union(StaticServerFilterOptions.Select(z => z.Column).ToList()).ToList();
//Add the internal filters into the listoptions existing filters //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 //NOTE: There is currently no overlap between internal filtered columns and filters coming from the client
foreach (DataListFilterOption dfo in StaticServerFilterOptions) foreach (DataListFilterOption dfo in StaticServerFilterOptions)
listOptions.Filter.Add(dfo); dataListTableOptions.Filter.Add(dfo);
//BUILD THE QUERY //BUILD THE QUERY
@@ -65,16 +65,16 @@ namespace AyaNova.DataList
var qOrderBy = string.Empty; var qOrderBy = string.Empty;
//WHERE CLAUSE - FILTER //WHERE CLAUSE - FILTER
qWhere = DataListSqlFilterCriteriaBuilder.DataFilterToSQLCriteria(DataList.FieldDefinitions, listOptions); qWhere = DataListSqlFilterCriteriaBuilder.DataFilterToSQLCriteria(DataList.FieldDefinitions, dataListTableOptions);
//ORDER BY CLAUSE - SORT //ORDER BY CLAUSE - SORT
//BUILD ORDER BY //BUILD ORDER BY
qOrderBy = DataListSqlFilterOrderByBuilder.DataFilterToSQLOrderBy(DataList.FieldDefinitions, listOptions); qOrderBy = DataListSqlFilterOrderByBuilder.DataFilterToSQLOrderBy(DataList.FieldDefinitions, dataListTableOptions);
//LIMIT AND OFFSET CLAUSE - PAGING //LIMIT AND OFFSET CLAUSE - PAGING
listOptions.Offset = listOptions.Offset ?? DataListOptions.DefaultOffset; dataListTableOptions.Offset = dataListTableOptions.Offset ?? DataListTableOptions.DefaultOffset;
listOptions.Limit = listOptions.Limit ?? DataListOptions.DefaultLimit; dataListTableOptions.Limit = dataListTableOptions.Limit ?? DataListTableOptions.DefaultLimit;
var qLimitOffset = $"LIMIT {listOptions.Limit} OFFSET {listOptions.Offset}"; var qLimitOffset = $"LIMIT {dataListTableOptions.Limit} OFFSET {dataListTableOptions.Offset}";
//PUT IT ALL TOGETHER //PUT IT ALL TOGETHER
string qDataQuery = string.Empty; string qDataQuery = string.Empty;
@@ -84,7 +84,7 @@ namespace AyaNova.DataList
qTotalRecordsQuery = $"SELECT COUNT(*) {qFrom} {qWhere}".Replace(" ", " "); qTotalRecordsQuery = $"SELECT COUNT(*) {qFrom} {qWhere}".Replace(" ", " ");
//RETURN OBJECTS //RETURN OBJECTS
int returnRowColumnCount = listOptions.Columns.Count(); int returnRowColumnCount = dataListTableOptions.Columns.Count();
List<List<AyaFieldData>> rows = new List<List<AyaFieldData>>(); List<List<AyaFieldData>> rows = new List<List<AyaFieldData>>();
long totalRecordCount = 0; long totalRecordCount = 0;
@@ -105,7 +105,7 @@ namespace AyaNova.DataList
//INSERT REMAINING FIELDS FROM TEMPLATE INTO THE RETURN ROWS LIST //INSERT REMAINING FIELDS FROM TEMPLATE INTO THE RETURN ROWS LIST
foreach (string TemplateField in listOptions.Columns) foreach (string TemplateField in dataListTableOptions.Columns)
{ {
//get the AyaObjectFieldDefinition //get the AyaObjectFieldDefinition
@@ -230,7 +230,7 @@ namespace AyaNova.DataList
//BUILD THE COLUMNS RETURN PROPERTY JSON FRAGMENT //BUILD THE COLUMNS RETURN PROPERTY JSON FRAGMENT
Newtonsoft.Json.Linq.JArray ColumnsJSON = null; Newtonsoft.Json.Linq.JArray ColumnsJSON = null;
ColumnsJSON = DataList.GenerateReturnListColumns(listOptions.Columns);//<<<-----this next ColumnsJSON = DataList.GenerateReturnListColumns(dataListTableOptions.Columns);//<<<-----this next
return new ApiDataListResponse(rows, totalRecordCount, ColumnsJSON); return new ApiDataListResponse(rows, totalRecordCount, ColumnsJSON);

View File

@@ -1,86 +1,89 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using
namespace AyaNova.DataList //MOVED TO MODELS AS DataListTableOptions AND BROKEN APART
{
public sealed class DataListOptions : DataListBase // using System.ComponentModel.DataAnnotations;
{ // using Microsoft.AspNetCore.Mvc;
public const int MaxPageSize = 1000; // using System.Collections.Generic;
public const int DefaultOffset = 0; // using
public const int DefaultLimit = 25;
[FromBody] // namespace AyaNova.DataList
public int? Offset { get; set; } // {
[FromBody] // public sealed class DataListOptions : DataListBase
public int? Limit { get; set; } // {
// public const int MaxPageSize = 1000;
// public const int DefaultOffset = 0;
// public const int DefaultLimit = 25;
[FromBody, Required] // [FromBody]
public string DataListKey { get; set; } // public int? Offset { get; set; }
[FromBody] // [FromBody]
public DataListView View { get; set; } // public int? Limit { get; set; }
// [FromBody, Required]
// public string DataListKey { get; set; }
// [FromBody]
// public DataListView View { get; set; }
// [FromBody] // // [FromBody]
// public List<string> Columns { get; set; } // // public List<string> Columns { get; set; }
// [FromBody] // // [FromBody]
// public Dictionary<string, string> SortBy { get; set; } // // public Dictionary<string, string> SortBy { get; set; }
// [FromBody] // // [FromBody]
// public List<DataListFilterOption> Filter { get; set; } // // public List<DataListFilterOption> Filter { get; set; }
// [FromBody] // // [FromBody]
// public string ClientCriteria { get; set; } // // public string ClientCriteria { get; set; }
} // }
public class DataListView // public class DataListView
{ // {
/* // /*
OLD EXAMPLE: // OLD EXAMPLE:
{"offset":0,"limit":10,"dataListKey":"CustomerDataList", // {"offset":0,"limit":10,"dataListKey":"CustomerDataList",
"listView":"[ // "listView":"[
{\"fld\":\"customername\",\"sort\":\"+\",\"filter\":{\"items\":[{\"op\":\"=\",\"value\":\"dfdfdf\"},{\"op\":\"=\",\"value\":\"3333\"}],\"any\":true}}, // {\"fld\":\"customername\",\"sort\":\"+\",\"filter\":{\"items\":[{\"op\":\"=\",\"value\":\"dfdfdf\"},{\"op\":\"=\",\"value\":\"3333\"}],\"any\":true}},
{\"fld\":\"customerphone1\",\"filter\":{\"items\":[{\"op\":\">\",\"value\":\"44444\"}, // {\"fld\":\"customerphone1\",\"filter\":{\"items\":[{\"op\":\">\",\"value\":\"44444\"},
{\"op\":\"<\",\"value\":\"7777\"}]}}, // {\"op\":\"<\",\"value\":\"7777\"}]}},
{\"fld\":\"customeremail\"} // {\"fld\":\"customeremail\"}
{\"fld\":\"customerheadoffice\"}, // {\"fld\":\"customerheadoffice\"},
{\"fld\":\"customertags\",\"sort\":\"+\"}]"} // {\"fld\":\"customertags\",\"sort\":\"+\"}]"}
NEW: // NEW:
columns:["PartInventoryTransactionEntryDate","PartPartNumber","PartWarehouseName","PartInventoryTransactionQuantity","PartInventoryTransactionDescription","PartInventoryTransactionSource","PartInventoryBalance"] // columns:["PartInventoryTransactionEntryDate","PartPartNumber","PartWarehouseName","PartInventoryTransactionQuantity","PartInventoryTransactionDescription","PartInventoryTransactionSource","PartInventoryBalance"]
sortBy:[{"PartInventoryTransactionEntryDate":"-"}],//All sorted columns here as keyvalue pairs value is a string of "+" for ascending "-" for descending and are IN ORDER of how to be sorted // sortBy:[{"PartInventoryTransactionEntryDate":"-"}],//All sorted columns here as keyvalue pairs value is a string of "+" for ascending "-" for descending and are IN ORDER of how to be sorted
filter:[{column:"PartPartNumber",any:true/false,items:[{op: "=",value: "400735"}]}], // filter:[{column:"PartPartNumber",any:true/false,items:[{op: "=",value: "400735"}]}],
clientCriteria:"2" //could be anything here that makes sense to the list, in this case an example customer id for customernotedatalist // clientCriteria:"2" //could be anything here that makes sense to the list, in this case an example customer id for customernotedatalist
*/ // */
[FromBody] // [FromBody]
public List<string> Columns { get; set; } // public List<string> Columns { get; set; }
[FromBody] // [FromBody]
public Dictionary<string, string> SortBy { get; set; } // public Dictionary<string, string> SortBy { get; set; }
[FromBody] // [FromBody]
public List<DataListFilterOption> Filter { get; set; } // public List<DataListFilterOption> Filter { get; set; }
[FromBody] // [FromBody]
public string ClientCriteria { get; set; } // public string ClientCriteria { get; set; }
} // }
public class DataListFilterOption // public class DataListFilterOption
{ // {
public string Column { get; set; } // public string Column { get; set; }
public List<DataListColumnFilter> items { get; set; } // public List<DataListColumnFilter> items { get; set; }
public bool Any { get; set; }//means "or" the filter conditions // public bool Any { get; set; }//means "or" the filter conditions
DataListFilterOption() // DataListFilterOption()
{ // {
items = new List<DataListColumnFilter>(); // items = new List<DataListColumnFilter>();
} // }
} // }
public class DataListColumnFilter // public class DataListColumnFilter
{ // {
public string op { get; set; } // public string op { get; set; }
public string value { get; set; } // public string value { get; set; }
} // }
} // }

View File

@@ -4,13 +4,14 @@ using System.Globalization;
using System.Text; using System.Text;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Linq; using System.Linq;
using AyaNova.Models;
using AyaNova.Biz; using AyaNova.Biz;
namespace AyaNova.DataList namespace AyaNova.DataList
{ {
public static class DataListSqlFilterCriteriaBuilder public static class DataListSqlFilterCriteriaBuilder
{ {
public static string DataFilterToSQLCriteria(List<AyaDataListFieldDefinition> objectFieldsList, DataListOptions listOptions) public static string DataFilterToSQLCriteria(List<AyaDataListFieldDefinition> objectFieldsList, DataListTableOptions listOptions)
{ {
if (listOptions.Filter == null || listOptions.Filter.Count == 0) if (listOptions.Filter == null || listOptions.Filter.Count == 0)

View File

@@ -2,6 +2,7 @@ using System.Text;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using AyaNova.Models;
namespace AyaNova.DataList namespace AyaNova.DataList
{ {
@@ -9,7 +10,7 @@ namespace AyaNova.DataList
{ {
public static string DataFilterToSQLOrderBy(List<AyaDataListFieldDefinition> objectFieldsList, DataListOptions listOptions) public static string DataFilterToSQLOrderBy(List<AyaDataListFieldDefinition> objectFieldsList, DataListTableOptions listOptions)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using AyaNova.Biz; using AyaNova.Biz;
using AyaNova.Models;
namespace AyaNova.DataList namespace AyaNova.DataList
{ {
internal interface IAyaDataList internal interface IAyaDataList
@@ -22,7 +23,7 @@ namespace AyaNova.DataList
List<string> DefaultColumns { get; set; } List<string> DefaultColumns { get; set; }
Dictionary<string, string> DefaultSortBy { get; set; } Dictionary<string, string> DefaultSortBy { get; set; }
void SetListOptionDefaultsIfNecessary(DataListOptions listOptions); void SetListOptionDefaultsIfNecessary(DataListBase listOptions);
Newtonsoft.Json.Linq.JArray GenerateReturnListColumns(List<string> columns); Newtonsoft.Json.Linq.JArray GenerateReturnListColumns(List<string> columns);
// List<string> GetFieldListFromListView(JArray listViewArray); // List<string> GetFieldListFromListView(JArray listViewArray);

View File

@@ -1,11 +1,11 @@
using AyaNova.Models;
namespace AyaNova.DataList namespace AyaNova.DataList
{ {
internal interface IAyaDataListServerCriteria internal interface IAyaDataListServerCriteria
{ {
//Additional criteria for security or other reasons //Additional criteria for security or other reasons
//hard coded into some lists (e.g. MemoDataList so users can't get other people's memos) //hard coded into some lists (e.g. MemoDataList so users can't get other people's memos)
//User is just to look up for roles and stuff
//clientCriteria is additional criteria provided by client to list to process as it sees fit (e.g. CustomerNoteDataList requires customer id from client) //clientCriteria is additional criteria provided by client to list to process as it sees fit (e.g. CustomerNoteDataList requires customer id from client)
System.Collections.Generic.List<DataListFilterOption> DataListServerCriteria(long currentUserId, AyaNova.Biz.AuthorizationRoles userRoles, DataListOptions dataListOptions); System.Collections.Generic.List<DataListFilterOption> DataListServerCriteria(long currentUserId, AyaNova.Biz.AuthorizationRoles userRoles, DataListBase dataListBase);
} }
} }

View File

@@ -135,9 +135,10 @@ namespace AyaNova.DataList
string IAyaDataListServerCriteria.DataListServerCriteria(AyaNova.Models.AyContext ct, long currentUserId, DataListOptions dataListOptions) DataListFilterOption DataListServerCriteria(long currentUserId, AyaNova.Biz.AuthorizationRoles userRoles, DataListBase dataListBase)
{ {
return "[{\"fld\":\"metamemoto\",\"filter\":{\"items\":[{\"op\":\"=\",\"value\":" + currentUserId.ToString() + "}]}}]"; //return "[{\"fld\":\"metamemoto\",\"filter\":{\"items\":[{\"op\":\"=\",\"value\":" + currentUserId.ToString() + "}]}}]";
return null;
} }
}//eoc }//eoc

View File

@@ -555,7 +555,9 @@ namespace AyaNova.Biz
} }
//Report meta data //Report meta data
var reportMeta = $"{{Id:{report.Id},Name:`{report.Name}`,Notes:`{report.Notes}`,ObjectType:`{report.ObjectType}`,CustomFieldsDefinition:{CustomFieldsTemplate},DataListKey:`{reportParam.DataListKey}`,ListView:`{reportParam.ListView}`,SelectedRowIds: `{string.Join(",", reportParam.SelectedRowIds)}`}}"; // var reportMeta = $"{{Id:{report.Id},Name:`{report.Name}`,Notes:`{report.Notes}`,ObjectType:`{report.ObjectType}`,CustomFieldsDefinition:{CustomFieldsTemplate},DataListKey:`{reportParam.DataListKey}`,ListView:`{reportParam.ListView}`,SelectedRowIds: `{string.Join(",", reportParam.SelectedRowIds)}`}}";
//removed listview as it no longer exists and I don't think there's any useful purpose to it in the report javascript at this time
var reportMeta = $"{{Id:{report.Id},Name:`{report.Name}`,Notes:`{report.Notes}`,ObjectType:`{report.ObjectType}`,CustomFieldsDefinition:{CustomFieldsTemplate},DataListKey:`{reportParam.DataListKey}`,SelectedRowIds: `{string.Join(",", reportParam.SelectedRowIds)}`}}";
//duplicate meta data in report page wide variable for use by our internal functions //duplicate meta data in report page wide variable for use by our internal functions