public async Task <TestingPersonnelInvitationConfirmedShiftsDto> ConfirmInvitationAsync(TestingPersonnelInvitationConfirmDto confirmDto)
        {
            if (confirmDto == null)
            {
                throw new ArgumentNullException(nameof(confirmDto));
            }

            var testingPersonnelAndInvitationData = await _invitationConfirmationTokensRepository
                                                    .GetTestingPersonnelAndInvitationByConfirmationTokenAsync(confirmDto.Token)
                                                    .ConfigureAwait(false);

            if (testingPersonnelAndInvitationData == null)
            {
                ValidationDictionary
                .AddModelError("The token is not valid", $"The provided token has been already used or doesn't exist.");

                return(null);
            }

            var doesConfirmationExist = await _testingPersonnelConfirmationsRepository
                                        .CheckIfConfirmationExistsForInvitationAndTestingPersonnelAsync(testingPersonnelAndInvitationData.InvitationId, testingPersonnelAndInvitationData.TestingPersonnelId)
                                        .ConfigureAwait(false);

            if (doesConfirmationExist)
            {
                ValidationDictionary
                .AddModelError("Confirmation already exists", $"Confirmation for this invitation already exists.");

                await _invitationConfirmationTokensRepository
                .DisposeInvitationConfirmationToken(confirmDto.Token)
                .ConfigureAwait(false);

                return(null);
            }

            var testingPersonnelConfirmSpecDto = new TestingPersonnelConfirmationSpecDto
            {
                InvitationId = testingPersonnelAndInvitationData.InvitationId,
                PersonnelId  = testingPersonnelAndInvitationData.TestingPersonnelId,
                ShiftNumbers = confirmDto.Shifts
            };

            var shiftsBooked = await _testingPersonnelConfirmationsRepository
                               .AddConfirmationOfInvitationAsync(testingPersonnelConfirmSpecDto)
                               .ConfigureAwait(false);

            await _invitationConfirmationTokensRepository
            .DisposeInvitationConfirmationToken(confirmDto.Token)
            .ConfigureAwait(false);

            if (shiftsBooked.ShiftsBooked.Any())
            {
                await _mailSender
                .SendConfirmationForPoolingAssignmentAsync(testingPersonnelAndInvitationData.Email,
                                                           testingPersonnelAndInvitationData.InvitationDate, shiftsBooked.ShiftsBooked)
                .ConfigureAwait(false);
            }

            return(shiftsBooked);
        }
        public async Task <TestingPersonnelInvitationConfirmedShiftsDto> CreateConfirmationAsync(TestingPersonnelManuallyAddedConfirmationDto confirmDto)
        {
            if (confirmDto == null)
            {
                throw new ArgumentNullException(nameof(confirmDto));
            }

            var invitationId = await _testingPersonnelInvitationsRepository.GetInvitationIdByDateAsync(confirmDto.Date.Date)
                               .ConfigureAwait(false);

            if (invitationId == Guid.Empty)
            {
                ValidationDictionary
                .AddModelError("Invitation for date was not found", $"{confirmDto.Date.ToString(dateFormat, CultureInfo.InvariantCulture)}");
                return(null);
            }

            var doesUserExist = await _testingPersonnelsRepository
                                .AnyAsync(tp => tp.Id == confirmDto.TestingPersonnelId)
                                .ConfigureAwait(false);

            if (!doesUserExist)
            {
                ValidationDictionary
                .AddModelError("Testing personnel was not found", $"Testing personnel was not found");
                return(null);
            }

            var doesConfirmationExist = await _testingPersonnelConfirmationsRepository
                                        .CheckIfConfirmationExistsForSelectedShiftsAsync(invitationId, confirmDto.TestingPersonnelId, confirmDto.Shifts)
                                        .ConfigureAwait(false);

            if (doesConfirmationExist)
            {
                ValidationDictionary
                .AddModelError("Confirmation already exists for selected testing personnel", $"Confirmation already exists for selected testing personnel");
                return(null);
            }

            var testingPersonnelConfirmSpecDto = new TestingPersonnelConfirmationSpecDto
            {
                InvitationId = invitationId,
                PersonnelId  = confirmDto.TestingPersonnelId,
                ShiftNumbers = confirmDto.Shifts
            };

            var confirmedShifts = await _testingPersonnelConfirmationsRepository
                                  .AddConfirmationOfInvitationAsync(testingPersonnelConfirmSpecDto)
                                  .ConfigureAwait(false);

            if (!confirmedShifts.ShiftsBooked.Any())
            {
                ValidationDictionary
                .AddModelError("Shift capacity is already full", $"Shift capacity is already full");
                return(null);
            }

            return(confirmedShifts);
        }
Exemplo n.º 3
0
        public async Task <TestingPersonnelInvitationConfirmedShiftsDto> AddConfirmationOfInvitationAsync(TestingPersonnelConfirmationSpecDto specDto)
        {
            if (specDto == null)
            {
                throw new ArgumentNullException(nameof(specDto));
            }
            var confirmedShifts = new TestingPersonnelInvitationConfirmedShiftsDto()
            {
                ShiftsBooked = new List <int>()
            };

            await using var context     = ContextFactory.CreateDataContext(null);
            await using var transaction = context.Database.BeginTransaction();
            var confirmations = context.TestingPersonnelConfirmations;

            var invitation = await context.TestingPersonnelInvitations
                             .Where(x => x.Id == specDto.InvitationId)
                             .Include(x => x.TestingPersonnelConfirmations)
                             .Select(x => new
            {
                RequiredPersonnelCountShift1        = x.RequiredPersonnelCountShift1,
                RequiredPersonnelCountShift2        = x.RequiredPersonnelCountShift2,
                TestingPersonnelConfirmationsShift1 = x.TestingPersonnelConfirmations.Where(conf => conf.ShiftNumber == ShiftNumber.First && !conf.CanceledOn.HasValue).Count(),
                TestingPersonnelConfirmationsShift2 = x.TestingPersonnelConfirmations.Where(conf => conf.ShiftNumber == ShiftNumber.Second && !conf.CanceledOn.HasValue).Count()
            })
                             .FirstAsync()
                             .ConfigureAwait(false);

            if (invitation.RequiredPersonnelCountShift1 > invitation.TestingPersonnelConfirmationsShift1 ||
                invitation.RequiredPersonnelCountShift2 > invitation.TestingPersonnelConfirmationsShift2)
            {
                foreach (var shiftNumber in specDto.ShiftNumbers)
                {
                    var entity = Mapper.Map <TestingPersonnelConfirmationSpecDto, TestingPersonnelConfirmation>(specDto);
                    entity.Id         = Guid.NewGuid();
                    entity.AcceptedOn = DateTime.UtcNow;

                    if (shiftNumber == ShiftNumber.First &&
                        invitation.RequiredPersonnelCountShift1 > invitation.TestingPersonnelConfirmationsShift1)
                    {
                        entity.ShiftNumber = ShiftNumber.First;
                        confirmations.Add(entity);
                        confirmedShifts.ShiftsBooked.Add(1);
                    }
                    else if (shiftNumber == ShiftNumber.Second &&
                             invitation.RequiredPersonnelCountShift2 > invitation.TestingPersonnelConfirmationsShift2)
                    {
                        entity.ShiftNumber = ShiftNumber.Second;
                        confirmations.Add(entity);
                        confirmedShifts.ShiftsBooked.Add(2);
                    }
                }

                await context.SaveChangesAsync().ConfigureAwait(false);

                await transaction.CommitAsync().ConfigureAwait(false);
            }

            return(confirmedShifts);
        }