public async Task <IActionResult> DeactivateLocality([Required][FromBody] DeactivateLocalityRequest deactivateLocalityRequest, CancellationToken cancellationToken = default) { var(_, isFailure, error) = await _localityManagementService.DeactivateLocality(deactivateLocalityRequest, cancellationToken); if (isFailure) { return(BadRequestWithProblemDetails(error)); } return(NoContent()); }
public async Task <Result> DeactivateLocality(DeactivateLocalityRequest deactivateLocalityRequest, CancellationToken cancellationToken = default) { var deactivatedLocalityHtId = deactivateLocalityRequest.DeactivatedLocalityHtId; var localityToReplaceHtId = deactivateLocalityRequest.LocalityToReplaceHtId; return(await GetLocalityWithAccommodationsAndZones(deactivatedLocalityHtId) .Bind(dl => GetLocalityToReplace(dl, localityToReplaceHtId)) .Bind(ValidateLocalities) .BindWithTransaction(_dbContext, l => Result.Success(l) .Tap(UpdateDeactivatedLocalityAccommodations) .Tap(UpdateDeactivatedLocalityZones) .Tap(DeactivateLocality)) .Tap(PublishLocalityChanges)); async Task <Result <Locality> > GetLocalityWithAccommodationsAndZones(string htId) { var(_, isGettingIdFailure, id, gettingIdError) = GetId(htId, MapperLocationTypes.Locality); if (isGettingIdFailure) { return(Result.Failure <Locality>(gettingIdError)); } var locality = await _dbContext.Localities .Include(l => l.Accommodations) .Include(l => l.LocalityZones) .SingleOrDefaultAsync(l => l.Id == id && l.IsActive, cancellationToken); if (locality is null) { return(Result.Failure <Locality>($"Failed to retrieve the locality by the requested htId '{htId}'")); } return(locality !); } async Task <Result <(Locality, Locality)> > GetLocalityToReplace(Locality deactivatedLocality, string localityToReplaceHtId) { var(_, isGettingIdFailure, localityToReplaceId, gettingIdError) = GetId(localityToReplaceHtId, MapperLocationTypes.Locality); if (isGettingIdFailure) { return(Result.Failure <(Locality, Locality)>(gettingIdError)); } var localityToReplace = await _dbContext.Localities.Include(l => l.Country) .SingleOrDefaultAsync(l => l.Id == localityToReplaceId && l.IsActive, cancellationToken); if (localityToReplace is null) { return(Result.Failure <(Locality, Locality)>($"Failed to retrieve the substitutional locality by htId '{localityToReplaceHtId}")); } return(deactivatedLocality, localityToReplace); } Result <(Locality deactivatedLocality, Locality substitutionalLocality)> ValidateLocalities( (Locality deactivatedLocality, Locality substitutionalLocality) localities) { if (localities.deactivatedLocality.CountryId != localities.substitutionalLocality.CountryId) { return(Result.Failure <(Locality, Locality)>($"Country of the original locality and substitutional locality mustn't be different")); } return(localities); } async Task UpdateDeactivatedLocalityAccommodations((Locality deactivatedLocality, Locality localityToReplace) localities) { var deactivatedLocality = localities.deactivatedLocality; var localityToReplace = localities.localityToReplace; var accommodations = deactivatedLocality.Accommodations.ToList(); await UpdateAccommodationsLocalityId(localityToReplace, accommodations, cancellationToken); } async Task UpdateDeactivatedLocalityZones((Locality deactivatedLocality, Locality localityToReplace) localities) { var deactivatedLocality = localities.deactivatedLocality; var localityToReplace = localities.localityToReplace; var localityZones = deactivatedLocality.LocalityZones; if (!localityZones.Any()) { return; } foreach (var localityZone in localityZones) { localityZone.Modified = DateTimeOffset.UtcNow; localityZone.LocalityId = localityToReplace.Id; } _dbContext.UpdateRange(localityZones); await _dbContext.SaveChangesAsync(cancellationToken); } async Task DeactivateLocality((Locality deactivatedLocality, Locality localityToReplace) localities) { var deactivatedLocality = localities.deactivatedLocality; deactivatedLocality.Modified = DateTimeOffset.UtcNow; deactivatedLocality.IsActive = false; _dbContext.Update(deactivatedLocality); await _dbContext.SaveChangesAsync(cancellationToken); } async Task PublishLocalityChanges((Locality deactivatedLocality, Locality localityToReplace) localities) { var deactivatedLocality = localities.deactivatedLocality; var localityToReplace = localities.localityToReplace; await _localityChangePublisher.PublishRemovedLocalities(new() { deactivatedLocality.Id }); await _localityChangePublisher.PublishUpdatedLocalities(new() { new(localityToReplace.Id, localityToReplace.Names.En, localityToReplace.Country.Names.En, localityToReplace.Country.Code) }); } }