private void LogFusionMeeting(GeneralMeeting meeting)
        {
            var message = new StringBuilder();

            message.AppendLine($"Meeting ID: {meeting.Id}");
            message.AppendLine($"Meeting Classification: {meeting.Classification}");
            foreach (var p in meeting.Participants)
            {
                message.AppendLine($" Guid:({p.Person.Id?.ToString()}), Name:({p.Person?.Name}), Email:({p.Person?.Mail}), OutlookResponse:({p.OutlookResponse}), Type:({p.Type}), IsOrganizer:({p.Organizer}), IsResponsible:({p.Responsible})");
            }

            _logger.LogInformation(message.ToString());
        }
        public async Task <Result <InvitationDto> > Handle(GetInvitationByIdQuery request, CancellationToken cancellationToken)
        {
            var invitation = await _context.QuerySet <Invitation>()
                             .Include(i => i.CommPkgs)
                             .Include(i => i.McPkgs)
                             .Include(i => i.Participants)
                             .SingleOrDefaultAsync(x => x.Id == request.InvitationId, cancellationToken);

            if (invitation == null)
            {
                return(new NotFoundResult <InvitationDto>(Strings.EntityNotFound(nameof(Invitation), request.InvitationId)));
            }

            var createdBy = await _context.QuerySet <Person>().SingleOrDefaultAsync(p => p.Id == invitation.CreatedById, cancellationToken);

            if (createdBy == null)
            {
                return(new NotFoundResult <InvitationDto>(Strings.EntityNotFound(nameof(Person), invitation.CreatedById)));
            }

            GeneralMeeting meeting = null;

            try
            {
                meeting = await _meetingClient.GetMeetingAsync(invitation.MeetingId,
                                                               query => query.ExpandInviteBodyHtml().ExpandProperty("participants.outlookstatus"));

                LogFusionMeeting(meeting);
            }
            catch (NotAuthorizedError e)
            {
                _logger.LogWarning(e, $"Fusion meeting not authorized. MeetingId={invitation.MeetingId}");
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"Fusion meeting error. MeetingId={invitation.MeetingId}.");
            }

            var invitationDto = await ConvertToInvitationDtoAsync(invitation, meeting, createdBy);

            return(new SuccessResult <InvitationDto>(invitationDto));
        }
        private async Task <InvitationDto> ConvertToInvitationDtoAsync(Invitation invitation, GeneralMeeting meeting, Person createdBy)
        {
            var canEdit = meeting != null &&
                          (meeting.Participants.Any(p => p.Person.Id == _currentUserProvider.GetCurrentUserOid()) ||
                           meeting.Organizer.Id == _currentUserProvider.GetCurrentUserOid());
            var currentUserIsCreator = createdBy.Id == invitation.CreatedById;
            var canDelete            = invitation.Status == IpoStatus.Canceled && currentUserIsCreator;
            var canCancel            = invitation.Status is IpoStatus.Completed or IpoStatus.Planned &&
                                       (currentUserIsCreator ||
                                        await CurrentUserIsAmongParticipantsAsync(invitation.Participants.Where(p => p.SortKey == 0).ToList()));

            var invitationResult = new InvitationDto(
                invitation.ProjectName,
                invitation.Title,
                invitation.Description,
                invitation.Location,
                invitation.Type,
                invitation.Status,
                ConvertToPersonDto(invitation.CreatedById).Result,
                invitation.StartTimeUtc,
                invitation.EndTimeUtc,
                canEdit,
                invitation.RowVersion.ConvertToString(),
                canCancel,
                canDelete)
            {
                Participants = await ConvertToParticipantDtoAsync(invitation.Participants, invitation.Status),
                McPkgScope   = ConvertToMcPkgDto(invitation.McPkgs),
                CommPkgScope = ConvertToCommPkgDto(invitation.CommPkgs)
            };

            AddParticipantTypeAndOutlookResponseToParticipants(meeting, invitationResult);

            return(invitationResult);
        }
 private static ParticipantType?GetParticipantTypeByEmail(GeneralMeeting meeting, string email)
 => meeting.Participants.FirstOrDefault(p =>
                                        string.Equals(p.Person.Mail, email, StringComparison.CurrentCultureIgnoreCase))?.Type;
 private static OutlookResponse?GetOutlookResponseByEmailAsync(GeneralMeeting meeting, string email)
 => meeting.Participants.FirstOrDefault(p
                                        => string.Equals(p.Person.Mail, email, StringComparison.CurrentCultureIgnoreCase))
 ?.OutlookResponse;
        private static void AddParticipantTypeAndOutlookResponseToParticipants(GeneralMeeting meeting, InvitationDto invitationResult)
        {
            foreach (var participant in invitationResult.Participants)
            {
                if (participant.Person != null)
                {
                    OutlookResponse?participantPersonResponse = null;
                    if (meeting != null)
                    {
                        participantPersonResponse = participant.Person.AzureOid == meeting.Organizer.Id
                            ? OutlookResponse.Organizer
                            : GetOutlookResponseByEmailAsync(meeting, participant.Person.Email);
                    }

                    participant.Person.Response = participantPersonResponse;
                }

                if (participant.ExternalEmail != null)
                {
                    var externalEmailResponse = meeting != null
                        ? GetOutlookResponseByEmailAsync(meeting, participant.ExternalEmail?.ExternalEmail)
                        : null;

                    participant.ExternalEmail.Response = externalEmailResponse;
                }

                if (participant.FunctionalRole != null)
                {
                    foreach (var personInFunctionalRole in participant.FunctionalRole.Persons)
                    {
                        var participantType = meeting != null
                            ? GetParticipantTypeByEmail(meeting, personInFunctionalRole.Email)
                            : null;

                        personInFunctionalRole.Required = participantType.Equals(ParticipantType.Required);

                        var functionalRolePersonResponse = meeting != null
                            ? GetOutlookResponseByEmailAsync(meeting, personInFunctionalRole.Email)
                            : null;

                        personInFunctionalRole.Response = functionalRolePersonResponse;
                    }

                    OutlookResponse?functionalRoleResponse = null;
                    if (participant.FunctionalRole.Email != null && meeting != null)
                    {
                        functionalRoleResponse =
                            GetOutlookResponseByEmailAsync(meeting, participant.FunctionalRole.Email);
                    }

                    if (participant.FunctionalRole.Persons != null && meeting != null)
                    {
                        functionalRoleResponse = GetOutlookResponseForFunctionalRole(
                            participant.FunctionalRole.Persons.ToList(),
                            functionalRoleResponse);
                    }

                    participant.FunctionalRole.Response = functionalRoleResponse;
                }
            }
        }