| | | 1 | | using pva.SuperV.Api.Exceptions; |
| | | 2 | | using pva.SuperV.Api.Mappers; |
| | | 3 | | using pva.SuperV.Engine; |
| | | 4 | | using pva.SuperV.Engine.Exceptions; |
| | | 5 | | using pva.SuperV.Engine.FieldFormatters; |
| | | 6 | | using pva.SuperV.Model; |
| | | 7 | | using pva.SuperV.Model.FieldDefinitions; |
| | | 8 | | using pva.SuperV.Model.Services; |
| | | 9 | | |
| | | 10 | | namespace pva.SuperV.Api.Services.FieldDefinitions |
| | | 11 | | { |
| | | 12 | | public class FieldDefinitionService : BaseService, IFieldDefinitionService |
| | | 13 | | { |
| | | 14 | | private readonly ILogger logger; |
| | 13 | 15 | | private readonly Dictionary<string, Comparison<FieldDefinitionModel>> sortOptions = new() |
| | 13 | 16 | | { |
| | 34 | 17 | | { "name", new Comparison<FieldDefinitionModel>((a, b) => a.Name.CompareTo(b.Name)) } |
| | 13 | 18 | | }; |
| | | 19 | | |
| | 13 | 20 | | public FieldDefinitionService(ILoggerFactory loggerFactory) |
| | 13 | 21 | | { |
| | 13 | 22 | | this.logger = loggerFactory.CreateLogger(this.GetType()); |
| | 13 | 23 | | } |
| | | 24 | | |
| | | 25 | | public async Task<List<FieldDefinitionModel>> GetFieldsAsync(string projectId, string className) |
| | 11 | 26 | | { |
| | 11 | 27 | | logger.LogDebug("Getting fields for {ClassName} for {ProjectId}", |
| | 11 | 28 | | className, projectId); |
| | 216 | 29 | | return await Task.FromResult(GetClassEntity(projectId, className).FieldDefinitions.Values.Select(field => Fi |
| | 11 | 30 | | } |
| | | 31 | | |
| | | 32 | | public async Task<FieldDefinitionModel> GetFieldAsync(string projectId, string className, string fieldName) |
| | 1 | 33 | | { |
| | 1 | 34 | | logger.LogDebug("Getting field {FieldName} for {ClassName} for {ProjectId}", |
| | 1 | 35 | | fieldName, className, projectId); |
| | 1 | 36 | | if (GetClassEntity(projectId, className).FieldDefinitions.TryGetValue(fieldName, out IFieldDefinition? field |
| | 1 | 37 | | { |
| | 1 | 38 | | return await Task.FromResult(FieldDefinitionMapper.ToDto(fieldDefinition)); |
| | | 39 | | } |
| | 0 | 40 | | return await Task.FromException<FieldDefinitionModel>(new UnknownEntityException("Field", fieldName)); |
| | 1 | 41 | | } |
| | | 42 | | |
| | | 43 | | public async Task<PagedSearchResult<FieldDefinitionModel>> SearchFieldsAsync(string projectId, string className, |
| | 9 | 44 | | { |
| | 9 | 45 | | logger.LogDebug("Searching for fields with filter {NameFilter} for {ClassName} for {ProjectId} page number { |
| | 9 | 46 | | search.NameFilter, className, projectId, search.PageNumber, search.PageSize); |
| | 9 | 47 | | List<FieldDefinitionModel> allFieldDefinitions = await GetFieldsAsync(projectId, className); |
| | 9 | 48 | | List<FieldDefinitionModel> fieldDefinitions = FilterFieldDefinitions(allFieldDefinitions, search); |
| | 9 | 49 | | fieldDefinitions = SortResult(fieldDefinitions, search.SortOption, sortOptions); |
| | 8 | 50 | | return CreateResult(search, allFieldDefinitions, fieldDefinitions); |
| | 8 | 51 | | } |
| | | 52 | | |
| | | 53 | | |
| | | 54 | | public async Task<List<FieldDefinitionModel>> CreateFieldsAsync(string projectId, string className, List<FieldDe |
| | 4 | 55 | | { |
| | 4 | 56 | | logger.LogDebug("Creating fields for {ClassName} for {ProjectId}", |
| | 4 | 57 | | className, projectId); |
| | 4 | 58 | | if (GetProjectEntity(projectId) is WipProject wipProject) |
| | 4 | 59 | | { |
| | 4 | 60 | | List<FieldDefinitionModel> createdFieldDefinitions = []; |
| | 4 | 61 | | Class clazz = GetClassEntity(wipProject, className); |
| | | 62 | | try |
| | 4 | 63 | | { |
| | 4 | 64 | | createRequests.ForEach(fieldDefinition => |
| | 82 | 65 | | { |
| | 82 | 66 | | logger.LogDebug("Creating field {FieldName} of type {FieldType} for {ClassName} for {ProjectId}" |
| | 82 | 67 | | fieldDefinition.Name, fieldDefinition.FieldType, className, projectId); |
| | 82 | 68 | | FieldFormatter? fieldFormatter = null; |
| | 82 | 69 | | if (fieldDefinition.ValueFormatter is not null) |
| | 17 | 70 | | { |
| | 17 | 71 | | fieldFormatter = wipProject.GetFormatter(fieldDefinition.ValueFormatter); |
| | 17 | 72 | | } |
| | 82 | 73 | | createdFieldDefinitions.Add(FieldDefinitionMapper.ToDto(clazz.AddField(FieldDefinitionMapper.Fro |
| | 86 | 74 | | }); |
| | 4 | 75 | | return await Task.FromResult(createdFieldDefinitions); |
| | | 76 | | } |
| | 0 | 77 | | catch (SuperVException e) |
| | 0 | 78 | | { |
| | | 79 | | // If exception while creatig one of the fields, remove all the already created fields. |
| | | 80 | | try |
| | 0 | 81 | | { |
| | 0 | 82 | | createdFieldDefinitions.ForEach(fieldDefinition => clazz.RemoveField(fieldDefinition.Name)); |
| | 0 | 83 | | } |
| | 0 | 84 | | catch (SuperVException) |
| | 0 | 85 | | { |
| | | 86 | | // Ignore execption while deleting |
| | 0 | 87 | | } |
| | 0 | 88 | | return await Task.FromException<List<FieldDefinitionModel>>(e); |
| | | 89 | | } |
| | 0 | 90 | | } |
| | 0 | 91 | | return await Task.FromException<List<FieldDefinitionModel>>(new NonWipProjectException(projectId)); |
| | 4 | 92 | | } |
| | | 93 | | |
| | | 94 | | public async Task<FieldDefinitionModel> UpdateFieldAsync(string projectId, string className, string fieldName, F |
| | 3 | 95 | | { |
| | 3 | 96 | | logger.LogDebug("Updating field {FieldName} of type {FieldType} for {ClassName} for {ProjectId}", |
| | 3 | 97 | | updateRequest.Name, updateRequest.FieldType, className, projectId); |
| | 3 | 98 | | if (GetProjectEntity(projectId) is WipProject wipProject) |
| | 3 | 99 | | { |
| | 3 | 100 | | _ = GetClassEntity(wipProject, className); |
| | 3 | 101 | | if (updateRequest.Name?.Equals(fieldName) != false) |
| | 2 | 102 | | { |
| | 2 | 103 | | IFieldDefinition fieldDefinitionUpdate = FieldDefinitionMapper.FromDto(updateRequest); |
| | 2 | 104 | | return await Task.FromResult(FieldDefinitionMapper.ToDto(wipProject.UpdateField(className, fieldName |
| | | 105 | | } |
| | 1 | 106 | | return await Task.FromException<FieldDefinitionModel>(new EntityPropertyNotChangeableException("field", |
| | | 107 | | } |
| | 0 | 108 | | return await Task.FromException<FieldDefinitionModel>(new NonWipProjectException(projectId)); |
| | 1 | 109 | | } |
| | | 110 | | |
| | | 111 | | public async ValueTask DeleteFieldAsync(string projectId, string className, string fieldName) |
| | 1 | 112 | | { |
| | 1 | 113 | | logger.LogDebug("Deleting field {FieldName} for {ClassName} for {ProjectId}", |
| | 1 | 114 | | fieldName, className, projectId); |
| | 1 | 115 | | if (GetProjectEntity(projectId) is WipProject wipProject) |
| | 1 | 116 | | { |
| | 1 | 117 | | GetClassEntity(wipProject, className).RemoveField(fieldName); |
| | 1 | 118 | | await ValueTask.CompletedTask; |
| | 1 | 119 | | return; |
| | | 120 | | } |
| | 0 | 121 | | await ValueTask.FromException(new NonWipProjectException(projectId)); |
| | 1 | 122 | | } |
| | | 123 | | private static List<FieldDefinitionModel> FilterFieldDefinitions(List<FieldDefinitionModel> allFieldDefinitions, |
| | 9 | 124 | | { |
| | 9 | 125 | | List<FieldDefinitionModel> filteredClasses = allFieldDefinitions; |
| | 9 | 126 | | if (!String.IsNullOrEmpty(search.NameFilter)) |
| | 2 | 127 | | { |
| | 68 | 128 | | filteredClasses = [.. filteredClasses.Where(fieldDefinition => fieldDefinition.Name.Contains(search.Name |
| | 2 | 129 | | } |
| | 9 | 130 | | return filteredClasses; |
| | 9 | 131 | | } |
| | | 132 | | } |
| | | 133 | | } |
| | | 134 | | |