using System.Linq; using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json.Linq; using AyaNova.Util; using AyaNova.Api.ControllerHelpers; using AyaNova.Models; using AyaNova.PickList; namespace AyaNova.Biz { internal class PickListBiz : BizObject { internal PickListBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles) { ct = dbcontext; UserId = currentUserId; UserTranslationId = userTranslationId; CurrentUserRoles = UserRoles; BizType = AyaType.PickListTemplate; } internal static PickListBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null) { if (httpContext != null) return new PickListBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items)); else return new PickListBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdminFull); } //////////////////////////////////////////////////////////////////////////////////////////////// /// GET // //Get one // internal async Task GetAsync(long fetchId, bool logTheGetEvent = true) // { // //This is simple so nothing more here, but often will be copying to a different output object or some other ops // var ret = await ct.DataListView.SingleOrDefaultAsync(m => m.Id == fetchId && (m.Public == true || m.UserId == UserId)); // if (logTheGetEvent && ret != null) // { // //Log // await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct); // } // return ret; // } //get picklist internal async Task> GetPickListAsync(AyaType ayaType, string query, bool inactive, AuthorizationRoles userRoles) { List items = await PickListFetcher.GetResponseAsync(ayaType, query, inactive, ct, userRoles); return items; } //get picklist templates, basically all the object types that support picklists internal List GetListOfAllPickListTypes(long translationId) { return PickListFactory.GetListOfAllPickListTypes(translationId); // List items = await PickListFetcher.GetResponseAsync(ayaType, query, ct, UserId, userRoles); // return items; } //////////////////////////////////////////////////////////////////////////////////////////////// //UPDATE // //put internal async Task ReplaceAsync(AyaType ayaType, string template) { throw new System.NotImplementedException(); // //preserve the owner ID if none was specified // if (inObj.UserId == 0) // inObj.UserId = dbObj.UserId; // //Replace the db object with the PUT object // CopyObject.Copy(inObj, dbObj, "Id"); // //Set "original" value of concurrency token to input token // //this will allow EF to check it out // ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = inObj.ConcurrencyToken; // await ValidateAsync(dbObj, false); // if (HasErrors) // return false; // await ct.SaveChangesAsync(); // //Log modification and save context // await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct); //return true; } //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // internal async Task DeleteAsync(AyaType ayaType) { //REMOVE ANY RECORD WITH SAME AYATYPE ID throw new System.NotImplementedException(); //Determine if the object can be deleted, do the deletion tentatively //Probably also in here deal with tags and associated search text etc //FUTURE POSSIBLE NEED //ValidateCanDelete(dbObj); // if (HasErrors) // return false; // ct.DataListView.Remove(dbObj); // await ct.SaveChangesAsync(); // //Delete sibling objects // //Event log process delete // await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct); // //Delete search index // //Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType); // return true; } //////////////////////////////////////////////////////////////////////////////////////////////// //VALIDATION // //Can save or update? private async Task ValidateAsync(DataListView inObj, bool isNew) { // //UserId required // if (!isNew) // { // if (inObj.UserId == 0) // AddError(ApiErrorCode.VALIDATION_REQUIRED, "UserId"); // } // //Name required // if (string.IsNullOrWhiteSpace(inObj.Name)) // AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name"); // //Name must be less than 255 characters // if (inObj.Name.Length > 255) // AddError(ApiErrorCode.VALIDATION_LENGTH_EXCEEDED, "Name", "255 max"); // //If name is otherwise OK, check that name is unique // if (!PropertyHasErrors("Name")) // { // //Use Any command is efficient way to check existance, it doesn't return the record, just a true or false // if (await ct.DataListView.AnyAsync(m => m.Name == inObj.Name && m.Id != inObj.Id)) // { // AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name"); // } // } // if (string.IsNullOrWhiteSpace(inObj.ListKey)) // AddError(ApiErrorCode.VALIDATION_REQUIRED, "ListKey"); // var DataList = DataListFactory.GetAyaDataList(inObj.ListKey); // if (DataList == null) // { // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ListKey", $"ListKey \"{inObj.ListKey}\" DataListKey is not valid"); // } // if (inObj.ListKey.Length > 255) // AddError(ApiErrorCode.VALIDATION_LENGTH_EXCEEDED, "ListKey", "255 max"); // //Filter json must parse // //this is all automated normally so not going to do too much parsing here // //just ensure it's basically there // if (!string.IsNullOrWhiteSpace(inObj.ListView)) // { // try // { // var v = JArray.Parse(inObj.ListView); // for (int i = 0; i < v.Count; i++) // { // var filterItem = v[i]; // if (filterItem["fld"] == null) // AddError(ApiErrorCode.VALIDATION_REQUIRED, "ListView", $"ListView array item {i}, object is missing required \"fld\" property "); // else // { // var fld = filterItem["fld"].Value(); // if (string.IsNullOrWhiteSpace(fld)) // AddError(ApiErrorCode.VALIDATION_REQUIRED, "ListView", $"ListView array item {i}, \"fld\" property is empty and required"); // //validate the field name if we can // if (DataList != null) // { // var TheField = DataList.FieldDefinitions.SingleOrDefault(x => x.FieldKey.ToLowerInvariant() == fld); // if (TheField == null) // { // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ListView", $"ListView array item {i}, fld property value \"{fld}\" is not a valid value for ListKey specified"); // } // } // } // //This is the old filter validation code but at this point only going to validate that the fields are present and valid as the bare minimum // // if (filterItem["op"] == null) // // AddError(ApiErrorCode.VALIDATION_REQUIRED, "Filter", $"Filter array item {i}, object is missing required \"op\" property "); // // else // // { // // var opType = filterItem["op"].Value(); // // if (!DataListFilterComparisonOperator.Operators.Contains(opType)) // // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Filter", $"Filter array item {i}, \"op\" property value of \"{opType}\" is not a valid FilterComparisonOperator type"); // // } // // if (filterItem["value"] == null) // // AddError(ApiErrorCode.VALIDATION_REQUIRED, "Filter", $"Filter array item {i}, object is missing or is empty the required \"value\" property "); // // else // // { // // //check if the value is present, not what it is exactly, just that it's present // // //value also could contain relative date tokens, not that it checks them anyway but just noting it here // // if (filterItem["value"].Type == JTokenType.String && string.IsNullOrWhiteSpace(filterItem["value"].Value())) // // AddError(ApiErrorCode.VALIDATION_REQUIRED, "Filter", $"Filter array item {i}, object is missing or is empty the required \"value\" property "); // // if (filterItem["value"].Type == JTokenType.Array && filterItem["value"].Count() == 0) // // AddError(ApiErrorCode.VALIDATION_REQUIRED, "Filter", $"Filter array item {i}, object is missing or is empty the required \"value\" property ARRAY "); // // } // //NOTE: value of nothing, null or empty is a valid value so no checking for it here // } // } // catch (Newtonsoft.Json.JsonReaderException ex) // { // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ListView", "ListView is not valid JSON string: " + ex.Message); // } // } // // //VALIDATE SORT // // //Filter json must parse // // if (!string.IsNullOrWhiteSpace(inObj.Sort)) // // { // // try // // { // // var v = JArray.Parse(inObj.Sort); // // for (int i = 0; i < v.Count; i++) // // { // // var sortItem = v[i]; // // if (sortItem["fld"] == null) // // AddError(ApiErrorCode.VALIDATION_REQUIRED, "Sort", $"Sort array item {i}, object is missing required \"fld\" property "); // // else // // { // // var fld = sortItem["fld"].Value(); // // if (string.IsNullOrWhiteSpace(fld)) // // AddError(ApiErrorCode.VALIDATION_REQUIRED, "Sort", $"Sort array item {i}, \"fld\" property is empty and required"); // // //validate the field name if we can // // if (DataList != null) // // { // // if (!DataList.FieldDefinitions.Exists(x => x.FieldKey.ToLowerInvariant() == fld && x.IsFilterable)) // // { // // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Sort", $"Sort array item {i}, fld property value \"{fld}\" is not a valid value for ListKey specified"); // // } // // } // // } // // if (sortItem["dir"] == null) // // AddError(ApiErrorCode.VALIDATION_REQUIRED, "Sort", $"Sort array item {i}, object is missing required \"dir\" sort direction property "); // // else // // { // // var sortDir = sortItem["dir"].Value(); // // if (sortDir != "+" && sortDir != "-") // // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Sort", $"Sort array item {i}, \"dir\" property value of \"{sortDir}\" is not a valid sort direction value, must be \"+\" or \"-\" only"); // // } // // //NOTE: value of nothing, null or empty is a valid value so no checking for it here // // } // // } // // catch (Newtonsoft.Json.JsonReaderException ex) // // { // // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Sort", "Sort is not valid JSON string: " + ex.Message); // // } // // } return; } ///////////////////////////////////////////////////////////////////// }//eoc }//eons