using AutobusApi.Application.Common.Exceptions; using AutobusApi.Application.Common.Interfaces; using AutobusApi.Domain.Entities; using AutobusApi.Domain.Enums; using MediatR; using Microsoft.EntityFrameworkCore; namespace AutobusApi.Application.TicketGroups.Commands.UpdateTicketGroup; public class UpdateTicketGroupCommandHandler : IRequestHandler { private readonly IApplicationDbContext _dbContext; public UpdateTicketGroupCommandHandler(IApplicationDbContext dbContext) { _dbContext = dbContext; } public async Task Handle( UpdateTicketGroupCommand request, CancellationToken cancellationToken) { var ticketGroup = await _dbContext.TicketGroups .Include(tg => tg.Tickets) .SingleAsync(tg => tg.Id == request.Id, cancellationToken); if (ticketGroup == null) { throw new NotFoundException(); } ticketGroup.BuyerFirstName = request.BuyerFirstName; ticketGroup.BuyerLastName = request.BuyerLastName; ticketGroup.BuyerPhoneNumber = request.BuyerPhoneNumber; ticketGroup.BuyerEmailAddress = request.BuyerEmail; ticketGroup.PassengerFirstName = request.PassengerFirstName; ticketGroup.PassengerLastName = request.PassengerLastName; ticketGroup.PassengerPatronymic = request.PassengerPatronymic; ticketGroup.PassengerSex = Enum.Parse(request.PassengerSex); ticketGroup.PassengerBirthDate = request.PassengerBirthDate; ticketGroup.TicketDocument.Type = Enum.Parse(request.DocumentType); ticketGroup.TicketDocument.Information = request.DocumentInformation; var compaper = new TicketEqualityComparer(); var ticketsToBeRemoved = ticketGroup.Tickets .ExceptBy(request.Tickets.Select( t => new Ticket { Id = t.Id ?? 0, DepartureAddressId = t.DepartureAddressId, ArrivalAddressId = t.ArrivalAddressId, VehicleEnrollmentId = t.VehicleEnrollmentId }), t => new Ticket { Id = t.Id, DepartureAddressId = t.DepartureAddressId, ArrivalAddressId = t.ArrivalAddressId, VehicleEnrollmentId = t.VehicleEnrollmentId }, compaper ).ToList(); var remainingTickets = ticketGroup.Tickets .ExceptBy(ticketsToBeRemoved.Select( ttbr => new Ticket { Id = ttbr.Id, DepartureAddressId = ttbr.DepartureAddressId, ArrivalAddressId = ttbr.ArrivalAddressId, VehicleEnrollmentId = ttbr.VehicleEnrollmentId }), t => new Ticket { Id = t.Id, DepartureAddressId = t.DepartureAddressId, ArrivalAddressId = t.ArrivalAddressId, VehicleEnrollmentId = t.VehicleEnrollmentId }, compaper ).ToList(); var newTickets = remainingTickets .UnionBy(request.Tickets.Select( t => new Ticket { Id = t.Id ?? 0, DepartureAddressId = t.DepartureAddressId, ArrivalAddressId = t.ArrivalAddressId, VehicleEnrollmentId = t.VehicleEnrollmentId }), rt => new Ticket { Id = rt.Id, DepartureAddressId = rt.DepartureAddressId, ArrivalAddressId = rt.ArrivalAddressId, VehicleEnrollmentId = rt.VehicleEnrollmentId }, compaper ).ToList(); ticketGroup.Tickets = newTickets.ToList(); await _dbContext.SaveChangesAsync(cancellationToken); } private class TicketEqualityComparer : IEqualityComparer { public bool Equals(Ticket? x, Ticket? y) { return x?.Id == y?.Id && x?.DepartureAddressId == y?.DepartureAddressId && x?.ArrivalAddressId == y?.ArrivalAddressId && x?.VehicleEnrollmentId == y?.VehicleEnrollmentId; } public int GetHashCode(Ticket obj) { return obj.ArrivalAddressId.GetHashCode() + obj.DepartureAddressId.GetHashCode() + obj.VehicleEnrollmentId.GetHashCode(); } } }