From 1f56291f9a6358707f29f4687b6d032c0f5edbbd Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Wed, 24 Feb 2021 00:12:55 +0000 Subject: [PATCH] --- server/AyaNova/biz/RequiredFieldsValidator.cs | 94 ++++++++++++++++--- 1 file changed, 79 insertions(+), 15 deletions(-) diff --git a/server/AyaNova/biz/RequiredFieldsValidator.cs b/server/AyaNova/biz/RequiredFieldsValidator.cs index 632258f1..f4154486 100644 --- a/server/AyaNova/biz/RequiredFieldsValidator.cs +++ b/server/AyaNova/biz/RequiredFieldsValidator.cs @@ -3,6 +3,7 @@ using System.Linq; using Newtonsoft.Json.Linq; + namespace AyaNova.Biz { //VALIDATE **USER DEFINED** (not stock) REQUIRED FIELDS THAT ARE NOT CUSTOM @@ -18,7 +19,7 @@ namespace AyaNova.Biz //var OuterJson=JObject.Parse(formCustom.Template); var FormTemplate = JArray.Parse(formCustom.Template); - // var FormTemplate=(JArray)OuterJson["template"]; + // var FormTemplate=(JArray)OuterJson["template"]; var FormFields = Biz.FormFieldOptionalCustomizableReference.FormFieldReferenceList(formCustom.FormKey); // var ThisFormNormalFieldsList = FormFields.Where(z => z.Custom == false).Select(z => z.Key).ToList(); @@ -32,31 +33,94 @@ namespace AyaNova.Biz //get the FormField object FormField FF = FormFields.Where(z => z.FieldKey == FldLtKey).Single(); - - //don't validate custom fields, just skip them - // if (!string.IsNullOrWhiteSpace(FF.PropertyName))//this used to work because there would be no property name but now there is so it doesn't + + //don't validate custom fields, just skip them + // if (!string.IsNullOrWhiteSpace(FF.PropertyName))//this used to work because there would be no property name but now there is so it doesn't if (!FF.IsCustomField) { - //TODO: CHILD COLLECTION MOD - /* - Update RequiredFieldsValidator to look for these period seperated items and navigate through teh collection by name / reflection to step through children and flag errors to include parent - e.g in validation error field name could be "poitems[3].vendorpartnumber" to indicate poitems collection 4th row has error in vendorpartnumber - */ + //Now get the actual property name from the available fields using the lt key string RequiredPropertyName = FF.FieldKey; - - //use reflection to get the underlying value from the proposed object to be saved - object propertyValue = proposedObject.GetType().GetProperty(RequiredPropertyName).GetValue(proposedObject, null); + //Is it a child 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_REQUIRED, $"{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_REQUIRED, $"{FieldKeyParts[0]}[{GrandParentIndex}].{FieldKeyParts[1]}[{ParentIndex}].{FieldKeyParts[2]}"); + ParentIndex++; + } + GrandParentIndex++; + } + } + + var item = proposedObject.GetType().GetProperty(FieldKeyParts[0]).GetValue(proposedObject, null); + if (item is System.Collections.IEnumerable) + { + foreach (object o in (item as System.Collections.IEnumerable)) + { + var subitem = o.GetType().GetProperty(FieldKeyParts[1]).GetValue(o, null); + } + } + else + { + // reflect over item + } + // object propertyValue = proposedObject.GetType().GetProperty(RequiredPropertyName).GetValue(proposedObject, null); + + } + else + { + //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_REQUIRED, FldLtKey);//was returning the ltkey in the error but that's not a match to the client end object so instead... + biz.AddError(ApiErrorCode.VALIDATION_REQUIRED, RequiredPropertyName); + } - if (propertyValue == null || string.IsNullOrWhiteSpace(propertyValue.ToString())) - //biz.AddError(ApiErrorCode.VALIDATION_REQUIRED, FldLtKey);//was returning the ltkey in the error but that's not a match to the client end object so instead... - biz.AddError(ApiErrorCode.VALIDATION_REQUIRED, RequiredPropertyName); } } } } + internal static + }//eoc }//ens