public override Action GetBulkAddFunctionFor(string referenceName, RecordEntryViewModelBase recordForm)
        {
            var functions      = new Dictionary <string, Action>();
            var enumeratedType = ObjectRecordService.GetPropertyType(referenceName, recordForm.GetRecordType()).GenericTypeArguments[0];
            var customFunction = enumeratedType.GetCustomAttribute <BulkAddFunction>();

            return(customFunction != null
                ? customFunction.GetCustomFunction(recordForm, referenceName)
                : null);
        }
        public override IEnumerable <ValidationRuleBase> GetValidationRules(string fieldName, string recordType)
        {
            var validators    = new List <ValidationRuleBase>();
            var type          = ObjectRecordService.GetPropertyType(fieldName, ObjectType.AssemblyQualifiedName);
            var isValidatable = type.IsTypeOf(typeof(IValidatableObject));

            if (isValidatable)
            {
                validators.Add(new IValidatableObjectValidationRule());
            }
            validators.AddRange(ObjectRecordService.GetValidatorAttributes(fieldName, ObjectType.AssemblyQualifiedName)
                                .Select(va => new PropertyAttributeValidationRule(va)));
            return(validators);
        }
        private void AppendFieldForChanges(string fieldName, string recordType, List <Action <RecordEntryViewModelBase> > onChanges, bool clearValue = false)
        {
            var lookupForAttributes = ObjectRecordService.GetPropertyInfo(fieldName, recordType)
                                      .GetCustomAttributes(typeof(RecordFieldFor), true).Cast <RecordFieldFor>();

            foreach (var attribute in lookupForAttributes)
            {
                onChanges.Add(
                    re => re.StartNewAction(() =>
                {
                    var recordFieldViewModel = re.GetRecordFieldFieldViewModel(fieldName);
                    if (recordFieldViewModel.Value != null)
                    {
                        var matchingFields = re.FieldViewModels.Where(f => f.FieldName == attribute.PropertyPaths.First());
                        foreach (var fieldViewModel in matchingFields.ToArray())
                        {
                            var selectedFieldName       = recordFieldViewModel.Value.Key;
                            var selectedFieldRecordType = GetRecordTypeFor(recordFieldViewModel.FieldName, re);
                            var lookupService           = re.RecordService.GetLookupService(recordFieldViewModel.FieldName, recordFieldViewModel.GetRecordType(), null, recordFieldViewModel.RecordEntryViewModel.GetRecord());
                            if (lookupService != null)
                            {
                                //get the source field type
                                var fieldType = lookupService.GetFieldType(selectedFieldName, selectedFieldRecordType);
                                //get the section the target field is in and its field metadata
                                var metadata = re.FormService.GetFormMetadata(re.GetRecordType(), ObjectRecordService);
                                FormFieldMetadata fieldMetadata = null;
                                string sectionName = null;
                                foreach (var sectionMetadata in metadata.FormSections.Cast <FormFieldSection>())
                                {
                                    foreach (var field in sectionMetadata.FormFields)
                                    {
                                        if (field.FieldName == fieldViewModel.FieldName)
                                        {
                                            sectionName   = sectionMetadata.SectionLabel;
                                            fieldMetadata = field;
                                        }
                                    }
                                }
                                if (!string.IsNullOrWhiteSpace(sectionName))
                                {
                                    var targetPropInfo = ObjectRecordService.GetPropertyType(attribute.PropertyPaths.First(), recordType);
                                    if (targetPropInfo.IsEnum)
                                    {
                                        //if target is an enum then filter the items source for the field type
                                        var picklistFieldViewModel = fieldViewModel as PicklistFieldViewModel;
                                        var picklistOptions        = ObjectRecordService.GetPicklistKeyValues(picklistFieldViewModel.FieldName, picklistFieldViewModel.GetRecordType(), fieldType.ToString(), picklistFieldViewModel.RecordEntryViewModel.GetRecord());
                                        if (clearValue)
                                        {
                                            picklistFieldViewModel.Value = null;
                                        }
                                        picklistFieldViewModel.ItemsSource = picklistOptions;
                                    }
                                    else
                                    {
                                        //otherwise is a field input dynamic for the field's tpye
                                        //now we need to create the view model for the target field as the correct type
                                        //okay now we need to replace the old field view model for this field
                                        var explicitTargetType = fieldType == RecordFieldType.Lookup || fieldType == RecordFieldType.Customer || fieldType == RecordFieldType.Owner
                                                ? lookupService.GetLookupTargetType(selectedFieldName, selectedFieldRecordType)
                                                : null;
                                        var explicitPicklistOptions = fieldType == RecordFieldType.Picklist ||
                                                                      fieldType == RecordFieldType.Status ||
                                                                      fieldType == RecordFieldType.State ||
                                                                      fieldType == RecordFieldType.Integer
                                                ? lookupService.GetPicklistKeyValues(selectedFieldName, selectedFieldRecordType)
                                                : null;
                                        if (clearValue)
                                        {
                                            fieldViewModel.ValueObject = null;
                                        }
                                        var newFieldViewModel = fieldMetadata.CreateFieldViewModel(re.GetRecordType(), re.RecordService, re, re.ApplicationController, explicitFieldType: fieldType, explicitLookupTargetType: explicitTargetType, explicitPicklistOptions: explicitPicklistOptions);
                                        var section           = re.FieldSections.First(s => s.SectionLabel == sectionName);
                                        var index             = section.Fields.Count;
                                        for (var i = 0; i < section.Fields.Count; i++)
                                        {
                                            if (section.Fields[i].FieldName == fieldViewModel.FieldName)
                                            {
                                                index = i;
                                                break;
                                            }
                                        }

                                        re.DoOnMainThread(() =>
                                        {
                                            if (section.Fields.Count > index)
                                            {
                                                section.Fields.RemoveAt(index);
                                            }

                                            if (clearValue)
                                            {
                                                fieldViewModel.ValueObject = null;
                                            }
                                            section.Fields.Insert(index, newFieldViewModel);
                                            re.RefreshVisibility();
                                        });
                                    }
                                }
                            }
                        }
                    }
                }));
            }
        }