public async Task <IActionResult> GetServices([FromQuery] ServicesQueryParam queryParam)
 {
     try
     {
         return(Ok(await _getServicesUseCase.Execute(queryParam).ConfigureAwait(false)));
     }
     catch (UseCaseException e)
     {
         return(BadRequest(e));
     }
 }
        public async Task <List <ServiceResponse> > Execute(ServicesQueryParam servicesQuery)
        {
            var servicesDomain = await _servicesGateway.GetServicesAsync(servicesQuery).ConfigureAwait(false);

            if (servicesDomain == null)
            {
                throw new UseCaseException()
                      {
                          UserErrorMessage = $"Could not retrieve services using the supplied search parameters"
                      }
            }
            ;

            return(servicesDomain.ToResponse());
        }
    }
        public async Task <List <ServiceDomain> > GetServicesAsync(ServicesQueryParam servicesQuery)
        {
            // Search       search term to use (searches on [name] column for the MVP)
            // Sort         the column name by which to sort
            // Direction    sort order; asc, desc
            // Limit        maximum number of records to return
            // Offset       number of records to skip for pagination

            List <ServiceDomain> response = new List <ServiceDomain>();
            var direction = ConvertToEnum(servicesQuery.Direction);

            if (direction == SortDirection.None)
            {
                throw new UseCaseException()
                      {
                          UserErrorMessage = "The sort direction was not valid (must be one of asc, desc)"
                      }
            }
            ;

            var matchingServices = Context.Services.AsQueryable();

            // handle search
            if (!string.IsNullOrWhiteSpace(servicesQuery.Search))
            {
                matchingServices = matchingServices.Where(s => EF.Functions.ILike(s.Name, $"%{servicesQuery.Search}%"));
            }

            // handle sort by column name and sort direction
            var entityPropName = GetEntityPropertyForColumnName(typeof(User), servicesQuery.Sort);

            if (entityPropName == null)
            {
                throw new UseCaseException()
                      {
                          UserErrorMessage = $"The 'Sort' parameter contained the value '{servicesQuery.Sort}' " +
                                             "which is not a valid column name"
                      }
            }
            ;

            matchingServices = (direction == SortDirection.Asc) ?
                               matchingServices.OrderBy(s => EF.Property <Service>(s, entityPropName)) :
                               matchingServices.OrderByDescending(s => EF.Property <Service>(s, entityPropName));

            // handle pagination options
            if (servicesQuery.Offset.HasValue)
            {
                matchingServices = matchingServices.Skip(servicesQuery.Offset.Value);
            }

            if (servicesQuery.Limit.HasValue)
            {
                matchingServices = matchingServices.Take(servicesQuery.Limit.Value);
            }

            try
            {
                var services = await matchingServices
                               .Where(s => s.Status != ServiceStatus.Deleted)
                               .Include(s => s.Organisation)
                               .ThenInclude(o => o.UserOrganisations)
                               .ThenInclude(uo => uo.User)
                               .Include(s => s.Image)
                               .Include(s => s.ServiceLocations)
                               .Include(s => s.ServiceTaxonomies)
                               .ThenInclude(st => st.Taxonomy)
                               .AsNoTracking()
                               .ToListAsync()
                               .ConfigureAwait(false);

                response = _mapper.ToDomain(services);
            }
            catch (InvalidOperationException e)
            {
                throw new UseCaseException()
                      {
                          UserErrorMessage = "Could not run the services search query with the supplied input parameters",
                          DevErrorMessage  = e.Message
                      };
            }

            return(response);
        }