using Disco.Data.Repository; using Disco.Models.Services.Exporting; using Disco.Models.UI.Shared; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Linq.Expressions; using System.Web.Mvc; namespace Disco.Web.Models.Shared { public static class ExportFieldsModel { public static ExportFieldsModel Create(V options, V defaultOptions, params string[] ignoreProperties) where V : IExportOptions { return new ExportFieldsModel(options, defaultOptions, ignoreProperties); } } public class ExportFieldsModel : SharedExportFieldsModel where T : IExportOptions { public T Options { get; set; } public List FieldGroups { get; set; } public ExportFieldsModel(T options, T defaultOptions, params string[] ignoreProperties) { Options = options; FieldGroups = GetFields(options, defaultOptions, ignoreProperties); } private static List GetFields(T options, T defaultOptions, params string[] ignoreProperties) { var properties = new List(); foreach (var prop in typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)) { if (prop.PropertyType != typeof(bool) || ignoreProperties.Contains(prop.Name)) continue; var display = prop.GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault() as DisplayAttribute; if (display == null) continue; properties.Add(new ExportOptionField() { GroupName = display.GroupName, Name = prop.Name, DisplayName = display.Name, Description = display.Description, IsDefault = (bool)prop.GetValue(defaultOptions), IsChecked = (bool)prop.GetValue(options), }); } return properties .GroupBy(p => p.GroupName) .Select(g => { var group = new ExportOptionGroup(g.Key); group.AddRange(g); return group; }) .ToList(); } public void AddCustomUserDetails(Expression>> modelAccessor, int groupIndex = -1) { List userCustomDetailKeys; using (var database = new DiscoDataContext()) userCustomDetailKeys = database.UserDetails.Where(d => d.Scope == "Details").Select(d => d.Key).Distinct().OrderBy(k => k).ToList(); if (userCustomDetailKeys.Any()) { var fieldKey = ((MemberExpression)modelAccessor.Body).Member.Name; var checkedKeys = modelAccessor.Compile().Invoke(Options); var group = new ExportOptionGroup("User Custom Details"); foreach (var key in userCustomDetailKeys) { var displayName = key.TrimEnd('*', '&'); group.Add(new ExportOptionField() { GroupName = group.Name, Name = key, DisplayName = displayName, Description = $"{displayName} custom detail for the user", IsChecked = checkedKeys?.Contains(key) ?? false, CustomKey = fieldKey, CustomValue = key, }); } if (groupIndex < 0) FieldGroups.Add(group); else FieldGroups.Insert(groupIndex, group); } } } }