/// <summary>
        /// Function to retrieve persons by search text.
        /// </summary>
        /// <param name="shipId">The ship identifier.</param>
        /// <param name="searchText">Search text</param>
        /// <param name="personTypes">List of person types to search</param>
        /// <param name="searchType">Search Type</param>
        /// <param name="dob">The DOB.</param>
        /// <param name="documentTypeId">The document type identifier.</param>
        /// <param name="pageNumber">The page number.</param>
        /// <param name="maxResults">The maximum results.</param>
        /// <param name="personId">The person identifier.</param>
        /// <param name="folioNumber">The folio number.</param>
        /// <returns>List of Person.</returns>
        public async Task<Person> RetrievePersonsBySearchText(string shipId, string searchText, IList<PersonType> personTypes, SearchType searchType, string dob = null, string documentTypeId = null, int? pageNumber = null, int? maxResults = null, string personId = null, string folioNumber = null)
        {
            var personType = personTypes.RetrievePersonTypeFilterValue();

            var workstation = DIContainer.Instance.Resolve<Workstation>();
            var activeVoyagesString = workstation.SelectedVoyageIds;
            var startDate = searchType == SearchType.StateroomFromStatisticsHistory ? null : workstation.CurrentDateTime.ToString(CommonConstants.DateFormat, CultureInfo.CurrentCulture);
            var endDate = searchType == SearchType.StateroomFromStatisticsHistory ? null : workstation.CurrentDateTime.Date.AddHours(23).AddMinutes(59).AddSeconds(59).ToString(CommonConstants.DateTimeFormat, CultureInfo.CurrentCulture);
            var shipDateTime = workstation.CurrentDateTime.ToString(CommonConstants.DateTimeFormat, CultureInfo.CurrentCulture);
            string itineraryDate = workstation.CurrentDateTime.ToString(CommonConstants.DateFormat, CultureInfo.CurrentCulture);

            var personData = new ListResult<Person>();
            string accessCardNumberScanned = string.Empty;

            if (personTypes.FirstOrDefault() == PersonType.Visitor && (!string.IsNullOrEmpty(documentTypeId) || !string.IsNullOrEmpty(dob)))
            {
                var task = await this.personsClient.RetrievePersonsAsync(shipId, documentTypeId: documentTypeId, documentNo: searchText, birthdate: dob, personType: personType, voyageIds: activeVoyagesString, startDate: startDate, endDate: endDate, alertMessageStartDate: shipDateTime, alertMessageEndDate: shipDateTime, portId: workstation.Port.PortId, portArrivalDate: itineraryDate);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }
            else if (personTypes.Count == 1 && personTypes.FirstOrDefault() == PersonType.Crewmember && searchType == SearchType.EmployeeNumber)
            {
                var task = await this.personsClient.RetrievePersonsAsync(shipId, employeeNumber: searchText, personType: personType, voyageIds: activeVoyagesString, startDate: startDate, endDate: endDate, alertMessageStartDate: shipDateTime, alertMessageEndDate: shipDateTime, portId: workstation.Port.PortId, portArrivalDate: itineraryDate);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }
            else if (searchType == SearchType.LastName)
            {
                var task = await this.personsClient.RetrievePersonsAsync(shipId, nameContains: searchText, personType: personType, voyageIds: activeVoyagesString, pageNumber: pageNumber, maxResults: maxResults, startDate: startDate, endDate: endDate, alertMessageStartDate: shipDateTime, alertMessageEndDate: shipDateTime, portId: workstation.Port.PortId, portArrivalDate: itineraryDate);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }
            else if (searchType == SearchType.Stateroom || searchType == SearchType.StateroomFromStatisticsHistory)
            {
                var task = await this.personsClient.RetrievePersonsAsync(shipId, staterooms: searchText, personType: personType, voyageIds: activeVoyagesString, maxResults: 0, startDate: startDate, endDate: endDate, alertMessageStartDate: shipDateTime, alertMessageEndDate: shipDateTime, portId: workstation.Port.PortId, portArrivalDate: itineraryDate);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }
            else if (searchType == SearchType.Reservation)
            {
                var task = await this.personsClient.RetrievePersonsAsync(shipId, reservationNumbers: searchText, personType: personType, voyageIds: activeVoyagesString, maxResults: 0, startDate: startDate, endDate: endDate, alertMessageStartDate: shipDateTime, alertMessageEndDate: shipDateTime, portId: workstation.Port.PortId, portArrivalDate: itineraryDate);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }
            else if (searchType == SearchType.PassportNumber)
            {
                var task = await this.personsClient.RetrievePersonsAsync(shipId, documentNo: searchText, personType: personType, voyageIds: activeVoyagesString, startDate: startDate, endDate: endDate, documentTypeId: documentTypeId, alertMessageStartDate: shipDateTime, alertMessageEndDate: shipDateTime, portId: workstation.Port.PortId, portArrivalDate: itineraryDate);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }
            else if (searchType == SearchType.PersonId)
            {
                var task = await this.RetrievePersonsByPersonId(shipId, personTypes.FirstOrDefault(), startDate, endDate, personId, shipDateTime);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }
            else if (searchType == SearchType.BarcodeScanning)
            {
                accessCardNumberScanned = searchText;
                var task = await this.personsClient.RetrievePersonsAsync(shipId, accessCardNumber: searchText, personType: personType, voyageIds: activeVoyagesString, startDate: startDate, endDate: endDate, alertMessageStartDate: shipDateTime, alertMessageEndDate: shipDateTime, maxResults: 0, portId: workstation.Port.PortId, portArrivalDate: itineraryDate);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }
            else if (searchType == SearchType.MagneticStripe || searchType == SearchType.RFID)
            {
                accessCardNumberScanned = searchText;
                var task = await this.personsClient.RetrievePersonsAsync(shipId, sourceIds: searchText, personType: personType, voyageIds: activeVoyagesString, startDate: startDate, endDate: endDate, alertMessageStartDate: shipDateTime, alertMessageEndDate: shipDateTime, maxResults: 0, portId: workstation.Port.PortId, portArrivalDate: itineraryDate);
                personData = task != null ? JsonConvert.DeserializeObject<ListResult<Person>>(task) : default(ListResult<Person>);
            }

            var data = personData != null ? personData.Items.FirstOrDefault() : null;

            // Fills IsOnboard status
            if (data != null)
            {
                data.TotalResults = personData.TotalResults;

                CommonDataMethods.FillOnboardStatus(data);
                CommonDataMethods.ManageAlerts(data, accessCardNumberScanned, folioNumber);
                CommonDataMethods.FillCardStatusForVisitor(data);
            }

            return await Task.FromResult(data ?? new Person());
        }        
        /// <summary>
        /// Function to retrieve persons by search text.
        /// </summary>
        /// <param name="shipId">The ship identifier.</param>
        /// <param name="searchText">Search text</param>
        /// <param name="personTypes">List of person types to search</param>
        /// <param name="searchType">Search Type</param>
        /// <param name="dob">The dob.</param>
        /// <param name="documentTypeId">The document type identifier.</param>
        /// <param name="pageNumber">The page number.</param>
        /// <param name="maxResults">The maximum results.</param>
        /// <param name="personId">The person identifier.</param>
        /// <param name="folioNumber">The folio number.</param>
        /// <returns>
        /// List of Person
        /// </returns>
        public async Task<Person> RetrievePersonsBySearchText(string shipId, string searchText, IList<PersonType> personTypes, SearchType searchType, string dob = null, string documentTypeId = null, int? pageNumber = null, int? maxResults = null, string personId = null, string folioNumber = null)
        {
            var personType = personTypes.RetrievePersonTypeFilterValue();
            string personTypeId = null;
            if (personTypes.Count == 1)
            {
                personTypeId = personTypes.FirstOrDefault().RetrievePersonTypeId();
            }

            var workstation = DIContainer.Instance.Resolve<Workstation>();
            var activeVoyagesString = workstation.SelectedVoyageIds;
            var startDate = searchType == SearchType.StateroomFromStatisticsHistory ? null : workstation.CurrentDateTime.ToString(CommonConstants.DateFormat, CultureInfo.CurrentCulture);
            var endDate = searchType == SearchType.StateroomFromStatisticsHistory ? null : workstation.CurrentDateTime.Date.AddHours(23).AddMinutes(59).AddSeconds(59).ToString(CommonConstants.DateTimeFormat, CultureInfo.CurrentCulture);
            var shipDateTime = workstation.CurrentDateTime.ToString(CommonConstants.DateTimeFormat, CultureInfo.CurrentCulture);
            var personData = new ListResult<Person>();
            string accessCardNumberScanned = string.Empty;

            var command = this.Database.GetStoredProcCommand(RetrievePersonStoredProcedure);
            if (personTypes.FirstOrDefault() == PersonType.Visitor && (!string.IsNullOrEmpty(documentTypeId) || !string.IsNullOrEmpty(dob)))
            {
                command.AddParameter(DocumentNumbers, DbType.String, searchText)
                    .AddParameter(DocumentTypeIds, DbType.String, documentTypeId)
                    .AddParameter(PersonTypeId, DbType.String, personTypeId)
                    .AddParameter(BirthDate, DbType.Date, dob)
                    .AddParameter(VisitorStartDate, DbType.DateTime, startDate)
                    .AddParameter(VisitorEndDate, DbType.DateTime, endDate);
            }
            else if (personTypes.FirstOrDefault() == PersonType.Visitor && searchType == SearchType.VisitorExpectedToday)
            {
                command.AddParameter(PersonTypeId, DbType.String, personTypeId)
                    .AddParameter(VisitorStartDate, DbType.DateTime, startDate);
            }
            else if (personTypes.Count == 1 && personTypes.FirstOrDefault() == PersonType.Crewmember && searchType == SearchType.EmployeeNumber)
            {
                command.AddParameter(EmployeeNo, DbType.String, searchText)
                    .AddParameter(PersonTypeId, DbType.String, personTypeId)
                    .AddParameter(VisitorStartDate, DbType.DateTime, startDate)
                    .AddParameter(VisitorEndDate, DbType.DateTime, endDate);
            }
            else if (searchType == SearchType.LastName)
            {
                command.AddParameter(Name, DbType.String, searchText)
                    .AddParameter(PersonTypeId, DbType.String, personTypeId)
                    .AddParameter(VisitorStartDate, DbType.DateTime, startDate)
                    .AddParameter(VisitorEndDate, DbType.DateTime, endDate);
            }
            else if (searchType == SearchType.Stateroom || searchType == SearchType.StateroomFromStatisticsHistory)
            {
                command.AddParameter(StateRoom, DbType.String, searchText)
                    .AddParameter(PersonTypeId, DbType.String, personTypeId)
                    .AddParameter(VisitorStartDate, DbType.DateTime, startDate)
                    .AddParameter(VisitorEndDate, DbType.DateTime, endDate)
                    .AddParameter(FullStateroomFlag, DbType.Boolean, true);
            }
            else if (searchType == SearchType.Reservation)
            {
                command.AddParameter(ReservationNumbers, DbType.String, searchText)
                    .AddParameter(PersonTypeId, DbType.String, personTypeId);
            }
            else if (searchType == SearchType.PassportNumber)
            {
                command.AddParameter(DocumentNumbers, DbType.String, searchText)
                   .AddParameter(DocumentTypeIds, DbType.String, documentTypeId)
                   .AddParameter(PersonTypeId, DbType.String, personTypeId)
                   .AddParameter(VisitorStartDate, DbType.DateTime, startDate)
                    .AddParameter(VisitorEndDate, DbType.DateTime, endDate);
            }
            else if (searchType == SearchType.PersonId)
            {
                foreach (var persontype in personTypes)
                {
                    if (persontype == PersonType.Guest)
                    {
                        command.AddParameter(GuestIds, DbType.String, personId);
                    }

                    if (persontype == PersonType.Crewmember)
                    {
                        command.AddParameter(CrewmemberIds, DbType.String, personId);
                    }

                    if (persontype == PersonType.Visitor)
                    {
                        command.AddParameter(VisitorIds, DbType.String, personId);
                    }

                    command.AddParameter(PersonTypeId, DbType.Int32, personTypeId);
                }
            }
            else if (searchType == SearchType.BarcodeScanning)
            {
                accessCardNumberScanned = searchText;

                command.AddParameter(AccessCardNumber, DbType.String, searchText)
                    .AddParameter(PersonTypeId, DbType.String, personTypeId)
                    .AddParameter(VisitorStartDate, DbType.DateTime, startDate)
                     .AddParameter(VisitorEndDate, DbType.DateTime, endDate)
                .AddParameter(FullStateroomFlag, DbType.Boolean, true);
            }
            else if (searchType == SearchType.MagneticStripe || searchType == SearchType.RFID)
            {
                accessCardNumberScanned = searchText;

                command.AddParameter(SourceIds, DbType.String, searchText)
                   .AddParameter(PersonTypeId, DbType.String, personTypeId)
                   .AddParameter(VisitorStartDate, DbType.DateTime, startDate)
                     .AddParameter(VisitorEndDate, DbType.DateTime, endDate)
                .AddParameter(FullStateroomFlag, DbType.Boolean, true);
            }

            if (command.Parameters.Count != 0)
            {
                command.AddParameter(ShipId, DbType.Int16, Convert.ToInt16(shipId))
                    .AddParameter(AlertStartDate, DbType.DateTime, shipDateTime)
                    .AddParameter(AlertEndDate, DbType.DateTime, shipDateTime)
                    .AddParameter(PageNumber, DbType.Int32, pageNumber != null && pageNumber.Value != default(int) ? pageNumber : OfflineConstants.DefaultPageNumber)
                    .AddParameter(PageSize, DbType.Int32, maxResults != null && maxResults.Value != default(int) ? maxResults : OfflineConstants.DefaultPageSize)
                    .AddParameter(RecordCount, ParameterDirection.Output, DbType.Int64, 0);

                if (!string.IsNullOrWhiteSpace(activeVoyagesString))
                {
                    command.AddParameter(VoyageIds, DbType.String, activeVoyagesString);
                }

                personData = await this.ExecuteReaderAsync(command, PersonDataMapper.MapPerson);
            }

            var data = personData != null ? personData.Items.FirstOrDefault() : null;

            // Fills IsOnboard status
            if (data != null)
            {
                data.TotalResults = RetrieveRecordCountValue(command);
                CommonDataMethods.FillOnboardStatus(data);
                CommonDataMethods.ManageAlerts(data, accessCardNumberScanned, folioNumber);
                CommonDataMethods.FillCardStatusForVisitor(data);
            }

            return await Task.FromResult(data ?? new Person());
        }