Skip to content

Commit

Permalink
Merge pull request #340 from UKGovernmentBEIS/dvs-311-removal-emails-…
Browse files Browse the repository at this point in the history
…duty-to-remove

feat(remove-service): email notification and  status update changes
  • Loading branch information
JoeGLauria authored Jan 24, 2025
2 parents 834cd15 + 75d64b4 commit 9efe963
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using DVSRegister.BusinessLogic.Models.CAB;
using DVSRegister.CommonUtility.Models;
using DVSRegister.CommonUtility.Models.Enums;

namespace DVSRegister.BusinessLogic.Services
{
public interface IRemoveProvider2iService
{
//Remove provider
public Task<ProviderProfileDto?> GetProviderAndServiceDetailsByRemovalToken(string token, string tokenId);
public Task<GenericResponse> UpdateRemovalStatus(string token, string tokenId, ProviderProfileDto providerDto, string loggedInUserEmail);
public Task<GenericResponse> UpdateRemovalStatus(TeamEnum team, string token, string tokenId, ProviderProfileDto providerDto, string loggedInUserEmail);
public Task<bool> RemoveRemovalToken(string token, string tokenId, string loggedInUserEmail);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,63 @@ public RemoveProvider2iService(IRemoveProvider2iRepository removeProvider2iRepos
if (removeProviderToken.Provider != null)
{
var provider = await removeProvider2iRepository.GetProviderDetails(removeProviderToken.ProviderProfileId);
ProviderProfileDto providerProfileDto = mapper.Map<ProviderProfileDto>(provider);
return providerProfileDto;
if (removeProviderToken.RemoveTokenServiceMapping != null && removeProviderToken.RemoveTokenServiceMapping.Count>0)
{
var mappedServiceIds = removeProviderToken.RemoveTokenServiceMapping.Where(mapping => mapping.RemoveProviderTokenId == removeProviderToken.Id).Select(mapping => mapping.ServiceId).ToList();
ProviderProfileDto providerProfileDto = mapper.Map<ProviderProfileDto>(provider);
providerProfileDto.Services = providerProfileDto.Services.Where(service => mappedServiceIds.Contains(service.Id)).ToList();
return providerProfileDto;

}
else
{
ProviderProfileDto providerProfileDto = mapper.Map<ProviderProfileDto>(provider);
return providerProfileDto;
}

}
else
{
return null;
}
}

public async Task<GenericResponse> UpdateRemovalStatus(string token, string tokenId, ProviderProfileDto providerDto, string loggedInUserEmail)
public async Task<GenericResponse> UpdateRemovalStatus(TeamEnum team, string token, string tokenId, ProviderProfileDto providerDto, string loggedInUserEmail)
{
GenericResponse genericResponse = new();
RemoveProviderToken removeProviderToken = await removeProvider2iRepository.GetRemoveProviderToken(token, tokenId);
TeamEnum teamEnum = TeamEnum.Provider;// To Do : update after correcting Removal Reason to int



if (!string.IsNullOrEmpty(removeProviderToken.Token) && !string.IsNullOrEmpty(removeProviderToken.TokenId)) //proceed update status if token exists
{
if (removeProviderToken.RemoveTokenServiceMapping != null && removeProviderToken.RemoveTokenServiceMapping.Count > 0) // remove selected services in this case
{
List<int> serviceIds = removeProviderToken.RemoveTokenServiceMapping.Select(mapping => mapping.ServiceId).ToList();
genericResponse = await removeProvider2iRepository.UpdateRemovalStatus(providerDto.Id, teamEnum, EventTypeEnum.RemoveServices2i, serviceIds, loggedInUserEmail);
List<int> serviceIds = providerDto.Services.Select(s => s.Id).ToList();
genericResponse = await removeProvider2iRepository.UpdateRemovalStatus(providerDto.Id, team, EventTypeEnum.RemoveServices2i, serviceIds, loggedInUserEmail);
// get updated service list and decide provider status
ProviderProfile providerProfile = await removeProvider2iRepository.GetProviderWithAllServices(providerDto.Id);
// update provider status
ProviderStatusEnum providerStatus = GetProviderStatus(providerProfile.Services, providerProfile.ProviderStatus);
genericResponse = await removeProvider2iRepository.UpdateProviderStatus(providerDto.Id, providerStatus, loggedInUserEmail, EventTypeEnum.RemoveProvider2i);

}
else
{
genericResponse = await removeProvider2iRepository.UpdateRemovalStatus(providerDto.Id, teamEnum, EventTypeEnum.RemoveServices2i, null, loggedInUserEmail);
{
genericResponse = await removeProvider2iRepository.UpdateRemovalStatus(providerDto.Id, team, EventTypeEnum.RemoveServices2i, null, loggedInUserEmail);
}

if (genericResponse.Success)
{
// ToDo : send email confirmation
if(team == TeamEnum.Provider)
{
await emailSender.SendRemovalRequestConfirmedToDIP(providerDto.PrimaryContactFullName, providerDto.PrimaryContactEmail);
}

if (team == TeamEnum.DSIT)
{
//to do
}
}

}
Expand All @@ -67,5 +95,49 @@ public async Task<bool> RemoveRemovalToken(string token, string tokenId, string
{
return await removeProvider2iRepository.RemoveRemovalToken(token, tokenId, loggedInUserEmail);
}

#region private methods
private ProviderStatusEnum GetProviderStatus(ICollection<Service> services, ProviderStatusEnum currentStatus)
{
ProviderStatusEnum providerStatus = currentStatus;
if (services != null && services.Count > 0)
{

if (services.All(service => service.ServiceStatus == ServiceStatusEnum.Removed))
{
providerStatus = ProviderStatusEnum.RemovedFromRegister;
}

var priorityOrder = new List<ServiceStatusEnum>
{
ServiceStatusEnum.CabAwaitingRemovalConfirmation,
ServiceStatusEnum.ReadyToPublish,
ServiceStatusEnum.AwaitingRemovalConfirmation,
ServiceStatusEnum.Published,
ServiceStatusEnum.Removed
};

ServiceStatusEnum highestPriorityStatus = services.Select(service => service.ServiceStatus).OrderBy(status => priorityOrder.IndexOf(status)).FirstOrDefault();


switch (highestPriorityStatus)
{
case ServiceStatusEnum.CabAwaitingRemovalConfirmation:
return ProviderStatusEnum.CabAwaitingRemovalConfirmation;
case ServiceStatusEnum.ReadyToPublish:
bool hasPublishedServices = services.Any(service => service.ServiceStatus == ServiceStatusEnum.Published);
return hasPublishedServices ? ProviderStatusEnum.PublishedActionRequired : ProviderStatusEnum.ActionRequired;
case ServiceStatusEnum.AwaitingRemovalConfirmation:
return ProviderStatusEnum.AwaitingRemovalConfirmation;
case ServiceStatusEnum.Published:
return ProviderStatusEnum.Published;
default:
return ProviderStatusEnum.AwaitingRemovalConfirmation;
}

}
return providerStatus;
}
#endregion
}
}
21 changes: 21 additions & 0 deletions DVSRegister.CommonUtility/Email/GovUkNotifyApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,27 @@ public async Task<bool> SendAgreementToPublishToDSIT(string companyName, string
};
return await SendEmail(emailModel);
}

#endregion

#region Remove
public async Task<bool> SendRemovalRequestConfirmedToDIP(string recipientName, string emailAddress)
{
var template = govUkNotifyConfig.ProviderRemovalRequestConfirmed;

var personalisation = new Dictionary<string, dynamic>
{
{ template.RecipientName, recipientName}

};
var emailModel = new GovUkNotifyEmailModel
{
EmailAddress = govUkNotifyConfig.OfDiaEmailId,
TemplateId = template.Id,
Personalisation = personalisation
};
return await SendEmail(emailModel);
}
#endregion
}
}
5 changes: 5 additions & 0 deletions DVSRegister.CommonUtility/Email/IEmailSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ public interface IEmailSender
public Task<bool> SendAgreementToPublishToDSIT(string companyName, string serviceName);
public Task<bool> SendAgreementToPublishToDIP(string companyName, string serviceName, string recipientName, string emailAddress);

