using AyaNova.Models; using System.Linq; using Newtonsoft.Json.Linq; namespace AyaNova.Biz { internal static class CustomFieldsValidator { internal static void Validate(BizObject biz, FormCustom formCustom, string customFields, string onlyIfStartsWith = null) { //No form custom = no template to check against so nothing to do if (formCustom == null) return; //case 4615 //this is to eliminate the old block optimization to short circuit checking if there is no custom data present if (string.IsNullOrWhiteSpace(customFields)) { customFields = "{}"; } //case 4615 bool checkPrefix = !string.IsNullOrEmpty(onlyIfStartsWith); var FormTemplate = JArray.Parse(formCustom.Template); var ThisFormCustomFieldsList = FormFieldOptionalCustomizableReference.FormFieldReferenceList(formCustom.FormKey).Where(z => z.IsCustomField == true).Select(z => z.TKey).ToList(); //case 4615 moved this logic into main check below as it would not support startsWith and isn't much of an optimization anyway; less code is best code. // //If the customFields string is empty then only validation is if any of the fields are required to be filled in // if (!hasCustomData) // { // //iterate the template // for (int i = 0; i < FormTemplate.Count; i++) // { // //get the field customization // var fldKey = FormTemplate[i]["fld"].Value(); // var fldRequired = FormTemplate[i]["required"].Value(); // //Check if this is an expected custom field and that it was set to required // //case 4615 // if (checkPrefix) // continue; // if (ThisFormCustomFieldsList.Contains(fldKey) && fldRequired == true) // { // //Ok, this field is required but custom fields are all empty so add this error // biz.AddError(ApiErrorCode.VALIDATION_CUSTOM_REQUIRED_EMPTY, fldKey); // } // } // return; // } //here we have both a bunch of custom fields presumeably and a form customization so let's get cracking... //parse the custom fields, it should contain an object with 16 keys //NOTE: to save bandwidth the actual custom fields look like this: // - {c1:"blah",c2:"blah",c3:"blah".....c16:"blah"} //However the LT field names might be WidgetCustom1 or UserCustom16 so we need to translate by EndsWith //Top level object is a Object not an array when it comes to custom fields and the key names are the custom fields abbreviated var CustomFieldData = JObject.Parse(customFields); //make sure all the *required* keys are present foreach (string iFldKey in ThisFormCustomFieldsList) { //case 4615 //ensure descendant custom fields are only checked against matching descendant objects if (checkPrefix && !iFldKey.StartsWith(onlyIfStartsWith)) continue; //ensure when validating work order header don't check workorder item (or workorderitemunit, both work here) custom fields as both could be present here if (!checkPrefix && iFldKey.StartsWith("WorkOrderItem")) continue; //Translate the LT field key to the actual customFieldData field key var InternalCustomFieldName = FormFieldOptionalCustomizableReference.TranslateLTCustomFieldToInternalCustomFieldName(iFldKey); //Check if it's set to required var isRequired = CustomFieldIsSetToRequired(FormTemplate, iFldKey); //if it's not required then we don't care, jump to the next item... if (!isRequired) continue; //It's required, make sure the key is present and contains data if (CustomFieldData.ContainsKey(InternalCustomFieldName)) { //validate for now that the custom fields set as required have data in them. Note that we are not validating the sanity of the values, only that they exist //trying to build in slack for when users inevitably change the TYPE of the custom field //Maybe in future this will be handled more thoroughly here but for now just make sure it's been filled in //validate it string CurrentValue = CustomFieldData[InternalCustomFieldName].Value(); if (string.IsNullOrWhiteSpace(CurrentValue)) { biz.AddError(ApiErrorCode.VALIDATION_CUSTOM_REQUIRED_EMPTY, iFldKey); } } else { //This is a serious issue and invalidates all biz.AddError(ApiErrorCode.VALIDATION_MISSING_PROPERTY, iFldKey); } } } /// /// Check if field is required /// /// /// /// private static bool CustomFieldIsSetToRequired(JArray FormTemplate, string FieldKey) { foreach (JObject jo in FormTemplate) { if (jo["fld"].Value() == FieldKey) { return jo["required"].Value(); } } return false; } }//eoc }//ens