From 3e2b4d79f019bdf1acc2d7ba099cd60592b9d027 Mon Sep 17 00:00:00 2001 From: Cantte Date: Mon, 12 Apr 2021 18:32:02 -0500 Subject: [PATCH] feat(back-end): Implement new logic of domain event handling The readability of domain event handlers is improved. Refactorizing the different actions in different classes. --- ...erateServiceInvoiceWhenUpdatedWorkOrder.cs | 79 +++++++++ Kaizen/DomainEvents/Handlers/OnPaidInvoice.cs | 55 ------ .../DomainEvents/Handlers/OnSavedActivity.cs | 80 --------- Kaizen/DomainEvents/Handlers/OnSavedPerson.cs | 79 --------- .../Handlers/OnSavedServiceRequest.cs | 32 ---- .../DomainEvents/Handlers/OnUpdatedClient.cs | 65 -------- .../Handlers/OnUpdatedServiceRequest.cs | 157 ------------------ .../Handlers/OnUpdatedWorkOrder.cs | 86 ---------- ...rNewAppliedActivityWhenUpdatedWorkOrder.cs | 31 ++++ .../RegisterNewClientWhenSavedClient.cs | 23 +++ .../ScheduleActivitiesWhenSavedActivity.cs | 26 +++ .../Handlers/SendEmailWhenSavedActivity.cs | 33 ++++ .../Handlers/SendEmailWhenSavedClient.cs | 50 ++++++ .../Handlers/SendEmailWhenUpdatedClient.cs | 62 +++++++ .../SendEmailWhenUpdatedServiceRequest.cs | 82 +++++++++ .../SendNotificationWhenPaidInvoice.cs | 53 ++++++ .../SendNotificationWhenSavedActivity.cs | 33 ++++ .../SendNotificationWhenSavedClient.cs | 27 +++ ...SendNotificationWhenSavedServiceRequest.cs | 33 ++++ ...ndNotificationWhenUpdatedServiceRequest.cs | 103 ++++++++++++ .../UpdateClientStateWhenSavedActivity.cs | 36 ++++ 21 files changed, 671 insertions(+), 554 deletions(-) create mode 100644 Kaizen/DomainEvents/Handlers/GenerateServiceInvoiceWhenUpdatedWorkOrder.cs delete mode 100644 Kaizen/DomainEvents/Handlers/OnPaidInvoice.cs delete mode 100644 Kaizen/DomainEvents/Handlers/OnSavedActivity.cs delete mode 100644 Kaizen/DomainEvents/Handlers/OnSavedPerson.cs delete mode 100644 Kaizen/DomainEvents/Handlers/OnSavedServiceRequest.cs delete mode 100644 Kaizen/DomainEvents/Handlers/OnUpdatedClient.cs delete mode 100644 Kaizen/DomainEvents/Handlers/OnUpdatedServiceRequest.cs delete mode 100644 Kaizen/DomainEvents/Handlers/OnUpdatedWorkOrder.cs create mode 100644 Kaizen/DomainEvents/Handlers/RegisterNewAppliedActivityWhenUpdatedWorkOrder.cs create mode 100644 Kaizen/DomainEvents/Handlers/RegisterNewClientWhenSavedClient.cs create mode 100644 Kaizen/DomainEvents/Handlers/ScheduleActivitiesWhenSavedActivity.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendEmailWhenSavedActivity.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendEmailWhenSavedClient.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendEmailWhenUpdatedClient.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendEmailWhenUpdatedServiceRequest.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendNotificationWhenPaidInvoice.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedActivity.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedClient.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedServiceRequest.cs create mode 100644 Kaizen/DomainEvents/Handlers/SendNotificationWhenUpdatedServiceRequest.cs create mode 100644 Kaizen/DomainEvents/Handlers/UpdateClientStateWhenSavedActivity.cs diff --git a/Kaizen/DomainEvents/Handlers/GenerateServiceInvoiceWhenUpdatedWorkOrder.cs b/Kaizen/DomainEvents/Handlers/GenerateServiceInvoiceWhenUpdatedWorkOrder.cs new file mode 100644 index 00000000..95e4774a --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/GenerateServiceInvoiceWhenUpdatedWorkOrder.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using Kaizen.Domain.Repositories; +using MediatR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class + GenerateServiceInvoiceWhenUpdatedWorkOrder : INotificationHandler> + { + private readonly IServiceInvoicesRepository _serviceInvoicesRepository; + private readonly IActivitiesRepository _activitiesRepository; + private readonly IUnitWork _unitWork; + + public GenerateServiceInvoiceWhenUpdatedWorkOrder(IServiceInvoicesRepository serviceInvoicesRepository, + IActivitiesRepository activitiesRepository, IUnitWork unitWork) + { + _serviceInvoicesRepository = serviceInvoicesRepository; + _activitiesRepository = activitiesRepository; + _unitWork = unitWork; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + WorkOrder workOrder = notification.DomainEvent.WorkOrder; + if (workOrder.WorkOrderState == WorkOrderState.Valid) + { + Activity appliedActivity = await UpdateActivityToApplied(workOrder.ActivityCode); + GenerateInvoice(appliedActivity); + + await _unitWork.SaveAsync(); + } + } + + private async Task UpdateActivityToApplied(int activityCode) + { + Activity activity = await _activitiesRepository.FindByIdAsync(activityCode); + if (activity != null) + { + activity.State = ActivityState.Applied; + _activitiesRepository.Update(activity); + } + + return activity; + } + + private void GenerateInvoice(Activity activity) + { + if (activity is null) + { + return; + } + + List services = activity.ActivitiesServices.Select(s => s.Service).ToList(); + + ServiceInvoice serviceInvoice = new ServiceInvoice + { + Client = activity.Client, + ClientId = activity.ClientId, + PaymentMethod = PaymentMethod.None, + State = InvoiceState.Generated, + IVA = 0.19M, + GenerationDate = DateTime.Now + }; + + services.ForEach(service => { serviceInvoice.AddDetail(service); }); + + serviceInvoice.CalculateTotal(); + + _serviceInvoicesRepository.Insert(serviceInvoice); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/OnPaidInvoice.cs b/Kaizen/DomainEvents/Handlers/OnPaidInvoice.cs deleted file mode 100644 index abb828bb..00000000 --- a/Kaizen/DomainEvents/Handlers/OnPaidInvoice.cs +++ /dev/null @@ -1,55 +0,0 @@ -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.ProductInvoice; -using Kaizen.Models.ServiceInvoice; -using MediatR; -using Microsoft.AspNetCore.SignalR; - -namespace Kaizen.DomainEvents.Handlers -{ - public class OnPaidInvoice - { - public class Handler : INotificationHandler> - { - private readonly IStatisticsRepository _statisticsRepository; - private readonly IHubContext _invoiceHub; - private readonly IMapper _mapper; - - public Handler(IStatisticsRepository statisticsRepository, IHubContext invoiceHub, - IMapper mapper) - { - _statisticsRepository = statisticsRepository; - _invoiceHub = invoiceHub; - _mapper = mapper; - } - - public async Task Handle(DomainEventNotification notification, - CancellationToken cancellationToken) - { - await _statisticsRepository.RegisterProfits(notification.DomainEvent.Invoice.Total); - - switch (notification.DomainEvent.Invoice) - { - case ProductInvoice productInvoice: - { - await _invoiceHub.Clients.Group("Administrator") - .SendAsync("OnPaidProductInvoice", _mapper.Map(productInvoice), - cancellationToken); - break; - } - case ServiceInvoice serviceInvoice: - { - await _invoiceHub.Clients.Group("Administrator").SendAsync("OnPaidServiceInvoice", - _mapper.Map(serviceInvoice), cancellationToken); - break; - } - } - } - } - } -} diff --git a/Kaizen/DomainEvents/Handlers/OnSavedActivity.cs b/Kaizen/DomainEvents/Handlers/OnSavedActivity.cs deleted file mode 100644 index ba7c84c3..00000000 --- a/Kaizen/DomainEvents/Handlers/OnSavedActivity.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using AutoMapper; -using Kaizen.Core.Services; -using Kaizen.Domain.Entities; -using Kaizen.Domain.Events; -using Kaizen.Domain.Repositories; -using Kaizen.Hubs; -using Kaizen.Models.Activity; -using MediatR; -using Microsoft.AspNetCore.SignalR; - -namespace Kaizen.DomainEvents.Handlers -{ - public class OnSavedActivity - { - public class Handler : INotificationHandler> - { - private readonly IHubContext _hubContext; - private readonly IMapper _mapper; - private readonly IMailService _mailService; - private readonly IMailTemplate _mailTemplate; - private readonly IActivitiesRepository _activitiesRepository; - private readonly IClientsRepository _clientsRepository; - private readonly IUnitWork _unitWork; - - public Handler(IHubContext hubContext, IMapper mapper, IMailService mailService, - IMailTemplate mailTemplate, - IActivitiesRepository activitiesRepository, IClientsRepository clientsRepository, IUnitWork unitWork) - { - _hubContext = hubContext; - _mapper = mapper; - _mailService = mailService; - _mailTemplate = mailTemplate; - _activitiesRepository = activitiesRepository; - _clientsRepository = clientsRepository; - _unitWork = unitWork; - } - - public async Task Handle(DomainEventNotification notification, - CancellationToken cancellationToken) - { - Activity activity = notification.DomainEvent.Activity; - - await _activitiesRepository.ScheduleActivities(activity); - await NotifyNewActivityRegister(activity, cancellationToken); - await SendNotificationEmail(activity); - await UpdateClientState(activity); - } - - private async Task NotifyNewActivityRegister(Activity activity, CancellationToken cancellationToken) - { - ActivityViewModel activityModel = _mapper.Map(activity); - await _hubContext.Clients.Groups("Clients").SendAsync("NewActivity", activityModel, cancellationToken); - } - - private async Task SendNotificationEmail(Activity activity) - { - Client client = activity.Client; - - string emailMessage = _mailTemplate.LoadTemplate("NewActivity.html", - $"{client.LastName} {client.FirstName}", activity.Date.ToString("yyyy/MM/dd hh:mm tt")); - - await _mailService.SendEmailAsync(client.User.Email, "Solicitud de servicios", emailMessage, true); - } - - private async Task UpdateClientState(Activity activity) - { - Client client = activity.Client; - client.State = (activity.Periodicity == PeriodicityType.Casual) - ? ClientState.Casual - : ClientState.Active; - - _clientsRepository.Update(client); - - await _unitWork.SaveAsync(); - } - } - } -} diff --git a/Kaizen/DomainEvents/Handlers/OnSavedPerson.cs b/Kaizen/DomainEvents/Handlers/OnSavedPerson.cs deleted file mode 100644 index 8dd1728f..00000000 --- a/Kaizen/DomainEvents/Handlers/OnSavedPerson.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using Kaizen.Core.Services; -using Kaizen.Domain.Entities; -using Kaizen.Domain.Events; -using Kaizen.Domain.Repositories; -using Kaizen.Extensions; -using Kaizen.Hubs; -using Kaizen.Middleware; -using MediatR; -using Microsoft.AspNetCore.SignalR; - -namespace Kaizen.DomainEvents.Handlers -{ - public class OnSavedPerson - { - public class Handler : INotificationHandler> - { - private readonly IApplicationUserRepository _applicationUserRepository; - private readonly IMailService _mailService; - private readonly IHubContext _clientHub; - private readonly IMailTemplate _mailTemplate; - private readonly IStatisticsRepository _statisticsRepository; - - public Handler(IMailService mailService, IHubContext clientHub, IMailTemplate mailTemplate, - IApplicationUserRepository applicationUserRepository, - IStatisticsRepository statisticsRepository) - { - _mailService = mailService; - _clientHub = clientHub; - _mailTemplate = mailTemplate; - _statisticsRepository = statisticsRepository; - _applicationUserRepository = applicationUserRepository; - } - - public async Task Handle(DomainEventNotification notification, - CancellationToken cancellationToken) - { - Client savedClient = notification.DomainEvent.Client; - - await SendConfirmationEmail(savedClient); - await NotifyNewClientRegister(cancellationToken); - await RegisterNewClient(); - } - - private async Task SendConfirmationEmail(Client client) - { - string emailConfirmationToken = - await _applicationUserRepository.GenerateEmailConfirmationTokenAsync(client.User); - UriBuilder uriBuilder = new UriBuilder(KaizenHttpContext.BaseUrl) - { - Path = "user/ConfirmEmail", - Query = $"token={emailConfirmationToken.Base64ForUrlEncode()}&email={client.User.Email}" - }; - string emailConfirmationLink = uriBuilder.ToString(); - - string emailMessage = _mailTemplate.LoadTemplate("NewClient.html", - $"{client.FirstName} {client.LastName}", - $"{client.TradeName}", $"{client.ClientAddress.City}", - $"{client.ClientAddress.Neighborhood}", $"{client.ClientAddress.Street}", - $"{emailConfirmationLink}"); - - await _mailService.SendEmailAsync(client.User.Email, "Cliente Registrado", emailMessage, true); - } - - private async Task NotifyNewClientRegister(CancellationToken cancellationToken) - { - await _clientHub.Clients.Groups("Administrator", "OfficeEmployee") - .SendAsync("NewPersonRequest", cancellationToken: cancellationToken); - } - - private async Task RegisterNewClient() - { - await _statisticsRepository.RegisterNewClientRegister(); - } - } - } -} diff --git a/Kaizen/DomainEvents/Handlers/OnSavedServiceRequest.cs b/Kaizen/DomainEvents/Handlers/OnSavedServiceRequest.cs deleted file mode 100644 index cf05bc5a..00000000 --- a/Kaizen/DomainEvents/Handlers/OnSavedServiceRequest.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using AutoMapper; -using Kaizen.Domain.Events; -using Kaizen.Hubs; -using Kaizen.Models.ServiceRequest; -using MediatR; -using Microsoft.AspNetCore.SignalR; - -namespace Kaizen.DomainEvents.Handlers -{ - public class OnSavedServiceRequest - { - public class Handler : INotificationHandler> - { - private readonly IHubContext _hubContext; - private readonly IMapper _mapper; - - public Handler(IHubContext hubContext, IMapper mapper) - { - _hubContext = hubContext; - _mapper = mapper; - } - - public async Task Handle(DomainEventNotification notification, CancellationToken cancellationToken) - { - ServiceRequestViewModel serviceRequestModel = _mapper.Map(notification.DomainEvent.ServiceRequest); - await _hubContext.Clients.Groups("Administrator", "OfficeEmployee").SendAsync("NewServiceRequest", serviceRequestModel, cancellationToken: cancellationToken); - } - } - } -} diff --git a/Kaizen/DomainEvents/Handlers/OnUpdatedClient.cs b/Kaizen/DomainEvents/Handlers/OnUpdatedClient.cs deleted file mode 100644 index 74ca03bd..00000000 --- a/Kaizen/DomainEvents/Handlers/OnUpdatedClient.cs +++ /dev/null @@ -1,65 +0,0 @@ -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 OnUpdatedClient - { - public class Handler : INotificationHandler> - { - private readonly INotificationsRepository _notificationsRepository; - private readonly IUnitWork _unitWork; - private readonly IHubContext _notificationsHub; - private readonly IMapper _mapper; - - public Handler(INotificationsRepository notificationsRepository, IUnitWork unitWork, - IHubContext hubContext, IMapper mapper) - { - _notificationsRepository = notificationsRepository; - _unitWork = unitWork; - _notificationsHub = hubContext; - _mapper = mapper; - } - - public async Task Handle(DomainEventNotification notification, - CancellationToken cancellationToken) - { - var client = notification.DomainEvent.Client; - if (client.State != ClientState.Acceptep && client.State != ClientState.Rejected) - { - return; - } - - var message = client.State switch - { - ClientState.Acceptep => "Hemos aceptado tu solicitud de ser nuestro cliente.", - ClientState.Rejected => "Desafortunadamente hemos rechazado tu solicitud de ser nuestro cliente.", - _ => string.Empty - }; - var clientNotification = new Notification - { - Title = "Respuesta de solicitud de cliente", - Message = message, - Icon = "question_answer", - State = NotificationState.Pending, - UserId = client.UserId - }; - - _notificationsRepository.Insert(clientNotification); - await _unitWork.SaveAsync(); - - var notificationViewModel = _mapper.Map(clientNotification); - await _notificationsHub.Clients.User(client.UserId).SendAsync("OnNewNotification", - notificationViewModel, cancellationToken); - } - } - } -} diff --git a/Kaizen/DomainEvents/Handlers/OnUpdatedServiceRequest.cs b/Kaizen/DomainEvents/Handlers/OnUpdatedServiceRequest.cs deleted file mode 100644 index cc26d35b..00000000 --- a/Kaizen/DomainEvents/Handlers/OnUpdatedServiceRequest.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using AutoMapper; -using Kaizen.Core.Services; -using Kaizen.Domain.Entities; -using Kaizen.Domain.Events; -using Kaizen.Domain.Repositories; -using Kaizen.Hubs; -using Kaizen.Middleware; -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; - private readonly IMailTemplate _mailTemplate; - private readonly IMailService _mailService; - - public Handler(IHubContext notificationsHub, IClientsRepository clientsRepository, - INotificationsRepository notificationsRepository, IUnitWork unitWork, IMapper mapper, - IMailTemplate mailTemplate, IMailService mailService) - { - _notificationsHub = notificationsHub; - _clientsRepository = clientsRepository; - _notificationsRepository = notificationsRepository; - _unitWork = unitWork; - _mapper = mapper; - _mailTemplate = mailTemplate; - _mailService = mailService; - } - - 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, client.User); - if (clientNotification is null) - { - return; - } - - await SendServiceRequestNotification(clientNotification, client.User.Id, cancellationToken); - await SendServiceRequestResponseEmail(serviceRequest, client); - } - - private async Task SendServiceRequestResponseEmail(ServiceRequest serviceRequest, Client client) - { - string responseMessage = serviceRequest.State switch - { - ServiceRequestState.Accepted => - "Hemos aceptado tu solicitud de servicio y agendamos las actividades a aplicar.", - ServiceRequestState.Rejected => "Desafortunadamente hemos rechazado tu solicitud de servicio.", - ServiceRequestState.PendingSuggestedDate => - "Te hemos sugerido una nueva fecha de aplicación de nuestros servicios.", - _ => "Tu solicitud aún está pendiente" - }; - - var responseUrl = new UriBuilder(KaizenHttpContext.BaseUrl) - { - Path = serviceRequest.State switch - { - ServiceRequestState.Accepted => "/activity_schedule/client_schedule", - ServiceRequestState.Rejected => "/service_requests/register", - ServiceRequestState.PendingSuggestedDate => "/service_requests/new_date", - _ => $"/service_requests/{serviceRequest.Code}" - } - }; - - var responseButtonMessage = serviceRequest.State switch - { - ServiceRequestState.Accepted => "Ver mi calendario de actividades", - ServiceRequestState.Rejected => "Intentar hacer otra solicitud", - ServiceRequestState.PendingSuggestedDate => "Ver fecha sugerida", - _ => "Ver solicitud" - }; - - string emailMessage = _mailTemplate.LoadTemplate("ServiceRequestResponse.html", - $"{client.FirstName} {client.LastName}", - responseMessage, - responseUrl.ToString(), - responseButtonMessage); - - await _mailService.SendEmailAsync( - client.User.Email, - "Respuesta de solicitud de servicio", - emailMessage, - true); - } - - private async Task SaveServiceRequestNotification(ServiceRequest serviceRequest, - ApplicationUser user) - { - var message = serviceRequest.State 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; - } - - var serviceRequestUrl = serviceRequest.State == ServiceRequestState.PendingSuggestedDate - ? "/service_requests/new_date" - : $"/service_requests/{serviceRequest.Code}"; - - var notification = new Notification - { - Title = "Respuesta de solicitud de servicio", - Message = message, - Icon = "question_answer", - State = NotificationState.Pending, - Url = serviceRequestUrl, - UserId = user.Id - }; - - _notificationsRepository.Insert(notification); - await _unitWork.SaveAsync(); - - return notification; - } - - private async Task SendServiceRequestNotification(Notification clientNotification, string userid, - CancellationToken cancellationToken) - { - var notificationViewModel = _mapper.Map(clientNotification); - await _notificationsHub.Clients.User(userid).SendAsync("OnNewNotification", - notificationViewModel, cancellationToken); - } - } - } -} diff --git a/Kaizen/DomainEvents/Handlers/OnUpdatedWorkOrder.cs b/Kaizen/DomainEvents/Handlers/OnUpdatedWorkOrder.cs deleted file mode 100644 index e2953638..00000000 --- a/Kaizen/DomainEvents/Handlers/OnUpdatedWorkOrder.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Kaizen.Domain.Entities; -using Kaizen.Domain.Events; -using Kaizen.Domain.Repositories; -using MediatR; - -namespace Kaizen.DomainEvents.Handlers -{ - public class OnUpdatedWorkOrder - { - public class Handler : INotificationHandler> - { - private readonly IUnitWork _unitWork; - private readonly IServiceInvoicesRepository _serviceInvoicesRepository; - private readonly IActivitiesRepository _activitiesRepository; - private readonly IStatisticsRepository _statisticsRepository; - - public Handler(IUnitWork unitWork, IServiceInvoicesRepository serviceInvoicesRepository, IStatisticsRepository statisticsRepository, IActivitiesRepository activitiesRepository) - { - _unitWork = unitWork; - _serviceInvoicesRepository = serviceInvoicesRepository; - _statisticsRepository = statisticsRepository; - _activitiesRepository = activitiesRepository; - } - - public async Task Handle(DomainEventNotification notification, CancellationToken cancellationToken) - { - WorkOrder workOrder = notification.DomainEvent.WorkOrder; - - if (workOrder.WorkOrderState == WorkOrderState.Valid) - { - Activity appliedActivity = await UpdateActivityToApplied(workOrder.ActivityCode); - GenerateInvoice(appliedActivity); - - await _statisticsRepository.RegisterNewAppliedActivity(); - await _unitWork.SaveAsync(); - } - } - - private async Task UpdateActivityToApplied(int activityCode) - { - Activity activity = await _activitiesRepository.FindByIdAsync(activityCode); - if (activity != null) - { - activity.State = ActivityState.Applied; - _activitiesRepository.Update(activity); - } - - return activity; - } - - private void GenerateInvoice(Activity activity) - { - if (activity is null) - { - return; - } - - List services = activity.ActivitiesServices.Select(s => s.Service).ToList(); - - ServiceInvoice serviceInvoice = new ServiceInvoice - { - Client = activity.Client, - ClientId = activity.ClientId, - PaymentMethod = PaymentMethod.None, - State = InvoiceState.Generated, - IVA = 0.19M, - GenerationDate = DateTime.Now - }; - - services.ForEach(service => - { - serviceInvoice.AddDetail(service); - }); - - serviceInvoice.CalculateTotal(); - - _serviceInvoicesRepository.Insert(serviceInvoice); - } - } - } -} diff --git a/Kaizen/DomainEvents/Handlers/RegisterNewAppliedActivityWhenUpdatedWorkOrder.cs b/Kaizen/DomainEvents/Handlers/RegisterNewAppliedActivityWhenUpdatedWorkOrder.cs new file mode 100644 index 00000000..939fffd9 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/RegisterNewAppliedActivityWhenUpdatedWorkOrder.cs @@ -0,0 +1,31 @@ +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using Kaizen.Domain.Repositories; +using MediatR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class + RegisterNewAppliedActivityWhenUpdatedWorkOrder : INotificationHandler> + { + private readonly IStatisticsRepository _statisticsRepository; + + public RegisterNewAppliedActivityWhenUpdatedWorkOrder(IStatisticsRepository statisticsRepository) + { + _statisticsRepository = statisticsRepository; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + WorkOrder workOrder = notification.DomainEvent.WorkOrder; + + if (workOrder.WorkOrderState == WorkOrderState.Valid) + { + await _statisticsRepository.RegisterNewAppliedActivity(); + } + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/RegisterNewClientWhenSavedClient.cs b/Kaizen/DomainEvents/Handlers/RegisterNewClientWhenSavedClient.cs new file mode 100644 index 00000000..409cd275 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/RegisterNewClientWhenSavedClient.cs @@ -0,0 +1,23 @@ +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Domain.Events; +using Kaizen.Domain.Repositories; +using MediatR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class RegisterNewClientWhenSavedClient : INotificationHandler> + { + private readonly IStatisticsRepository _statisticsRepository; + + public RegisterNewClientWhenSavedClient(IStatisticsRepository statisticsRepository) + { + _statisticsRepository = statisticsRepository; + } + + public async Task Handle(DomainEventNotification notification, CancellationToken cancellationToken) + { + await _statisticsRepository.RegisterNewClientRegister(); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/ScheduleActivitiesWhenSavedActivity.cs b/Kaizen/DomainEvents/Handlers/ScheduleActivitiesWhenSavedActivity.cs new file mode 100644 index 00000000..0f9a8b3f --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/ScheduleActivitiesWhenSavedActivity.cs @@ -0,0 +1,26 @@ +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using Kaizen.Domain.Repositories; +using MediatR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class ScheduleActivitiesWhenSavedActivity : INotificationHandler> + { + private readonly IActivitiesRepository _activitiesRepository; + + public ScheduleActivitiesWhenSavedActivity(IActivitiesRepository activitiesRepository) + { + _activitiesRepository = activitiesRepository; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + Activity activity = notification.DomainEvent.Activity; + await _activitiesRepository.ScheduleActivities(activity); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendEmailWhenSavedActivity.cs b/Kaizen/DomainEvents/Handlers/SendEmailWhenSavedActivity.cs new file mode 100644 index 00000000..89510e14 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendEmailWhenSavedActivity.cs @@ -0,0 +1,33 @@ +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Core.Services; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using MediatR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class SendEmailWhenSavedActivity : INotificationHandler> + { + private readonly IMailService _mailService; + private readonly IMailTemplate _mailTemplate; + + public SendEmailWhenSavedActivity(IMailService mailService, IMailTemplate mailTemplate) + { + _mailService = mailService; + _mailTemplate = mailTemplate; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + Activity activity = notification.DomainEvent.Activity; + Client client = activity.Client; + + string emailMessage = _mailTemplate.LoadTemplate("NewActivity.html", + $"{client.LastName} {client.FirstName}", activity.Date.ToString("yyyy/MM/dd hh:mm tt")); + + await _mailService.SendEmailAsync(client.User.Email, "Solicitud de servicios", emailMessage, true); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendEmailWhenSavedClient.cs b/Kaizen/DomainEvents/Handlers/SendEmailWhenSavedClient.cs new file mode 100644 index 00000000..2cc8a091 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendEmailWhenSavedClient.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Core.Services; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using Kaizen.Domain.Repositories; +using Kaizen.Extensions; +using Kaizen.Middleware; +using MediatR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class SendEmailWhenSavedClient : INotificationHandler> + { + private readonly IApplicationUserRepository _applicationUserRepository; + private readonly IMailTemplate _mailTemplate; + private readonly IMailService _mailService; + + public SendEmailWhenSavedClient(IApplicationUserRepository applicationUserRepository, + IMailTemplate mailTemplate, IMailService mailService) + { + _applicationUserRepository = applicationUserRepository; + _mailTemplate = mailTemplate; + _mailService = mailService; + } + + public async Task Handle(DomainEventNotification notification, CancellationToken cancellationToken) + { + Client client = notification.DomainEvent.Client; + + string emailConfirmationToken = + await _applicationUserRepository.GenerateEmailConfirmationTokenAsync(client.User); + UriBuilder uriBuilder = new UriBuilder(KaizenHttpContext.BaseUrl) + { + Path = "user/ConfirmEmail", + Query = $"token={emailConfirmationToken.Base64ForUrlEncode()}&email={client.User.Email}" + }; + string emailConfirmationLink = uriBuilder.ToString(); + + string emailMessage = _mailTemplate.LoadTemplate("NewClient.html", + $"{client.FirstName} {client.LastName}", + $"{client.TradeName}", $"{client.ClientAddress.City}", + $"{client.ClientAddress.Neighborhood}", $"{client.ClientAddress.Street}", + $"{emailConfirmationLink}"); + + await _mailService.SendEmailAsync(client.User.Email, "Cliente Registrado", emailMessage, true); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendEmailWhenUpdatedClient.cs b/Kaizen/DomainEvents/Handlers/SendEmailWhenUpdatedClient.cs new file mode 100644 index 00000000..770f0d10 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendEmailWhenUpdatedClient.cs @@ -0,0 +1,62 @@ +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 SendEmailWhenUpdatedClient : INotificationHandler> + { + private readonly INotificationsRepository _notificationsRepository; + private readonly IUnitWork _unitWork; + private readonly IHubContext _notificationsHub; + private readonly IMapper _mapper; + + public SendEmailWhenUpdatedClient(INotificationsRepository notificationsRepository, IUnitWork unitWork, + IHubContext hubContext, IMapper mapper) + { + _notificationsRepository = notificationsRepository; + _unitWork = unitWork; + _notificationsHub = hubContext; + _mapper = mapper; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + var client = notification.DomainEvent.Client; + if (client.State != ClientState.Acceptep && client.State != ClientState.Rejected) + { + return; + } + + var message = client.State switch + { + ClientState.Acceptep => "Hemos aceptado tu solicitud de ser nuestro cliente.", + ClientState.Rejected => "Desafortunadamente hemos rechazado tu solicitud de ser nuestro cliente.", + _ => string.Empty + }; + var clientNotification = new Notification + { + Title = "Respuesta de solicitud de cliente", + Message = message, + Icon = "question_answer", + State = NotificationState.Pending, + UserId = client.UserId + }; + + _notificationsRepository.Insert(clientNotification); + await _unitWork.SaveAsync(); + + var notificationViewModel = _mapper.Map(clientNotification); + await _notificationsHub.Clients.User(client.UserId).SendAsync("OnNewNotification", + notificationViewModel, cancellationToken); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendEmailWhenUpdatedServiceRequest.cs b/Kaizen/DomainEvents/Handlers/SendEmailWhenUpdatedServiceRequest.cs new file mode 100644 index 00000000..c0f13857 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendEmailWhenUpdatedServiceRequest.cs @@ -0,0 +1,82 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Core.Services; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using Kaizen.Domain.Repositories; +using Kaizen.Middleware; +using MediatR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class + SendEmailWhenUpdatedServiceRequest : INotificationHandler> + { + private readonly IClientsRepository _clientsRepository; + private readonly IMailTemplate _mailTemplate; + private readonly IMailService _mailService; + + public SendEmailWhenUpdatedServiceRequest(IClientsRepository clientsRepository, IMailTemplate mailTemplate, + IMailService mailService) + { + _clientsRepository = clientsRepository; + _mailTemplate = mailTemplate; + _mailService = mailService; + } + + 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); + + string responseMessage = serviceRequest.State switch + { + ServiceRequestState.Accepted => + "Hemos aceptado tu solicitud de servicio y agendamos las actividades a aplicar.", + ServiceRequestState.Rejected => "Desafortunadamente hemos rechazado tu solicitud de servicio.", + ServiceRequestState.PendingSuggestedDate => + "Te hemos sugerido una nueva fecha de aplicación de nuestros servicios.", + _ => "Tu solicitud aún está pendiente" + }; + + var responseUrl = new UriBuilder(KaizenHttpContext.BaseUrl) + { + Path = serviceRequest.State switch + { + ServiceRequestState.Accepted => "/activity_schedule/client_schedule", + ServiceRequestState.Rejected => "/service_requests/register", + ServiceRequestState.PendingSuggestedDate => "/service_requests/new_date", + _ => $"/service_requests/{serviceRequest.Code}" + } + }; + + var responseButtonMessage = serviceRequest.State switch + { + ServiceRequestState.Accepted => "Ver mi calendario de actividades", + ServiceRequestState.Rejected => "Intentar hacer otra solicitud", + ServiceRequestState.PendingSuggestedDate => "Ver fecha sugerida", + _ => "Ver solicitud" + }; + + string emailMessage = _mailTemplate.LoadTemplate("ServiceRequestResponse.html", + $"{client.FirstName} {client.LastName}", + responseMessage, + responseUrl.ToString(), + responseButtonMessage); + + await _mailService.SendEmailAsync( + client.User.Email, + "Respuesta de solicitud de servicio", + emailMessage, + true); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendNotificationWhenPaidInvoice.cs b/Kaizen/DomainEvents/Handlers/SendNotificationWhenPaidInvoice.cs new file mode 100644 index 00000000..16a66066 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendNotificationWhenPaidInvoice.cs @@ -0,0 +1,53 @@ +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.ProductInvoice; +using Kaizen.Models.ServiceInvoice; +using MediatR; +using Microsoft.AspNetCore.SignalR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class SendNotificationWhenPaidInvoice : INotificationHandler> + { + private readonly IStatisticsRepository _statisticsRepository; + private readonly IHubContext _invoiceHub; + private readonly IMapper _mapper; + + public SendNotificationWhenPaidInvoice(IStatisticsRepository statisticsRepository, + IHubContext invoiceHub, + IMapper mapper) + { + _statisticsRepository = statisticsRepository; + _invoiceHub = invoiceHub; + _mapper = mapper; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + await _statisticsRepository.RegisterProfits(notification.DomainEvent.Invoice.Total); + + switch (notification.DomainEvent.Invoice) + { + case ProductInvoice productInvoice: + { + await _invoiceHub.Clients.Group("Administrator") + .SendAsync("OnPaidProductInvoice", _mapper.Map(productInvoice), + cancellationToken); + break; + } + case ServiceInvoice serviceInvoice: + { + await _invoiceHub.Clients.Group("Administrator").SendAsync("OnPaidServiceInvoice", + _mapper.Map(serviceInvoice), cancellationToken); + break; + } + } + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedActivity.cs b/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedActivity.cs new file mode 100644 index 00000000..6f160e1b --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedActivity.cs @@ -0,0 +1,33 @@ +using System.Threading; +using System.Threading.Tasks; +using AutoMapper; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using Kaizen.Hubs; +using Kaizen.Models.Activity; +using MediatR; +using Microsoft.AspNetCore.SignalR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class SendNotificationWhenSavedActivity : INotificationHandler> + { + private readonly IHubContext _hubContext; + private readonly IMapper _mapper; + + public SendNotificationWhenSavedActivity(IHubContext hubContext, IMapper mapper) + { + _hubContext = hubContext; + _mapper = mapper; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + Activity activity = notification.DomainEvent.Activity; + ActivityViewModel activityModel = _mapper.Map(activity); + + await _hubContext.Clients.Groups("Clients").SendAsync("NewActivity", activityModel, cancellationToken); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedClient.cs b/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedClient.cs new file mode 100644 index 00000000..a3c7b039 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedClient.cs @@ -0,0 +1,27 @@ +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Domain.Events; +using Kaizen.Hubs; +using MediatR; +using Microsoft.AspNetCore.SignalR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class SendNotificationWhenSavedClient : INotificationHandler> + { + private readonly IHubContext _clientHub; + + + public SendNotificationWhenSavedClient(IHubContext clientHub) + { + _clientHub = clientHub; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + await _clientHub.Clients.Groups("Administrator", "OfficeEmployee") + .SendAsync("NewPersonRequest", cancellationToken); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedServiceRequest.cs b/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedServiceRequest.cs new file mode 100644 index 00000000..77c641fd --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendNotificationWhenSavedServiceRequest.cs @@ -0,0 +1,33 @@ +using System.Threading; +using System.Threading.Tasks; +using AutoMapper; +using Kaizen.Domain.Events; +using Kaizen.Hubs; +using Kaizen.Models.ServiceRequest; +using MediatR; +using Microsoft.AspNetCore.SignalR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class + SendNotificationWhenSavedServiceRequest : INotificationHandler> + { + private readonly IHubContext _hubContext; + private readonly IMapper _mapper; + + public SendNotificationWhenSavedServiceRequest(IHubContext hubContext, IMapper mapper) + { + _hubContext = hubContext; + _mapper = mapper; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + ServiceRequestViewModel serviceRequestModel = + _mapper.Map(notification.DomainEvent.ServiceRequest); + await _hubContext.Clients.Groups("Administrator", "OfficeEmployee") + .SendAsync("NewServiceRequest", serviceRequestModel, cancellationToken); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/SendNotificationWhenUpdatedServiceRequest.cs b/Kaizen/DomainEvents/Handlers/SendNotificationWhenUpdatedServiceRequest.cs new file mode 100644 index 00000000..9f3f98a7 --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/SendNotificationWhenUpdatedServiceRequest.cs @@ -0,0 +1,103 @@ +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 + SendNotificationWhenUpdatedServiceRequest : INotificationHandler> + { + private readonly IHubContext _notificationsHub; + private readonly IMapper _mapper; + private readonly IClientsRepository _clientsRepository; + private readonly INotificationsRepository _notificationsRepository; + private readonly IUnitWork _unitWork; + + public SendNotificationWhenUpdatedServiceRequest(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, client.User); + if (clientNotification is null) + { + return; + } + + await SendServiceRequestNotification(clientNotification, client.User.Id, cancellationToken); + } + + private async Task SaveServiceRequestNotification(ServiceRequest serviceRequest, + ApplicationUser user) + { + var message = serviceRequest.State 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; + } + + var serviceRequestUrl = serviceRequest.State == ServiceRequestState.PendingSuggestedDate + ? "/service_requests/new_date" + : $"/service_requests/{serviceRequest.Code}"; + + var notification = new Notification + { + Title = "Respuesta de solicitud de servicio", + Message = message, + Icon = "question_answer", + State = NotificationState.Pending, + Url = serviceRequestUrl, + UserId = user.Id + }; + + _notificationsRepository.Insert(notification); + await _unitWork.SaveAsync(); + + return notification; + } + + private async Task SendServiceRequestNotification(Notification clientNotification, string userid, + CancellationToken cancellationToken) + { + var notificationViewModel = _mapper.Map(clientNotification); + await _notificationsHub.Clients.User(userid).SendAsync("OnNewNotification", + notificationViewModel, cancellationToken); + } + } +} diff --git a/Kaizen/DomainEvents/Handlers/UpdateClientStateWhenSavedActivity.cs b/Kaizen/DomainEvents/Handlers/UpdateClientStateWhenSavedActivity.cs new file mode 100644 index 00000000..03f7694d --- /dev/null +++ b/Kaizen/DomainEvents/Handlers/UpdateClientStateWhenSavedActivity.cs @@ -0,0 +1,36 @@ +using System.Threading; +using System.Threading.Tasks; +using Kaizen.Domain.Entities; +using Kaizen.Domain.Events; +using Kaizen.Domain.Repositories; +using MediatR; + +namespace Kaizen.DomainEvents.Handlers +{ + public class UpdateClientStateWhenSavedActivity : INotificationHandler> + { + private readonly IClientsRepository _clientsRepository; + private readonly IUnitWork _unitWork; + + public UpdateClientStateWhenSavedActivity(IClientsRepository clientsRepository, IUnitWork unitWork) + { + _clientsRepository = clientsRepository; + _unitWork = unitWork; + } + + public async Task Handle(DomainEventNotification notification, + CancellationToken cancellationToken) + { + Activity activity = notification.DomainEvent.Activity; + Client client = activity.Client; + + client.State = (activity.Periodicity == PeriodicityType.Casual) + ? ClientState.Casual + : ClientState.Active; + + _clientsRepository.Update(client); + + await _unitWork.SaveAsync(); + } + } +}