//remove emails

public Task<bool> SendRemovalRequestConfirmedToDIP(string recipientName, string emailAddress);


}
}
2 changes: 1 addition & 1 deletion DVSRegister.CommonUtility/JWT/IJwtService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace DVSRegister.CommonUtility.JWT
public interface IJwtService
{
public TokenDetails GenerateToken();
public Task<TokenDetails> ValidateToken(string token);
public Task<TokenDetails> ValidateToken(string token, string audience = "");
}
}
4 changes: 2 additions & 2 deletions DVSRegister.CommonUtility/JWT/JwtService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public TokenDetails GenerateToken()
return tokenDetails;
}

public async Task<TokenDetails> ValidateToken(string token)
public async Task<TokenDetails> ValidateToken(string token, string audience = "")
{

TokenDetails tokenDetails = new TokenDetails();
Expand All @@ -60,7 +60,7 @@ public async Task<TokenDetails> ValidateToken(string token)
ValidateLifetime = false,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings.Issuer,
ValidAudience = jwtSettings.Audience,
ValidAudience = string.IsNullOrEmpty(audience)? jwtSettings.Audience: "DSIT",
RequireExpirationTime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey))
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ public class GovUkNotifyConfiguration
public AgreementToPublishTemplate AgreementToPublishTemplate { get; set; }
public AgreementToPublishToDSITTemplate AgreementToPublishToDSITTemplate { get; set; }
public AgreementToProceedApplicationToDSIT AgreementToProceedApplicationToDSIT { get; set; }
public ProviderRemovalRequestConfirmed ProviderRemovalRequestConfirmed { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace DVSRegister.CommonUtility.Models
{
public class ProviderRemovalRequestConfirmed
{
public string Id { get; set; }
public string RecipientName { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public interface IRemoveProvider2iRepository
public Task<ProviderProfile> GetProviderDetails(int providerId);
public Task<GenericResponse> UpdateRemovalStatus(int providerProfileId, TeamEnum teamEnum, EventTypeEnum eventType, List<int>? serviceIds, string loggedInUserEmail);
public Task<bool> RemoveRemovalToken(string token, string tokenId, string loggedInUserEmail);

public Task<ProviderProfile> GetProviderWithAllServices(int providerId);
public Task<GenericResponse> UpdateProviderStatus(int providerProfileId, ProviderStatusEnum providerStatus, string loggedInUserEmail, EventTypeEnum eventType);
#endregion
}
}
75 changes: 62 additions & 13 deletions DVSRegister.Data/RemoveProvider2i/RemoveProvider2iRepository.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using DVSRegister.CommonUtility.Models.Enums;
using DVSRegister.CommonUtility.Models;
using DVSRegister.CommonUtility.Models;
using DVSRegister.CommonUtility.Models.Enums;
using DVSRegister.Data.Entities;
using DVSRegister.Data.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

Expand All @@ -20,11 +19,18 @@ public RemoveProvider2iRepository(DVSRegisterDbContext context, ILogger<RemovePr
#region Remove provider
public async Task<RemoveProviderToken> GetRemoveProviderToken(string token, string tokenId)
{
return await context.RemoveProviderToken.Include(p => p.Provider).ThenInclude(p => p.Services)
return await context.RemoveProviderToken.Include(p => p.Provider).ThenInclude(p => p.Services).Include(p=>p.RemoveTokenServiceMapping)
.FirstOrDefaultAsync(e => e.Token == token && e.TokenId == tokenId) ?? new RemoveProviderToken();
}


public async Task<ProviderProfile> GetProviderWithAllServices(int providerId)
{
ProviderProfile provider = new();
provider = await context.ProviderProfile.Include(p => p.Services)
.Where(p => p.Id == providerId).FirstOrDefaultAsync() ?? new ProviderProfile();
return provider;
}
public async Task<ProviderProfile> GetProviderDetails(int providerId)
{
ProviderProfile provider = new();
Expand Down Expand Up @@ -81,14 +87,20 @@ public async Task<GenericResponse> UpdateRemovalStatus(int providerProfileId, Te
using var transaction = await context.Database.BeginTransactionAsync();
try
{
if (serviceIds != null || serviceIds?.Count > 0)// remove only selected services
if (serviceIds != null && serviceIds.Count > 0)// remove only selected services
{
var existingServices = await context.Service.Where(e => e.ProviderProfileId == providerProfileId && serviceIds.Contains(e.Id)).ToListAsync();
foreach (var existingService in existingServices)
foreach (var item in serviceIds)
{
existingService.ServiceStatus = ServiceStatusEnum.Removed;
existingService.ModifiedTime = DateTime.UtcNow;
var service = await context.Service.Where(s => s.Id == item && s.ProviderProfileId == providerProfileId).FirstOrDefaultAsync();
if (service.ServiceStatus == ServiceStatusEnum.AwaitingRemovalConfirmation)
{
service.ServiceStatus = ServiceStatusEnum.Removed;
service.ModifiedTime = DateTime.UtcNow;
service.RemovedTime = DateTime.UtcNow;
}

}

}
else // remove all services and provider
{
Expand All @@ -97,14 +109,18 @@ public async Task<GenericResponse> UpdateRemovalStatus(int providerProfileId, Te
{
existingProvider.ModifiedTime = DateTime.UtcNow;
existingProvider.ProviderStatus = ProviderStatusEnum.RemovedFromRegister;

existingProvider.RemovedTime = DateTime.UtcNow;
// Update the status of each service
if (existingProvider.Services != null)
{
foreach (var service in existingProvider.Services)
{
service.ServiceStatus = ServiceStatusEnum.Removed;
service.ModifiedTime = DateTime.UtcNow;
if (service.ServiceStatus == ServiceStatusEnum.AwaitingRemovalConfirmation )
{
service.ServiceStatus = ServiceStatusEnum.Removed;
service.ModifiedTime = DateTime.UtcNow;
service.RemovedTime = DateTime.UtcNow;
}
}
}
}
Expand Down Expand Up @@ -137,7 +153,40 @@ public async Task<bool> RemoveRemovalToken(string token, string tokenId, string

return false;
}


public async Task<GenericResponse> UpdateProviderStatus(int providerProfileId, ProviderStatusEnum providerStatus, string loggedInUserEmail, EventTypeEnum eventType)
{
GenericResponse genericResponse = new();
using var transaction = await context.Database.BeginTransactionAsync();
try
{
var existingProvider = await context.ProviderProfile.FirstOrDefaultAsync(p => p.Id == providerProfileId);
if (existingProvider != null)
{

existingProvider.ModifiedTime = DateTime.UtcNow;
existingProvider.ProviderStatus = providerStatus;

if (providerStatus == ProviderStatusEnum.RemovedFromRegister)
{
existingProvider.RemovedTime = DateTime.UtcNow;
}

}
await context.SaveChangesAsync(TeamEnum.DSIT, eventType, loggedInUserEmail);
await transaction.CommitAsync();
genericResponse.Success = true;
}
catch (Exception ex)
{
genericResponse.Success = false;
await transaction.RollbackAsync();
logger.LogError(ex.Message);
}
return genericResponse;
}
#endregion

}
}
}
Loading

0 comments on commit 9efe963

Please sign in to comment.