Esempio n. 1
0
        public async Task <IActionResult> MoveLocalityCandidatesToLocalitySynonyms([FromBody] MoveLocalitySynonymsRequest request, CancellationToken cancellationToken = default)
        {
            var(_, isFailure, error) = await _localityCandidateManagementService.MoveLocalityCandidatesToLocalitySynonyms(request, cancellationToken);

            if (isFailure)
            {
                return(BadRequestWithProblemDetails(error));
            }

            return(NoContent());
        }
        public Task <Result> MoveLocalityCandidatesToLocalitySynonyms(MoveLocalitySynonymsRequest request, CancellationToken cancellationToken)
        {
            var localityCandidateIds = request.LocalityCandidateIds;
            var localityId           = request.LocalityId;

            return(GetLocalityCandidates(localityCandidateIds, cancellationToken)
                   .Ensure(lc => lc.Any(), "Failed to retrieve any locality candidate by the presented ids")
                   .Bind(async lc => await CheckIfLocalityAndCandidateCountriesAreSame(lc, localityId))
                   .Bind(CheckIfLocalitySynonymsDoNotExist)
                   .BindWithTransaction(_dbContext, lc => Result.Success(lc)
                                        .Tap(llc => RemoveLocalityCandidates(llc, cancellationToken))
                                        .Tap(AddSynonyms))
                   .Finally(result =>
            {
                if (result.IsFailure)
                {
                    return Result.Failure(result.Error);
                }

                _logger.LogMovingLocalityCandidatesToLocalitySynonyms(string.Join(", ", result.Value.Select(lc => lc.Names.En)), localityId.ToString());

                return Result.Success();
            }));


            async Task <Result <List <LocalityCandidate> > > CheckIfLocalityAndCandidateCountriesAreSame(List <LocalityCandidate> localityCandidates, int localityId)
            {
                var locality = await _dbContext.Localities.SingleOrDefaultAsync(l => l.Id == localityId, cancellationToken);

                if (locality is null)
                {
                    return(Result.Failure <List <LocalityCandidate> >($"Locality with id '{localityId}' doesn't exist"));
                }

                var localityCandidatesCountryIds = localityCandidates.Select(c => c.CountryId).ToList();

                if (localityCandidatesCountryIds.Any(lcc => lcc != locality.CountryId))
                {
                    return(Result.Failure <List <LocalityCandidate> >("Locality and locality candidates countries are different"));
                }

                return(localityCandidates);
            }

            async Task <Result <List <LocalityCandidate> > > CheckIfLocalitySynonymsDoNotExist(List <LocalityCandidate> localityCandidates)
            {
                var existedLocalitySynonyms = await _dbContext.LocalitySynonyms.Where(ls => ls.LocalityId == localityId)
                                              .Where(ls => localityCandidates.Select(lc => lc.Names.En).Contains(ls.Names.En))
                                              .ToListAsync(cancellationToken);

                return(existedLocalitySynonyms.Any()
                    ? Result.Failure <List <LocalityCandidate> >($"Failed to add locality synonyms." +
                                                                 $" '{string.Join(", ", existedLocalitySynonyms.Select(l => l.Names.En))}' locality synonyms are already exist")
                    : localityCandidates);
            }

            Task AddSynonyms(List <LocalityCandidate> localityCandidates)
            {
                var localitySynonyms = localityCandidates.Select(lc => Build(lc, localityId));

                _dbContext.AddRange(localitySynonyms);

                return(_dbContext.SaveChangesAsync(cancellationToken));
            }
        }