This commit is contained in:
303
server/biz/PickListBiz.cs
Normal file
303
server/biz/PickListBiz.cs
Normal file
@@ -0,0 +1,303 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Sockeye.Util;
|
||||
using Sockeye.Api.ControllerHelpers;
|
||||
using Sockeye.Models;
|
||||
using Sockeye.PickList;
|
||||
|
||||
namespace Sockeye.Biz
|
||||
{
|
||||
|
||||
|
||||
internal class PickListBiz : BizObject
|
||||
{
|
||||
|
||||
internal PickListBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
|
||||
{
|
||||
ct = dbcontext;
|
||||
UserId = currentUserId;
|
||||
UserTranslationId = userTranslationId;
|
||||
CurrentUserRoles = UserRoles;
|
||||
BizType = SockType.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.SOCKEYE_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdmin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// GET
|
||||
|
||||
//Get one
|
||||
internal async Task<PickListTemplate> GetAsync(SockType sockType, bool logTheGetEvent = true)
|
||||
{
|
||||
long lTypeId = (long)sockType;
|
||||
|
||||
//first try to fetch from db
|
||||
var ret = await ct.PickListTemplate.SingleOrDefaultAsync(z => z.Id == lTypeId);
|
||||
if (logTheGetEvent && ret != null)
|
||||
{
|
||||
//Log
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, lTypeId, BizType, SockEvent.Retrieved), ct);
|
||||
}
|
||||
|
||||
//not in db then get the default
|
||||
if (ret == null)
|
||||
{
|
||||
var PickList = PickListFactory.GetAyaPickList(sockType);
|
||||
if (PickList != null)
|
||||
{
|
||||
ret = new PickListTemplate();
|
||||
ret.Id = lTypeId;
|
||||
ret.Template = PickList.DefaultTemplate;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//get picklist
|
||||
internal async Task<List<NameIdActiveItem>> GetPickListAsync(IAyaPickList PickList, string query, bool inactive, long[] preIds, string variant, ILogger log, string template)
|
||||
{
|
||||
|
||||
//Crack and validate the query part set a broken rule if not valid and return null
|
||||
//else do the query
|
||||
string TagSpecificQuery = null;
|
||||
string AutoCompleteQuery = null;
|
||||
|
||||
//Here need to handle scenario of badly formed query so user knows they did it wrong and doesn't just assume it's not there
|
||||
//determine if this is a tag query and extract it
|
||||
bool HasQuery = !string.IsNullOrWhiteSpace(query);
|
||||
if (HasQuery)
|
||||
{
|
||||
AutoCompleteQuery = query;
|
||||
//is it a dual template and tag query?
|
||||
if (AutoCompleteQuery.Contains(" "))
|
||||
{
|
||||
// split the query on space
|
||||
var querySegments = AutoCompleteQuery.Split(' ');
|
||||
if (querySegments.Length > 2)
|
||||
{
|
||||
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "query", await Translate("ErrorPickListQueryInvalid"));
|
||||
return null;
|
||||
}
|
||||
//check the two query segments, it's valid for the user to put the tag first or the template query first
|
||||
//we handle either way, but if there are no tas in either then it's not a valid query
|
||||
if (querySegments[0].Contains(".."))
|
||||
{
|
||||
TagSpecificQuery = querySegments[0].Replace("..", "");
|
||||
AutoCompleteQuery = querySegments[1];
|
||||
}
|
||||
else if (querySegments[1].Contains(".."))
|
||||
{
|
||||
TagSpecificQuery = querySegments[1].Replace("..", "");
|
||||
AutoCompleteQuery = querySegments[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "query", await Translate("ErrorPickListQueryInvalid"));
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//is it a tag only query?
|
||||
if (AutoCompleteQuery.Contains(".."))
|
||||
{
|
||||
TagSpecificQuery = AutoCompleteQuery.Replace("..", "");
|
||||
AutoCompleteQuery = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Final fixup if user specifies tag query but there are not tags on this object then
|
||||
//rather than error just accept it as a no tag query
|
||||
//Note: it's not valid to have more than one field with tags in the picklist definition so this works
|
||||
if (PickList.ColumnDefinitions.FirstOrDefault(z => z.ColumnDataType == UiFieldDataType.Tags) == null)
|
||||
{
|
||||
TagSpecificQuery = null;
|
||||
}
|
||||
|
||||
//Autocomplete and tagonly query terms now set for consumption by PickListFetcher, ready to fetch...
|
||||
List<NameIdActiveItem> items = await PickListFetcher.GetResponseAsync(PickList, AutoCompleteQuery, TagSpecificQuery, inactive, preIds, variant, ct, log, template);
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
//get picklist display for a single item
|
||||
//used to populate UI with picklist format display for items
|
||||
internal async Task<string> GetTemplatedNameAsync(SockType sockType, long id, string variant, ILogger log, string template)
|
||||
{
|
||||
//short circuit for empty types
|
||||
if (id == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
long[] preIds = { id };
|
||||
var PickList = PickListFactory.GetAyaPickList(sockType);
|
||||
|
||||
if (log == null)
|
||||
log = Sockeye.Util.ApplicationLogging.CreateLogger("PickListBiz::GetTemplatedNameAsync");
|
||||
|
||||
//Autocomplete and tagonly query terms now set for consumption by PickListFetcher, ready to fetch...
|
||||
List<NameIdActiveItem> items = await PickListFetcher.GetResponseAsync(PickList, null, null, true, preIds, variant, ct, log, template);
|
||||
if (items.Count == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return items[0].Name;
|
||||
}
|
||||
|
||||
|
||||
//get picklist templates, basically all the object types that support picklists
|
||||
internal List<NameIdItem> GetListOfAllPickListTypes(long translationId)
|
||||
{
|
||||
return PickListFactory.GetListOfAllPickListTypes(translationId);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//UPDATE
|
||||
//
|
||||
|
||||
//put
|
||||
internal async Task<bool> ReplaceAsync(PickListTemplate template)
|
||||
{
|
||||
var o = await ct.PickListTemplate.FirstOrDefaultAsync(z => z.Id == (long)template.Id);
|
||||
bool bAdd = false;
|
||||
if (o == null)
|
||||
{
|
||||
o = new PickListTemplate();
|
||||
bAdd = true;
|
||||
}
|
||||
o.Id = (long)template.Id;
|
||||
o.Template = template.Template;
|
||||
|
||||
|
||||
Validate(o);
|
||||
if (HasErrors)
|
||||
return false;
|
||||
if (bAdd)
|
||||
await ct.PickListTemplate.AddAsync(o);
|
||||
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
//Log modification and save context
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, o.Id, BizType, SockEvent.Modified), ct);
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DELETE (return to default template)
|
||||
//
|
||||
internal async Task<bool> DeleteAsync(SockType sockType)
|
||||
{
|
||||
//REMOVE ANY RECORD WITH SAME AYATYPE ID
|
||||
long lTypeId = (long)sockType;
|
||||
|
||||
var o = await ct.PickListTemplate.FirstOrDefaultAsync(z => z.Id == lTypeId);
|
||||
if (o != null)
|
||||
{
|
||||
ct.PickListTemplate.Remove(o);
|
||||
await ct.SaveChangesAsync();
|
||||
//Event log process delete
|
||||
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, lTypeId, sockType.ToString(), ct);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//VALIDATION
|
||||
//
|
||||
|
||||
//Can save or update?
|
||||
private void Validate(PickListTemplate inObj)
|
||||
{
|
||||
|
||||
//validate that the template is valid, the type is legit etc
|
||||
var TemplateType = (SockType)inObj.Id;
|
||||
if (!TemplateType.HasAttribute(typeof(CoreBizObjectAttribute)))
|
||||
{
|
||||
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "sockType", "SockType specified is not a Core object type and doesn't support pick list templates");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(inObj.Template))
|
||||
AddError(ApiErrorCode.VALIDATION_REQUIRED, "Template");
|
||||
|
||||
var PickList = PickListFactory.GetAyaPickList(TemplateType);
|
||||
|
||||
//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.Template))
|
||||
{
|
||||
try
|
||||
{
|
||||
var v = JArray.Parse(inObj.Template);
|
||||
for (int i = 0; i < v.Count; i++)
|
||||
{
|
||||
var filterItem = v[i];
|
||||
if (filterItem["fld"] == null)
|
||||
AddError(ApiErrorCode.VALIDATION_REQUIRED, "Template", $"Template array item {i}, object is missing required \"fld\" property ");
|
||||
else
|
||||
{
|
||||
var fld = filterItem["fld"].Value<string>();
|
||||
if (string.IsNullOrWhiteSpace(fld))
|
||||
AddError(ApiErrorCode.VALIDATION_REQUIRED, "Template", $"Template array item {i}, \"fld\" property is empty and required");
|
||||
|
||||
//validate the field name if we can
|
||||
if (PickList != null)
|
||||
{
|
||||
|
||||
var TheField = PickList.ColumnDefinitions.SingleOrDefault(z => z.FieldKey.ToLowerInvariant() == fld.ToLowerInvariant());
|
||||
|
||||
if (TheField == null)
|
||||
{
|
||||
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Template", $"Template array item {i}, fld property value \"{fld}\" is not a valid value for SockType specified");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Newtonsoft.Json.JsonReaderException ex)
|
||||
{
|
||||
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Template", "Template is not valid JSON string: " + ex.Message);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
}//eoc
|
||||
|
||||
|
||||
}//eons
|
||||
|
||||
Reference in New Issue
Block a user