diff --git a/Domain/Events/UpdatedServiceRequest.cs b/Domain/Events/UpdatedServiceRequest.cs new file mode 100644 index 00000000..a9073739 --- /dev/null +++ b/Domain/Events/UpdatedServiceRequest.cs @@ -0,0 +1,15 @@ +using Kaizen.Core.Domain; +using Kaizen.Domain.Entities; + +namespace Kaizen.Domain.Events +{ + public class UpdatedServiceRequest : IDomainEvent + { + public UpdatedServiceRequest(ServiceRequest serviceRequest) + { + ServiceRequest = serviceRequest; + } + + public ServiceRequest ServiceRequest { get; } + } +} diff --git a/Kaizen/Controllers/ServiceRequestsController.cs b/Kaizen/Controllers/ServiceRequestsController.cs index 6c2694a4..a7945667 100644 --- a/Kaizen/Controllers/ServiceRequestsController.cs +++ b/Kaizen/Controllers/ServiceRequestsController.cs @@ -70,6 +70,7 @@ public async Task> PutServiceRequest(int i } _mapper.Map(serviceRequestModel, serviceRequest); + serviceRequest.PublishEvent(new UpdatedServiceRequest(serviceRequest)); _serviceRequestsRepository.Update(serviceRequest); try diff --git a/Kaizen/DomainEvents/Handlers/OnUpdatedServiceRequest.cs b/Kaizen/DomainEvents/Handlers/OnUpdatedServiceRequest.cs new file mode 100644 index 00000000..dff5fb51 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/OnUpdatedServiceRequest.cs @@ -0,0 +1,99 @@ +using System.Threading; +using System.Threading.Tasks; +using AutoMapper; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using Kaizen.Domain.Repositories; +using Kaizen.Hubs; +using Kaizen.Models.Notification; +using MediatR; +using Microsoft.AspNetCore.SignalR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class OnUpdatedServiceRequest + { + public class Handler : INotificationHandler> + { + private readonly IHubContext _notificationsHub; + private readonly IMapper _mapper; + private readonly IClientsRepository _clientsRepository; + private readonly INotificationsRepository _notificationsRepository; + private readonly IUnitWork _unitWork; + + public Handler(IHubContext notificationsHub, IClientsRepository clientsRepository, + INotificationsRepository notificationsRepository, IUnitWork unitWork, IMapper mapper) + { + _notificationsHub = notificationsHub; + _clientsRepository = clientsRepository; + _notificationsRepository = notificationsRepository; + _unitWork = unitWork; + _mapper = mapper; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + var serviceRequest = notification.DomainEvent.ServiceRequest; + if (serviceRequest.State == ServiceRequestState.Pending) + { + return; + } + + var client = + await _clientsRepository.GetClientWithUser(serviceRequest.ClientId); + + var clientNotification = await SaveServiceRequestNotification(serviceRequest.State, client.User); + if (clientNotification is null) + { + return; + } + + await SendServiceRequestNotification(clientNotification, client.User.UserName, cancellationToken); + } + + private async Task SaveServiceRequestNotification(ServiceRequestState serviceRequestState, + ApplicationUser user) + { + var message = serviceRequestState switch + { + ServiceRequestState.Accepted => + "Hemos aceptado tu solicitud de servicio y agendamos las actividades a aplicar. " + + "Consulta tu calendario.", + ServiceRequestState.Rejected => "Desafortunadamente hemos rechazado tu solicitud de servicio.", + ServiceRequestState.PendingSuggestedDate => + "Te hemos sugerido una nueva fecha de aplicaciĆ³n de nuestros servicios." + + "Puedes aceptarla o sugerirnos otra.", + _ => string.Empty + }; + + if (string.IsNullOrEmpty(message)) + { + return null; + } + + Notification notification = new Notification + { + Title = "Respuesta de solicitud de servicio", + Message = message, + Icon = "question_answer", + State = NotificationState.Pending, + UserId = user.Id + }; + + _notificationsRepository.Insert(notification); + await _unitWork.SaveAsync(); + + return notification; + } + + private async Task SendServiceRequestNotification(Notification clientNotification, string username, + CancellationToken cancellationToken) + { + var notificationViewModel = _mapper.Map(clientNotification); + await _notificationsHub.Clients.User(username).SendAsync("OnNewNotification", + notificationViewModel, cancellationToken); + } + } + } +}