示例#1
0
        /// <summary>
        ///     Returns all participations which pass the provided filters
        ///     If no answer exists, Automatically adds appointment participations with the answer null
        /// </summary>
        private static List <AppointmentParticipation> FilterAndAppendAllParticipations(Appointment appointment,
                                                                                        Func <AppointmentParticipation, bool> participationFilter,
                                                                                        Func <EventParticipation, bool> eventFilter)
        {
            // First create the appointment participations for users which have no participation yet
            // A appointment participation is required to track the sent emails
            List <int> participantIds = appointment.AppointmentParticipations.Select(p => p.ParticipantId).ToList();

            foreach (EventParticipation eventParticipationWithoutAppointmentParticipation in appointment.Event.EventParticipations.Where(e => !participantIds.Contains(e.ParticipantId)))
            {
                var newAppointmentParticipation = new AppointmentParticipation
                {
                    Appointment = appointment,
                    Participant = eventParticipationWithoutAppointmentParticipation.Participant,
                    AppointmentParticipationAnswer = null,
                    SentReminder = false,
                    SentSummary  = false
                };

                appointment.AppointmentParticipations.Add(newAppointmentParticipation);
            }

            return(appointment.AppointmentParticipations
                   .Where(participationFilter)
                   .Where(p => eventFilter(p.Appointment.Event.EventParticipations.First(e => e.Participant == p.Participant)))
                   .ToList());
        }
示例#2
0
        public async Task <MyAppointmentListDto> GetMyAppointmentsAsync(int?limit, int?offset)
        {
            var treeQuery = new Domain.Logic.Sections.FlattenedTree.Query();
            IEnumerable <ITree <Section> > flattenedTree = await _mediator.Send(treeQuery);

            Person currentPerson = await _userAccessor.GetCurrentPersonAsync();

            Tuple <IQueryable <Appointment>, int> appointmentTuple = await _mediator.Send(
                new AppointmentList.Query(limit, offset, flattenedTree, currentPerson));

            IList <MyAppointmentDto> myAppointmentDtos = await appointmentTuple.Item1
                                                         .ProjectTo <MyAppointmentDto>(_mapper.ConfigurationProvider)
                                                         .ToListAsync();

            foreach (MyAppointmentDto dto in myAppointmentDtos)
            {
                AppointmentParticipation participation = await _mediator.Send(new Domain.Logic.AppointmentParticipations.Details.Query(
                                                                                  dto.Id, currentPerson.Id));

                if (participation != null)
                {
                    _mapper.Map(participation, dto);
                }
            }

            return(new MyAppointmentListDto
            {
                TotalRecordsCount = appointmentTuple.Item2,
                UserAppointments = myAppointmentDtos
            });
        }
示例#3
0
            public async Task <Unit> Handle(Command request, CancellationToken cancellationToken)
            {
                Appointment existingAppointment = await _arpaContext.Appointments.FindAsync(new object[] { request.Id }, cancellationToken);

                AppointmentParticipation participation = existingAppointment.AppointmentParticipations
                                                         .FirstOrDefault(pa => pa.PersonId == request.PersonId);

                if (participation == null)
                {
                    participation = new AppointmentParticipation(Guid.NewGuid(), _mapper.Map <Command, Create.Command>(request));
                    await _arpaContext.AppointmentParticipations.AddAsync(participation, cancellationToken);
                }
                else
                {
                    _mapper.Map(request, participation);
                    _arpaContext.AppointmentParticipations.Update(participation);
                }

                if (await _arpaContext.SaveChangesAsync(cancellationToken) > 0)
                {
                    return(Unit.Value);
                }

                throw new Exception("Problem updating appointment participation");
            }
