/// <summary>
 /// Function to retrieve photo of Visitor.
 /// </summary>
 /// <param name="visitor">Instance of Crewmember</param>
 private static void RetrieveVisitorPhoto(Visitor visitor)
 {
     Observable.ToAsync(() =>
     {
         var person = new Person();
         var visitorCollection = new VisitorCollection();
         visitorCollection.Add(visitor);
         person.AssignVisitors(visitorCollection);
         DIContainer.Instance.Resolve<PhotoService>().RetrievePhotos(person);
     })().Subscribe(r => { }, ex => { });
 }
        /// <summary>
        /// Maps the person.
        /// </summary>
        /// <param name="dataReader">The data reader.</param>
        /// <returns>Person list</returns>
        internal static async Task<ListResult<Person>> MapPerson(SqlDataReader dataReader)
        {
            var persons = new ListResult<Person>();
            var person = new Person();
            var personCollection = new Collection<Person>();

            if (dataReader != null)
            {
                ////Map Crew
                person.AssignCrewmembers(await MapCrew(dataReader));

                ////Map Crew Personal Detail
                await dataReader.NextResultAsync();
                var crewPersonDetailList = await RetrieveCrewmemberPersonalDetail(dataReader);

                ////map access card
                await dataReader.NextResultAsync();
                var crewAccessCards = await AccessCardMapper.MapCrewAccessCards(dataReader);

                ////Map Crew Alerts
                await dataReader.NextResultAsync();
                var alerts = await AlertsAndMessageMapper.MapCrewAlerts(dataReader);

                await dataReader.NextResultAsync();
                var alertMessages = await AlertsAndMessageMapper.MapMessagesDescription(dataReader);

                await dataReader.NextResultAsync();
                var messages = await AlertsAndMessageMapper.MapCrewMessages(dataReader);

                await dataReader.NextResultAsync();
                var messageDescription = await AlertsAndMessageMapper.MapMessagesDescription(dataReader);

                MapCrewDetail(person, crewPersonDetailList, alerts, alertMessages, messages, messageDescription, crewAccessCards);

                ////Map Visitor
                await dataReader.NextResultAsync();
                person.AssignVisitors(await MapVisitors(dataReader));

                ////Map Visitor Personal Detail
                await dataReader.NextResultAsync();
                var visitorPersonalDetailList = await RetrieveVisitorPersonalDetail(dataReader);

                ////Map Visitor access card
                await dataReader.NextResultAsync();
                var visitorAccessCards = await AccessCardMapper.MapVisitorAccessCards(dataReader);

                ////Map Visitor Alerts
                await dataReader.NextResultAsync();
                var visitorAlerts = await AlertsAndMessageMapper.MapVisitorAlerts(dataReader);

                await dataReader.NextResultAsync();
                var visitorAlertMessages = await AlertsAndMessageMapper.MapMessagesDescription(dataReader);

                await dataReader.NextResultAsync();
                var visitorMessages = await AlertsAndMessageMapper.MapVisitorMessages(dataReader);

                await dataReader.NextResultAsync();
                var visitorMessagesDescription = await AlertsAndMessageMapper.MapMessagesDescription(dataReader);

                MapVisitorDetail(person, visitorPersonalDetailList, visitorAlerts, visitorAlertMessages, visitorMessages, visitorMessagesDescription, visitorAccessCards);

                ////Map Guest
                await dataReader.NextResultAsync();
                person.AssignGuests(await MapGuests(dataReader));

                ////Map Guest Personal Detail
                await dataReader.NextResultAsync();
                var guestPersonDetailList = await RetrieveGuestPersonalDetail(dataReader);

                ////Map Guest Cruise Detail
                await dataReader.NextResultAsync();
                var guestReservationDetailList = await RetrieveGuestReservationDetail(dataReader);

                ////Map Guest Alerts
                await dataReader.NextResultAsync();
                var guestAlerts = await AlertsAndMessageMapper.MapGuestAlerts(dataReader);

                await dataReader.NextResultAsync();
                var guestAlertMessages = await AlertsAndMessageMapper.MapMessagesDescription(dataReader);

                await dataReader.NextResultAsync();
                var guestMessages = await AlertsAndMessageMapper.MapGuestMessages(dataReader);

                await dataReader.NextResultAsync();
                var guestMessagesDescription = await AlertsAndMessageMapper.MapMessagesDescription(dataReader);

                // Map folio data.
                await dataReader.NextResultAsync();
                var folioList = await RetrieveFolios(dataReader);

                MapGuestDetail(person, guestPersonDetailList, guestReservationDetailList, guestAlerts, guestAlertMessages, guestMessages, guestMessagesDescription, folioList);

                ////map total results
                await dataReader.NextResultAsync();
                await MapTotalResults(dataReader, person);

                if (!dataReader.IsClosed)
                {
                    dataReader.Close();
                }
            }

            personCollection.Add(person);
            persons.AssignItems(personCollection);
            return await Task.FromResult(persons);
        }
        /// <summary>
        /// Searches the person.
        /// </summary>
        /// <param name="searchParameters">The search parameters.</param>
        /// <param name="personTypeList">The person type list.</param>
        /// <param name="staterooms">The staterooms.</param>
        /// <returns>
        /// Return person instance.
        /// </returns>
        private async Task<Person> SearchPerson(PersonSearchParameter searchParameters, ListResult<PersonTypeEntity> personTypeList, ListResult<DataAccess.Entities.Stateroom> staterooms)
        {
            var personType = searchParameters.PersonType.HasValue ? searchParameters.PersonType.Value : PersonTypes.All;
            var person = new Person();
            if ((personType & PersonTypes.All) == PersonTypes.All)
            {
                var guestList = this.RetrieveGuests(searchParameters, staterooms, true);
                var crewMemberList = this.RetrieveCrewMembers(searchParameters, personTypeList, staterooms);
                var visitorList = this.RetrieveVisitorsAsync(searchParameters, personTypeList);
                await Task.WhenAll(guestList, crewMemberList, visitorList);

                person.AssignGuests(guestList.Result.Items);
                person.TotalGuestsCount = guestList.Result.TotalResults;
                person.AssignCrewmembers(crewMemberList.Result.Items);
                person.TotalCrewmembersCount = crewMemberList.Result.TotalResults;
                person.AssignVisitors(visitorList.Result.Items);
                person.TotalVisitorsCount = visitorList.Result.Items.Count;
            }
            else if (personType == PersonTypes.Guest)
            {
                var guestList = await this.RetrieveGuests(searchParameters, staterooms, true);
                person.AssignGuests(guestList.Items);
                person.TotalGuestsCount = guestList.TotalResults;
            }
            else if (personType == PersonTypes.Crew)
            {
                var crewMemberList = await this.RetrieveCrewMembers(searchParameters, personTypeList, staterooms);
                person.AssignCrewmembers(crewMemberList.Items);
                person.TotalCrewmembersCount = crewMemberList.TotalResults;
            }
            else if (personType == PersonTypes.Visitor)
            {
                var visitorList = await this.RetrieveVisitorsAsync(searchParameters, personTypeList);
                person.AssignVisitors(visitorList.Items);
                person.TotalVisitorsCount = visitorList.Items.Count;
            }

            return person;
        }
        /// <summary>
        /// Retrieves the person by identifier.
        /// </summary>
        /// <param name="searchParameters">The search parameters.</param>
        /// <param name="personTypeList">The person type list.</param>
        /// <param name="staterooms">The staterooms.</param>
        /// <returns>Return Instance of person.</returns>
        private async Task<Person> RetrievePersonByIdAndDocument(PersonSearchParameter searchParameters, ListResult<PersonTypeEntity> personTypeList, ListResult<DataAccess.Entities.Stateroom> staterooms)
        {
            var person = new Person();
            var applicationSetting = DIContainer.Instance.Resolve<IApplicationSetting>();
            if ((!string.IsNullOrEmpty(searchParameters.GuestIds) && !string.IsNullOrEmpty(searchParameters.CrewmemberIds) && !string.IsNullOrEmpty(searchParameters.VisitorIds))
                || (!string.IsNullOrWhiteSpace(searchParameters.DocumentNo) && searchParameters.DocumentTypeId.Equals(applicationSetting.DocumentTypeId) && searchParameters.PersonType == PersonTypes.All))
            {
                person = await this.SearchPerson(searchParameters, personTypeList, staterooms);
            }
            else if (!string.IsNullOrEmpty(searchParameters.GuestIds) && !string.IsNullOrEmpty(searchParameters.CrewmemberIds))
            {
                person = await this.SearchGuestAndCrew(searchParameters, personTypeList, staterooms);
            }
            else if (!string.IsNullOrEmpty(searchParameters.GuestIds) && !string.IsNullOrEmpty(searchParameters.VisitorIds))
            {
                var guestList = this.RetrieveGuests(searchParameters, staterooms, true);
                var visitorList = this.RetrieveVisitorsAsync(searchParameters, personTypeList);
                await Task.WhenAll(guestList, visitorList);

                person.AssignGuests(guestList.Result.Items);
                person.TotalGuestsCount = guestList.Result.TotalResults;
                person.AssignVisitors(visitorList.Result.Items);
                person.TotalVisitorsCount = visitorList.Result.Items.Count;
            }
            else if (!string.IsNullOrEmpty(searchParameters.CrewmemberIds) && !string.IsNullOrEmpty(searchParameters.VisitorIds))
            {
                var crewMemberList = this.RetrieveCrewMembers(searchParameters, personTypeList, staterooms);
                var visitorList = this.RetrieveVisitorsAsync(searchParameters, personTypeList);
                await Task.WhenAll(crewMemberList, visitorList);

                person.AssignCrewmembers(crewMemberList.Result.Items);
                person.TotalCrewmembersCount = crewMemberList.Result.TotalResults;
                person.AssignVisitors(visitorList.Result.Items);
                person.TotalVisitorsCount = visitorList.Result.Items.Count;
            }
            else if (!string.IsNullOrEmpty(searchParameters.GuestIds) || (!string.IsNullOrWhiteSpace(searchParameters.DocumentNo) && searchParameters.PersonType == PersonTypes.Guest))
            {
                var guestList = await this.RetrieveGuests(searchParameters, staterooms, true);
                person.AssignGuests(guestList.Items);
                person.TotalGuestsCount = guestList.TotalResults;
            }
            else if (!string.IsNullOrEmpty(searchParameters.CrewmemberIds) || !string.IsNullOrWhiteSpace(searchParameters.EmployeeNumber) || (!string.IsNullOrWhiteSpace(searchParameters.DocumentNo) && searchParameters.PersonType == PersonTypes.Crew))
            {
                var crewMemberList = await this.RetrieveCrewMembers(searchParameters, personTypeList, staterooms);
                person.AssignCrewmembers(crewMemberList.Items);
                person.TotalCrewmembersCount = crewMemberList.TotalResults;
            }
            else if ((!string.IsNullOrEmpty(searchParameters.VisitorIds) || searchParameters.Birthdate.HasValue || (!string.IsNullOrWhiteSpace(searchParameters.DocumentNo) && searchParameters.PersonType == PersonTypes.Visitor))
                && (!string.IsNullOrEmpty(searchParameters.StartDate) || !string.IsNullOrEmpty(searchParameters.EndDate)))
            {
                var visitorList = await this.RetrieveVisitorsAsync(searchParameters, personTypeList);
                person.AssignVisitors(visitorList.Items);
                person.TotalVisitorsCount = visitorList.Items.Count;
            }

            return person;
        }
 /// <summary>
 /// Adds the visitor in person.
 /// </summary>
 /// <param name="personList">The person list.</param>
 /// <param name="person">The person.</param>
 /// <param name="visitorList">The visitor list.</param>
 private static void AddVisitorInPerson(ListResult<Person> personList, Person person, ListResult<Visitor> visitorList)
 {
     person.AssignVisitors(visitorList.Items);
     person.TotalVisitorsCount = visitorList.TotalResults;
     personList.TotalResults += visitorList.TotalResults;
 }
        /// <summary>
        /// Show Party Detail.
        /// </summary>
        /// <param name="selectedPerson">The Selected Person Identifier.</param>
        public async void ShowPartyDetail(PersonBase selectedPerson)
        {
            if (selectedPerson != null)
            {
                Messenger.Instance.Notify(MessengerMessage.ShowSpinWheel, true);

                if (selectedPerson.PersonType == PersonType.Guest)
                {
                    this.SetVoyage();
                    await this.RetrieveGuestsBySearchText(selectedPerson);
                }
                else
                {
                    var person = new Person();
                    person.AssignCrewmembers(this.RetrieveCrewMemberParty());
                    person.AssignVisitors(this.RetrieveVisitorParty());

                    // For crew member and visitor.
                    IList<PersonIdentity> personIdentities = new List<PersonIdentity>() { new PersonIdentity { PersonId = selectedPerson.PersonId, PersonType = selectedPerson.PersonType } };
                    var personsParty = await this.personsPartyService.RetrievePersonsPartyByPersons(person, personIdentities);
                    this.ManageParty(personsParty);
                }
            }
        }