Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GetByFilter for MinistryAdmin #803

Merged
merged 3 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,31 @@ public async Task<IActionResult> Profile()
return Ok(ministryAdmin);
}

/// <summary>
/// Get MinistryAdmins that match filter's parameters.
/// </summary>
/// <param name="filter">Entity that represents searching parameters.</param>
/// <returns><see cref="SearchResult{MinistryAdminDto}"/>, or no content.</returns>
[HasPermission(Permissions.SystemManagement)]
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(SearchResult<MinistryAdminDto>))]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetByFilter([FromQuery] MinistryAdminFilter filter)
{
var ministryAdmins = await ministryAdminService.GetByFilter(filter).ConfigureAwait(false);

if (ministryAdmins.TotalAmount < 1)
{
return NoContent();
}

return Ok(ministryAdmins);
}

/// <summary>
/// Method for creating new MinistryAdmin.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions OutOfSchool/OutOfSchool.WebApi/Models/MinistryAdminFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace OutOfSchool.WebApi.Models;

public class MinistryAdminFilter : SearchStringFilter
{
public Guid InstitutionId { get; set; } = Guid.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,12 @@ public interface IMinistryAdminService
/// <returns>The task result contains <see langword="true" /> if provider is subordinate of the ministry admin
/// filter; otherwise, <see langword="false" />.</returns>
Task<bool> IsProviderSubordinateAsync(string ministryAdminUserId, Guid providerId);

/// <summary>
/// Get Ministry Admins from the database that match filter's parameters.
/// </summary>
/// <param name="filter">Filter with specified searching parameters.</param>
/// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.
/// The task result contains the <see cref="SearchResult{MinistryAdminDto}"/> that contains found elements.</returns>
Task<SearchResult<MinistryAdminDto>> GetByFilter(MinistryAdminFilter filter);
}
75 changes: 74 additions & 1 deletion OutOfSchool/OutOfSchool.WebApi/Services/MinistryAdminService.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using AutoMapper;
using System.Linq.Expressions;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

using Newtonsoft.Json;
using OutOfSchool.Common.Models;
using OutOfSchool.Services.Enums;
using OutOfSchool.WebApi.Models;

namespace OutOfSchool.WebApi.Services;
Expand Down Expand Up @@ -86,6 +88,48 @@ public async Task<ResponseDto> CreateMinistryAdminAsync(string userId, CreateMin
return response;
}

/// <inheritdoc/>
public async Task<SearchResult<MinistryAdminDto>> GetByFilter(MinistryAdminFilter filter)
{
logger.LogInformation("Getting all Ministry admins started (by filter).");

filter ??= new MinistryAdminFilter();
ModelValidationHelper.ValidateOffsetFilter(filter);

var filterPredicate = PredicateBuild(filter);

int count = await institutionAdminRepository.Count(filterPredicate).ConfigureAwait(false);

var sortExpression = new Dictionary<Expression<Func<InstitutionAdmin, object>>, SortDirection>
{
{ x => x.User.LastName, SortDirection.Ascending },
};
var institutionAdmins = await institutionAdminRepository
.Get(
skip: filter.From,
take: filter.Size,
includeProperties: string.Empty,
where: filterPredicate,
orderBy: sortExpression,
asNoTracking: false)
.ToListAsync()
.ConfigureAwait(false);

logger.LogInformation(!institutionAdmins.Any()
? "Parents table is empty."
: $"All {institutionAdmins.Count} records were successfully received from the Parent table");

var ministryAdminsDto = institutionAdmins.Select(admin => mapper.Map<MinistryAdminDto>(admin)).ToList();

var result = new SearchResult<MinistryAdminDto>()
{
TotalAmount = count,
Entities = ministryAdminsDto,
};

return result;
}

/// <inheritdoc/>
public async Task<MinistryAdminDto> Update(MinistryAdminDto ministryAdminDto)
{
Expand Down Expand Up @@ -215,4 +259,33 @@ public async Task<bool> IsProviderSubordinateAsync(string ministryAdminUserId, G
.Any(x => x.UserId == ministryAdminUserId
&& x.Institution.RelatedProviders.Any(rp => rp.Id == providerId)).ConfigureAwait(false);
}

private static Expression<Func<InstitutionAdmin, bool>> PredicateBuild(MinistryAdminFilter filter)
{
var predicate = PredicateBuilder.True<InstitutionAdmin>();

if (!string.IsNullOrWhiteSpace(filter.SearchString))
{
var tempPredicate = PredicateBuilder.False<InstitutionAdmin>();

foreach (var word in filter.SearchString.Split(' ', ',', StringSplitOptions.RemoveEmptyEntries))
{
tempPredicate = tempPredicate.Or(
x => x.User.FirstName.StartsWith(word, StringComparison.InvariantCultureIgnoreCase)
|| x.User.LastName.StartsWith(word, StringComparison.InvariantCultureIgnoreCase)
|| x.User.Email.StartsWith(word, StringComparison.InvariantCultureIgnoreCase)
|| x.Institution.Title.StartsWith(word, StringComparison.InvariantCulture)
|| x.User.PhoneNumber.StartsWith(word, StringComparison.InvariantCultureIgnoreCase));
}

predicate = predicate.And(tempPredicate);
}

if (filter.InstitutionId != Guid.Empty)
{
predicate = predicate.And(a => a.Institution.Id == filter.InstitutionId);
}

return predicate;
}
}
2 changes: 1 addition & 1 deletion OutOfSchool/OutOfSchool.WebApi/Util/MappingProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ public MappingProfile()
.ForMember(dest => dest.PhoneNumber, opt => opt.MapFrom(src => src.User.PhoneNumber))
.ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.User.Email))
.ForMember(dest => dest.AccountStatus, m => m.Ignore())
.ForMember(dest => dest.Gender, m => m.Ignore());
.ForMember(dest => dest.Gender, m => m.MapFrom(src => src.User.Gender));

CreateMap<ProviderChangesLogRequest, ChangesLogFilter>()
.ForMember(dest => dest.EntityType, opt => opt.Ignore())
Expand Down