示例#4
0
 private static AppointmentParticipationDto CreateDto(AppointmentParticipation appointment)
 {
     return(new AppointmentParticipationDto
     {
         CreatedBy = "anonymous",
         CreatedAt = FakeDateTime.UtcNow,
         Id = appointment.Id,
         ModifiedAt = null,
         ModifiedBy = appointment.ModifiedBy,
         PredictionId = appointment.PredictionId,
         ResultId = appointment.ResultId
     });
 }
        public async Task <IActionResult> SetAppointmentResponse(SetAppointmentResponseDto setAppointmentResponseDto)
        {
            IDatabaseContext context     = _getDatabaseContext();
            Appointment?     appointment = await context.Appointments
                                           .Include(a => a.Event)
                                           .ThenInclude(e => e.Organizer)
                                           .Include(a => a.Event)
                                           .ThenInclude(e => e.EventParticipations)
                                           .Include(a => a.AppointmentParticipations)
                                           .ThenInclude(ap => ap.Participant)
                                           .FirstOrDefaultAsync(a => a.Id == setAppointmentResponseDto.AppointmentId);

            if (appointment == null)
            {
                return(BadRequest(RequestStringMessages.AppointmentNotFound));
            }

            User userToSetResponseFor = await context.Users.FindAsync(setAppointmentResponseDto.UserId);

            if (userToSetResponseFor == null)
            {
                return(BadRequest(RequestStringMessages.UserNotFound));
            }

            User currentUser = await HttpContext.GetCurrentUserAsync(context);

            bool changingOtherUser = currentUser != userToSetResponseFor;

            bool userIsPartOfEvent = appointment.Event.EventParticipations.Any(e => e.ParticipantId == userToSetResponseFor.Id);

            if (changingOtherUser)
            {
                if (appointment.Event.Organizer != currentUser)
                {
                    // Only the organizer is allowed to change another user
                    _logger.LogInformation("{0}(): Tried to set response for user {1} for the appointment {2}, which he's not organizing", nameof(SetAppointmentResponse), userToSetResponseFor.Id, appointment.Id);

                    return(BadRequest(RequestStringMessages.OrganizerRequired));
                }

                if (!userIsPartOfEvent)
                {
                    // A organizer shouldn't be able to add a user to the event, unless the user is participating in the event
                    // This should prevent that a user gets added to an event he never had anything to do with
                    return(BadRequest(RequestStringMessages.UserNotPartOfEvent));
                }
            }

            // Ensure a user can't participate in a private event without an invitation
            if (!userIsPartOfEvent && appointment.Event.IsPrivate && (appointment.Event.Organizer != currentUser))
            {
                return(BadRequest(RequestStringMessages.InvitationRequired));
            }

            AppointmentParticipation appointmentParticipation = appointment.AppointmentParticipations.FirstOrDefault(e => e.ParticipantId == userToSetResponseFor.Id);

            if (appointmentParticipation == null)
            {
                // Create a new participation if there isn't an existing one
                appointmentParticipation = new AppointmentParticipation
                {
                    Participant = userToSetResponseFor,
                    Appointment = appointment
                };

                context.AppointmentParticipations.Add(appointmentParticipation);
            }

            bool changeRelevantForSummary =
                (appointmentParticipation.AppointmentParticipationAnswer == AppointmentParticipationAnswer.Accepted) ||
                (setAppointmentResponseDto.Response == AppointmentParticipationAnswer.Accepted);

            appointmentParticipation.AppointmentParticipationAnswer = setAppointmentResponseDto.Response;

            if (!appointment.Event.EventParticipations.Select(e => e.ParticipantId).Contains(currentUser.Id))
            {
                // Automatically add a user to an event if he's not yet part of it
                var eventParticipation = new EventParticipation
                {
                    Event       = appointment.Event,
                    Participant = currentUser
                };

                context.EventParticipations.Add(eventParticipation);

                _auditLogger.LogInformation("{0}(): Joined event {1} automatically after joining appointment {2}", nameof(SetAppointmentResponse), appointment.Event.Id, appointment.Id);
            }

            await context.SaveChangesAsync();

            // Handle notifications
            if (changingOtherUser)
            {
                _auditLogger.LogInformation("{0}(response={1}): The organizer set the response to the appointment {2} for user {3}", nameof(SetAppointmentResponse), setAppointmentResponseDto.Response, appointment.Id, userToSetResponseFor.Id);

                await _notificationService.NotifyOrganizerUpdatedUserInfoAsync(appointment.Event, userToSetResponseFor, "Der Organisator hat Ihre Zusage an einem Termin editiert.");
            }
            else
            {
                _logger.LogDebug("{0}(response={1}): Set own response for appointment {2}", nameof(SetAppointmentResponse), setAppointmentResponseDto.Response, appointment.Id);
            }

            if (changeRelevantForSummary)
            {
                // Don't send a last minute change if the response change is irrelevant
                // E.g. Changing from No Answer to Declined
                await _notificationService.SendLastMinuteChangeIfRequiredAsync(appointment);
            }
            else
            {
                _logger.LogDebug("{0}(response={1}): Intentionally skipped last minute change as the change wasn't relevant for the summary", nameof(SetAppointmentResponse), setAppointmentResponseDto.Response, appointment.Id);
            }

            return(Ok());
        }
示例#6
0
 private static AppointmentParticipationNotificationInformation ExtractNotificationInformation(AppointmentParticipation participation)
 {
     return(new AppointmentParticipationNotificationInformation(
                ExtractNotificationInformation(participation.Participant),
                participation.AppointmentParticipationAnswer,
                participation.SentSummary,
                participation.SentReminder));
 }