Files
raven/server/AyaNova/biz/RequiredFieldsValidator.cs
2021-03-16 22:47:47 +00:00

97 lines
6.2 KiB
C#

using AyaNova.Models;
using System.Linq;
using Newtonsoft.Json.Linq;
namespace AyaNova.Biz
{
//VALIDATE **USER DEFINED** (not stock) REQUIRED FIELDS THAT ARE NOT CUSTOM
//(fields that are stock required are validated on their own not here)
internal static class RequiredFieldsValidator
{
internal static void Validate(BizObject biz, FormCustom formCustom, object proposedObject)
{
//No form custom = no template to check against so nothing to do
if (formCustom == null || string.IsNullOrWhiteSpace(formCustom.Template))
return;
var FormTemplate = JArray.Parse(formCustom.Template);
var FormFields = Biz.FormFieldOptionalCustomizableReference.FormFieldReferenceList(formCustom.FormKey);
foreach (JObject jo in FormTemplate)
{
if (jo["required"].Value<bool>() == true)
{
//First get the LT key
var FldLtKey = jo["fld"].Value<string>();
// - e.g.: {template:[{fld:"ltkeyfieldname",hide:"true/false",required:"true/false", type:"bool"},{fld:"ltkeyfieldname",hide:"true/false",required:"true/false", type:"text"]}
//get the FormField object
FormField FF = FormFields.Where(z => z.FieldKey == FldLtKey).Single();
//don't validate custom fields, just skip them
if (!FF.IsCustomField)
{
//Now get the actual property name from the available fields using the lt key
string RequiredPropertyName = FF.FieldKey;
//Is it an indexed collection field?
if (RequiredPropertyName.Contains("."))
{
/*
flag errors to include parent e.g in PO item validation error field name could be "Items[3].QuantityReceived" to indicate poitems collection 4th row has error in qtyreceived
Note: collections are logically never more than 3 deep so for example the deepest would be workorder granchildren: e.g. Workorder.Items.Parts and most
are two deep however like Po.PoItems.field
for purposes of rule checking they would be flagged by their immediate parent "Items[3].QuantityReceived" for po or for workorder it could be
a required UPC field in Workorder.Items.Parts.UPC would result in a target error return of "Items[2].Parts[3].UPC" would be valid
*/
var FieldKeyParts = RequiredPropertyName.Split('.');
if (FieldKeyParts.Length == 2)
{
//parent collection -> child field
//target name like "Items.FieldName"
var parentCollection = proposedObject.GetType().GetProperty(FieldKeyParts[0]).GetValue(proposedObject, null);
int index = 0;
foreach (object ChildObject in (parentCollection as System.Collections.IEnumerable))
{
var fieldValue = ChildObject.GetType().GetProperty(FieldKeyParts[1]).GetValue(ChildObject, null);
if (fieldValue == null || string.IsNullOrWhiteSpace(fieldValue.ToString()))
biz.AddError(ApiErrorCode.VALIDATION_CUSTOM_REQUIRED_EMPTY, $"{FieldKeyParts[0]}[{index}].{FieldKeyParts[1]}");
index++;
}
}
else if (FieldKeyParts.Length == 3)
{
//grandparent collection -> Parent collection -> Child field
//target name like "WorkorderItems.WorkorderItemParts.UPC
var GrandParentCollection = proposedObject.GetType().GetProperty(FieldKeyParts[0]).GetValue(proposedObject, null);
int GrandParentIndex = 0;
foreach (object GrandParentObject in (GrandParentCollection as System.Collections.IEnumerable))
{
var ParentCollection = GrandParentObject.GetType().GetProperty(FieldKeyParts[1]).GetValue(GrandParentObject, null);
int ParentIndex = 0;
foreach (object ChildObject in (ParentCollection as System.Collections.IEnumerable))
{
var fieldValue = ChildObject.GetType().GetProperty(FieldKeyParts[1]).GetValue(ChildObject, null);
if (fieldValue == null || string.IsNullOrWhiteSpace(fieldValue.ToString()))
biz.AddError(ApiErrorCode.VALIDATION_CUSTOM_REQUIRED_EMPTY, $"{FieldKeyParts[0]}[{GrandParentIndex}].{FieldKeyParts[1]}[{ParentIndex}].{FieldKeyParts[2]}");
ParentIndex++;
}
GrandParentIndex++;
}
}
}
else
{
//It's a simple property on the main object
//use reflection to get the underlying value from the proposed object to be saved
object propertyValue = proposedObject.GetType().GetProperty(RequiredPropertyName).GetValue(proposedObject, null);
if (propertyValue == null || string.IsNullOrWhiteSpace(propertyValue.ToString()))
biz.AddError(ApiErrorCode.VALIDATION_CUSTOM_REQUIRED_EMPTY, RequiredPropertyName);
}
}
}
}
}
}//eoc
}//ens