/// <summary>
        /// Retrieves the short name of a partner.
        /// </summary>
        /// <param name="APartnerKey">Partner key</param>
        /// <param name="ASituation">The current report situation</param>
        /// <returns></returns>
        public static String GetPartnerShortName(Int64 APartnerKey, ref TRptSituation ASituation)
        {
            String ReturnValue;
            PPartnerTable table;
            StringCollection fields;

            ReturnValue = "N/A";
            fields = new StringCollection();
            fields.Add(PPartnerTable.GetPartnerShortNameDBName());
            table = PPartnerAccess.LoadByPrimaryKey(APartnerKey, fields, ASituation.GetDatabaseConnection().Transaction);

            if (table.Rows.Count > 0)
            {
                ReturnValue = table[0].PartnerShortName;
            }

            return ReturnValue;
        }
        private String GetCountryName(String ACountryCode, ref TRptSituation ASituation)
        {
            PCountryTable CountryTable;

            CountryTable = PCountryAccess.LoadByPrimaryKey(ACountryCode, ASituation.GetDatabaseConnection().Transaction);

            if (CountryTable.Rows.Count > 0)
            {
                return (String)CountryTable.Rows[0][PCountryTable.GetCountryNameDBName()];
            }

            return "Unknown";
        }
        /// <summary>
        /// Main entry point for calculating the accommodation report.
        /// This must be called for each partner in each conference.
        /// </summary>
        /// <param name="AConferenceKey">Conference Key of the current conference to examine</param>
        /// <param name="AStartDate">Start date of the conference</param>
        /// <param name="AEndDate">End date of the conference</param>
        /// <param name="AFromDate">Start date of the report</param>
        /// <param name="AToDate">End date of the report</param>
        /// <param name="APartnerKey">Partner Key of the current partner to examine</param>
        /// <param name="AReportDetail">Indicator of the details of the report. Possible options: Brief, Full, Detail</param>
        /// <param name="ASituation">The current report situation</param>
        /// <returns></returns>
        public bool CalculatePartnerAccom(long AConferenceKey,
            DateTime AStartDate, DateTime AEndDate,
            DateTime AFromDate, DateTime AToDate,
            long APartnerKey, string AReportDetail,
            ref TRptSituation ASituation)
        {
            PcAttendeeTable AttendeeTable;
            PcAttendeeRow AttendeeRow = null;
            PmShortTermApplicationTable ShortTermTable;
            PmShortTermApplicationTable TmpTable = new PmShortTermApplicationTable();
            PmShortTermApplicationRow TemplateRow;


            TemplateRow = TmpTable.NewRowTyped(false);
            TemplateRow.PartnerKey = APartnerKey;
            TemplateRow.StConfirmedOption = AConferenceKey;

            if (FAccommodationTable == null)
            {
                InitAccomTable(AFromDate, AToDate);
            }

            AttendeeTable = PcAttendeeAccess.LoadByPrimaryKey(AConferenceKey, APartnerKey, ASituation.GetDatabaseConnection().Transaction);

            if (AttendeeTable.Rows.Count > 0)
            {
                AttendeeRow = (PcAttendeeRow)AttendeeTable.Rows[0];
            }

            ShortTermTable = PmShortTermApplicationAccess.LoadUsingTemplate(TemplateRow, ASituation.GetDatabaseConnection().Transaction);

            foreach (DataRow Row in ShortTermTable.Rows)
            {
                AddPartnerToAccom((PmShortTermApplicationRow)Row, AttendeeRow, AStartDate, AEndDate,
                    AFromDate, AToDate, AReportDetail, ref ASituation);
            }

            return true;
        }
        /// <summary>
        /// Retrieves the gender and age of one person.
        /// </summary>
        /// <param name="APartnerKey">Partner key of the person to examine</param>
        /// <param name="AStartDate">Start date of the conference. The age is calculated at the start date</param>
        /// <param name="AGender">Gender of the current person</param>
        /// <param name="AAge">Age of the current person</param>
        /// <param name="ASituation">The current report situation</param>
        /// <returns></returns>
        private bool GetGenderAndAge(long APartnerKey, DateTime AStartDate, out char AGender, out int AAge,
            ref TRptSituation ASituation)
        {
            bool ReturnValue = false;

            AGender = ' ';
            AAge = 0;

            PPersonTable PersonTable;
            PersonTable = PPersonAccess.LoadByPrimaryKey(APartnerKey, ASituation.GetDatabaseConnection().Transaction);

            if (PersonTable.Rows.Count > 0)
            {
                PPersonRow PersonRow = (PPersonRow)PersonTable.Rows[0];
                AGender = PersonRow.Gender.ToCharArray()[0];

                if (!PersonRow.IsDateOfBirthNull())
                {
                    AAge = Calculations.CalculateAge(PersonRow.DateOfBirth.Value, AStartDate);
                }

                ReturnValue = true;
            }

            return ReturnValue;
        }
        /// <summary>
        /// Get the start and end date of the conference.
        /// </summary>
        /// <param name="ASituation">Current report situation. Used to get a database transacion</param>
        /// <param name="AConferenceKey">Unique partner key of the conference</param>
        /// <returns>true if succussful</returns>
        private bool DetermineConferenceDate(ref TRptSituation ASituation, long AConferenceKey)
        {
            PcConferenceTable ConferenceTable;

            ConferenceTable = PcConferenceAccess.LoadByPrimaryKey(AConferenceKey, ASituation.GetDatabaseConnection().Transaction);

            if (ConferenceTable.Rows.Count > 0)
            {
                PcConferenceRow Row = (PcConferenceRow)ConferenceTable.Rows[0];

                if (Row.IsStartNull() || Row.IsEndNull())
                {
                    TLogging.Log("Can't get start or end date of conference: " + AConferenceKey.ToString());
                    return false;
                }

                FConferenceStartDate = Row.Start.Value;
                FConferenceEndDate = Row.End.Value;
                FConferenceDays = FConferenceEndDate.Subtract(FConferenceStartDate).Days + 1;

                FConferenceCurrency = Row.CurrencyCode;
            }

            return true;
        }
示例#6
0
        /// <summary>
        /// Find the best address of a partner
        /// </summary>
        /// <param name="APartnerKey">Partner key</param>
        /// <param name="ASituation">describing the current state of the report generator</param>
        /// <param name="AAddressRow">best address</param>
        /// <returns>true if a best address was found, otherwise false</returns>
        public static bool GetPartnerBestAddressRow(long APartnerKey, TRptSituation ASituation, out PPartnerLocationRow AAddressRow)
        {
            bool FoundBestAddress = false;

            AAddressRow = null;
            PPartnerLocationTable PartnerLocationTable;

            PartnerLocationTable = new PPartnerLocationTable();

            // add special column BestAddress and Icon
            PartnerLocationTable.Columns.Add(new System.Data.DataColumn("BestAddress", typeof(Boolean)));
            PartnerLocationTable.Columns.Add(new System.Data.DataColumn("Icon", typeof(Int32)));

            // find all locations of the partner, put it into a dataset
            PartnerLocationTable = PPartnerLocationAccess.LoadViaPPartner(APartnerKey, ASituation.GetDatabaseConnection().Transaction);

            // uses Ict.Petra.Shared.MPartner.Calculations.pas, DetermineBestAddress
            Calculations.DeterminePartnerLocationsDateStatus(PartnerLocationTable, DateTime.Today);
            Calculations.DetermineBestAddress(PartnerLocationTable);

            foreach (PPartnerLocationRow row in PartnerLocationTable.Rows)
            {
                // find the row with BestAddress = 1
                if (Convert.ToInt32(row["BestAddress"]) == 1)
                {
                    AAddressRow = row;
                    FoundBestAddress = true;
                }
            }

            return FoundBestAddress;
        }
        /// <summary>
        /// Find out about the accommodation
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="APartnerKey"></param>
        /// <returns></returns>
        private bool DetermineAccommodationCosts(ref TRptSituation ASituation, long APartnerKey)
        {
            PcRoomAllocTable RoomAllocTable;
            PcRoomTable RoomTable;

            FPreAccommodationCosts = 0;
            FAccommodationCosts = 0;
            FPostAccommodationCosts = 0;

            String AccommodationString = "";

            RoomAllocTable = PcRoomAllocAccess.LoadViaPcAttendee(FConferenceKey, APartnerKey, ASituation.GetDatabaseConnection().Transaction);

            foreach (PcRoomAllocRow RoomAllocRow in RoomAllocTable.Rows)
            {
                RoomTable = PcRoomAccess.LoadByPrimaryKey(RoomAllocRow.VenueKey, RoomAllocRow.BuildingCode,
                    RoomAllocRow.RoomNumber, ASituation.GetDatabaseConnection().Transaction);

                if (RoomTable.Rows.Count < 1)
                {
                    continue;
                }

                AccommodationString = AccommodationString + "(" + RoomAllocRow.In.Subtract(
                    RoomAllocRow.Out.Value).Days.ToString() + "), ";

                int PreNights = 0;
                int ConferenceNights = 0;
                int PostNights = 0;

                if (RoomAllocRow.In.CompareTo(FAttendeeStartDate) < 0)
                {
                    // calculate Pre conference nights
                    if (RoomAllocRow.Out.Value.CompareTo(FAttendeeStartDate) < 1)
                    {
                        PreNights = RoomAllocRow.Out.Value.Subtract(RoomAllocRow.In).Days;
                    }
                    else
                    {
                        PreNights = FAttendeeStartDate.Subtract(RoomAllocRow.In).Days;
                    }
                }

                if ((RoomAllocRow.In.CompareTo(FAttendeeEndDate) < 0)
                    || (RoomAllocRow.Out.Value.CompareTo(FAttendeeStartDate) > 0))
                {
                    // calculate conference nights
                    ConferenceNights = FAttendeeEndDate.Subtract(FAttendeeStartDate).Days;

                    // subtract if there are days left out at beginning of conference
                    if (RoomAllocRow.In.CompareTo(FAttendeeStartDate) > 0)
                    {
                        ConferenceNights = ConferenceNights - RoomAllocRow.In.Subtract(FAttendeeStartDate).Days;
                    }

                    //subtract if there are days left out at end of conference
                    if (RoomAllocRow.Out.Value.CompareTo(FAttendeeEndDate) < 0)
                    {
                        ConferenceNights = ConferenceNights - FAttendeeEndDate.Subtract(RoomAllocRow.Out.Value).Days;
                    }

                    if (RoomAllocRow.Out.Value.CompareTo(FAttendeeEndDate) > 0)
                    {
                        // calculate post conference nights
                        if (RoomAllocRow.In.CompareTo(FAttendeeEndDate) > 0)
                        {
                            PostNights = RoomAllocRow.Out.Value.Subtract(RoomAllocRow.In).Days;
                        }
                        else
                        {
                            PostNights = RoomAllocRow.Out.Value.Subtract(FAttendeeEndDate).Days;
                        }

                        FConferenceFlags = FConferenceFlags + "T";
                    }

                    decimal BedCharge = (decimal)RoomTable.Rows[0][PcRoomTable.GetBedChargeDBName()];

                    FPreAccommodationCosts = FPreAccommodationCosts + PreNights * BedCharge;
                    FAccommodationCosts = FAccommodationCosts + ConferenceNights * BedCharge;
                    FPostAccommodationCosts = FPostAccommodationCosts + PostNights * BedCharge;
                }
            }

            return true;
        }
        /// <summary>
        /// Determine the conference cost charges. Either per single day or per conference
        /// </summary>
        /// <param name="ASituation">Current report situation. Used to get a database transacion</param>
        /// <param name="AConferenceKey">Unique partner key of the conference</param>
        /// <returns>true</returns>
        private bool DetermineConferenceCostCharges(ref TRptSituation ASituation, long AConferenceKey)
        {
            PcConferenceCostTable ConferenceCostTable;

            ConferenceCostTable = PcConferenceCostAccess.LoadByPrimaryKey(AConferenceKey, 1, ASituation.GetDatabaseConnection().Transaction);

            if (ConferenceCostTable.Rows.Count > 0)
            {
                FConferenceDayRate = (decimal)ConferenceCostTable.Rows[0][PcConferenceCostTable.GetChargeDBName()];
            }
            else
            {
                FConferenceDayRate = 0;
            }

            return true;
        }
        /// <summary>
        /// Find any applicable outreach supplement and puts them into FSupportCost member
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="AOutreachType"></param>
        /// <param name="ACongressCode"></param>
        /// <param name="AChildDiscount"></param>
        /// <returns></returns>
        private bool DetermineOutreachSupplements(ref TRptSituation ASituation, String AOutreachType,
            String ACongressCode, decimal AChildDiscount)
        {
            PcSupplementTable SupplementTable;

            FSupportCost = 0;

            SupplementTable = PcSupplementAccess.LoadByPrimaryKey(FConferenceKey, AOutreachType, ASituation.GetDatabaseConnection().Transaction);

            if (SupplementTable.Rows.Count > 0)
            {
                PcSupplementRow Row = (PcSupplementRow)SupplementTable.Rows[0];

                FSupportCost = Row.Supplement;

                if (Row.ApplyDiscounts)
                {
                    FSupportCost = FSupportCost * (100 - AChildDiscount) / 100;

                    if (FIsCongressRole)
                    {
                        FSupportCost = FSupportCost * (100 - FRoleDiscountConferenceConference) / 100;
                    }

                    if (ACongressCode == "VOL")
                    {
                        FSupportCost = FSupportCost * (100 - FVolunteerDiscountConferenceConference) / 100;
                    }
                }
            }

            return true;
        }
        /// <summary>
        /// Find any extra costs for this attendee
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="APartnerKey"></param>
        /// <returns></returns>
        private bool DetermineExtraCosts(ref TRptSituation ASituation, long APartnerKey)
        {
            FExtraCost = 0;

            PcExtraCostTable ExtraCostTable;

            ExtraCostTable = PcExtraCostAccess.LoadViaPcAttendee(FConferenceKey, APartnerKey, ASituation.GetDatabaseConnection().Transaction);

            foreach (PcExtraCostRow Row in ExtraCostTable.Rows)
            {
                FExtraCost = FExtraCost + Row.CostAmount;
            }

            return true;
        }
        /// <summary>
        /// Congress option within a main congress which is charged at fixed rate
        /// Particularly applicable to De Bron when Staff and Ladies occur
        /// The conference rate and arrival/departure need to be adjusted
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="AOutreachOption">The unit key of the outreach</param>
        /// <param name="AShortTermerRow">The row of the attendee from the personnel short termer table</param>
        /// <returns></returns>
        private bool GetCongressOptionRates(ref TRptSituation ASituation, long AOutreachOption,
            ref PmShortTermApplicationRow AShortTermerRow)
        {
            PPartnerLocationTable PartnerLocationTable;

            PartnerLocationTable = PPartnerLocationAccess.LoadViaPPartner(AOutreachOption, ASituation.GetDatabaseConnection().Transaction);

            if (PartnerLocationTable.Rows.Count < 1)
            {
                return false;
            }

            PPartnerLocationRow PartnerLocationRow = (PPartnerLocationRow)PartnerLocationTable.Rows[0];

            FAttendeeStartDate = PartnerLocationRow.DateEffective.Value;
            FAttendeeEndDate = PartnerLocationRow.DateGoodUntil.Value;

            // Update arrival and departure dates if none have been entered yet,
            // either in the application travel details or the actual arrival at the conference
            if (AShortTermerRow.IsArrivalNull())
            {
                AShortTermerRow.Arrival = FAttendeeStartDate;
            }

            if (AShortTermerRow.IsDepartureNull())
            {
                AShortTermerRow.Departure = FAttendeeEndDate;
            }

            PcConferenceCostTable ConferenceCostTable;

            ConferenceCostTable = PcConferenceCostAccess.LoadByPrimaryKey(AOutreachOption,
                FAttendeeDays, ASituation.GetDatabaseConnection().Transaction);

            if (ConferenceCostTable.Rows.Count > 0)
            {
                FConferenceRate = (decimal)ConferenceCostTable.Rows[0][PcConferenceCostTable.GetChargeDBName()];
            }

            return true;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="AShortTermerRow">The row of the attendee from the personnel short termer table</param>
        /// <param name="AOutreachType"></param>
        /// <returns></returns>
        private bool DetermineConferenceBasicCharges(ref TRptSituation ASituation, ref PmShortTermApplicationRow AShortTermerRow,
            String AOutreachType)
        {
            FAttendeeStartDate = FConferenceStartDate;
            FAttendeeEndDate = FConferenceEndDate;

            PcConferenceCostTable ConferenceCostTable;

            ConferenceCostTable = PcConferenceCostAccess.LoadByPrimaryKey(FConferenceKey, FAttendeeDays,
                ASituation.GetDatabaseConnection().Transaction);

            if (ConferenceCostTable.Rows.Count > 0)
            {
                FConferenceRate = ((PcConferenceCostRow)ConferenceCostTable.Rows[0]).Charge;
            }
            else
            {
                FConferenceRate = 0;
            }

            //Find the outreach length for this individual
            // use the confirmed option code (the last two characters should give the number of days
            FAttendeeDays = 0;
            long OutreachOption = 0;
            FIsCongressOnly = false;

            FAttendeeDays = GetConferenceLengthFromConferenceCode(AShortTermerRow.ConfirmedOptionCode);

            if (FAttendeeDays > 0)
            {
                OutreachOption = AShortTermerRow.StConfirmedOption;
            }

            if (FAttendeeDays == 0)
            {
                // None of the options has given us a valid number of days so start with the conference length
                FAttendeeDays = FConferenceDays;
                OutreachOption = FConferenceKey;
            }

            if (FIsCongressOnly
                && (AOutreachType != "CNGRSS"))
            {
                GetCongressOptionRates(ref ASituation, OutreachOption, ref AShortTermerRow);
            }

            return true;
        }
        /// <summary>
        /// Adds one partner to the report table
        /// </summary>
        /// <param name="APartnerKey">The partner key of the current partner</param>
        /// <param name="AGender">Gender of the current partner</param>
        /// <param name="ALanguageCode">The mother language of the current partner</param>
        /// <param name="ASituation">The current report situation</param>
        /// <returns></returns>
        public bool CalculateNationalities(long APartnerKey, String AGender, String ALanguageCode, ref TRptSituation ASituation)
        {
            TCacheable CommonCacheable = new TCacheable();

            StringCollection PassportColumns = StringHelper.StrSplit(
                PmPassportDetailsTable.GetDateOfIssueDBName() + "," +
                PmPassportDetailsTable.GetDateOfExpirationDBName() + "," +
                PmPassportDetailsTable.GetPassportNationalityCodeDBName() + "," +
                PmPassportDetailsTable.GetMainPassportDBName(), ",");

            PmPassportDetailsTable PassportDetailsDT = PmPassportDetailsAccess.LoadViaPPerson(APartnerKey,
                PassportColumns, ASituation.GetDatabaseConnection().Transaction, null, 0, 0);

            string Nationalities = Ict.Petra.Shared.MPersonnel.Calculations.DeterminePersonsNationalities(
                @CommonCacheable.GetCacheableTable, PassportDetailsDT);

            string[] NationalitiesArray = Nationalities.Split(',');

            bool FoundNationality = false;
            List <string>PreviousNationalities = new List <string>();

            foreach (string Nationality in NationalitiesArray)
            {
                string SingleNationality = Nationality;

                // remove all characters other than the country name
                SingleNationality = Nationality.TrimStart(' ');

                if (SingleNationality.EndsWith(Ict.Petra.Shared.MPersonnel.Calculations.PASSPORT_EXPIRED))
                {
                    SingleNationality = SingleNationality.Remove(SingleNationality.Length -
                        Ict.Petra.Shared.MPersonnel.Calculations.PASSPORT_EXPIRED.Length);
                }
                else if (SingleNationality.EndsWith(Ict.Petra.Shared.MPersonnel.Calculations.PASSPORTMAIN_EXPIRED))
                {
                    SingleNationality = SingleNationality.Remove(SingleNationality.Length -
                        Ict.Petra.Shared.MPersonnel.Calculations.PASSPORTMAIN_EXPIRED.Length);
                }

                if (SingleNationality == "")
                {
                    SingleNationality = Catalog.GetString("UNKNOWN");
                }

                // make sure that this nationality has not already been processed for this partner
                if (!PreviousNationalities.Contains(SingleNationality))
                {
                    for (int Counter = 0; Counter < FNationalityTable.Rows.Count; ++Counter)
                    {
                        if (((String)FNationalityTable.Rows[Counter][COLUMNNATIONALITYCODE] == SingleNationality))
                        {
                            FoundNationality = true;
                            AddAttendeeToTable(Counter, AGender, SingleNationality, ALanguageCode);
                        }
                    }

                    if (!FoundNationality)
                    {
                        AddAttendeeToTable(-1, AGender, SingleNationality, ALanguageCode);
                    }

                    PreviousNationalities.Add(SingleNationality);
                }
            }

            return true;
        }
        /// <summary>
        /// Add the extra cost lines for the attendees to the report
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="AConferenceKey"></param>
        /// <param name="APartnerKey"></param>
        /// <param name="AMasterRow"></param>
        /// <param name="ALevel"></param>
        /// <param name="AChildRow"></param>
        /// <returns></returns>
        private int AddExtraCostLines(ref TRptSituation ASituation, long AConferenceKey, long APartnerKey,
            int AMasterRow, int ALevel, int AChildRow)
        {
            int NumLinesAdded = 0;

            PcExtraCostTable ExtraCostTable;

            ExtraCostTable = PcExtraCostAccess.LoadViaPcAttendee(AConferenceKey, APartnerKey, ASituation.GetDatabaseConnection().Transaction);

            TVariant[] Header = new TVariant[FMaxNumColumns];
            TVariant[] Description =
            {
                new TVariant(), new TVariant()
            };
            TVariant[] Columns = new TVariant[FMaxNumColumns];

            foreach (PcExtraCostRow ExtraCostRow in ExtraCostTable.Rows)
            {
                for (int Counter = 0; Counter < FMaxNumColumns; ++Counter)
                {
                    Columns[Counter] = new TVariant(" ");
                    Header[Counter] = new TVariant();
                }

                Description[0] = new TVariant();
                Description[1] = new TVariant();

                if (NumLinesAdded == 0)
                {
                    Columns[0] = new TVariant("Extra Cost:");
                }

                Columns[1] = new TVariant(ExtraCostRow.CostTypeCode);
                // we need one space after the amount. Otherwise it's not correctly printed in the report
                Columns[2] = new TVariant(StringHelper.FormatUsingCurrencyCode(ExtraCostRow.CostAmount, FConferenceCurrency));
                Columns[3] = new TVariant(ExtraCostRow.Comment);

                ASituation.GetResults().AddRow(AMasterRow, AChildRow, true, ALevel, "", "", false,
                    Header, Description, Columns);
                ASituation.GetResults().UpdateRow(AMasterRow, AChildRow++, Columns);

                ++NumLinesAdded;
            }

            return NumLinesAdded;
        }
        /// <summary>
        /// Returns the room allocation for this attendee.
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="APartnerKey"></param>
        /// <param name="AFromDate"></param>
        /// <param name="AToDate"></param>
        /// <returns></returns>
        private int GetRoomAllocatedNightsBetween(ref TRptSituation ASituation, long APartnerKey,
            DateTime AFromDate, DateTime AToDate)
        {
            PcRoomAllocTable RoomAllocTable = new PcRoomAllocTable();
            PcRoomAllocRow TemplateRow = (PcRoomAllocRow)RoomAllocTable.NewRow();

            TemplateRow.PartnerKey = APartnerKey;

            int Nights = 0;

            RoomAllocTable = PcRoomAllocAccess.LoadUsingTemplate(TemplateRow, ASituation.GetDatabaseConnection().Transaction);

            foreach (PcRoomAllocRow RoomAllocRow in RoomAllocTable.Rows)
            {
                if ((RoomAllocRow.Out.Value.CompareTo(AFromDate) < 1)
                    || (RoomAllocRow.In.CompareTo(AToDate) > 0))
                {
                    continue;
                }

                if (RoomAllocRow.In.CompareTo(AFromDate) < 0)
                {
                    RoomAllocRow.In = AFromDate;
                }

                if (RoomAllocRow.Out.Value.CompareTo(AToDate) > 0)
                {
                    RoomAllocRow.Out = AToDate;
                }

                Nights = Nights + RoomAllocRow.Out.Value.Subtract(RoomAllocRow.In).Days;
            }

            if (Nights <= 0)
            {
                //If no accommodation allocated, charge for full period
                Nights = AToDate.Subtract(AFromDate).Days;
            }

            return Nights;
        }
        /// <summary>
        /// Evaluates if a partner has a receiving field assigned.
        /// If there is a receiving field the FInvisibleRowCounter is increased because in the Receiving
        /// Field Report this partner is not displayed in the "NO FIELD" list.
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="APartnerKey"></param>
        /// <param name="ATargetFieldList"></param>
        /// <returns>True if there is a receiving field. Otherwise false.</returns>
        public bool HasAttendeeReceivingField(ref TRptSituation ASituation, long APartnerKey,
            String ATargetFieldList)
        {
            PPersonTable PersonTable;
            bool ReturnValue = false;
            PmStaffDataTable StaffDataTable = new PmStaffDataTable();
            PmStaffDataRow TemplateRow = (PmStaffDataRow)StaffDataTable.NewRow();

            TemplateRow.PartnerKey = APartnerKey;

            // 1. check the staff data if this partner has the same target / receiving field
            StaffDataTable = PmStaffDataAccess.LoadUsingTemplate(TemplateRow, ASituation.GetDatabaseConnection().Transaction);

            foreach (PmStaffDataRow StaffDataRow in StaffDataTable.Rows)
            {
                if ((StaffDataRow.StartOfCommitment < DateTime.Today)
                    && (StaffDataRow.IsEndOfCommitmentNull()
                        || (!StaffDataRow.IsEndOfCommitmentNull()
                            && (StaffDataRow.EndOfCommitment > DateTime.Today)))
                    && !StaffDataRow.IsReceivingFieldNull())
                {
                    if (ATargetFieldList.Contains(StaffDataRow.ReceivingField.ToString()))
                    {
                        ReturnValue = true;
                    }
                }
            }

            // 2. check the person gift destination
            PersonTable = PPersonAccess.LoadByPrimaryKey(APartnerKey, ASituation.GetDatabaseConnection().Transaction);

            if ((ReturnValue == false)
                && (PersonTable.Rows.Count > 0))
            {
                PPersonRow PersonRow = (PPersonRow)PersonTable.Rows[0];

                PPartnerGiftDestinationTable GiftDestinationTable =
                    PPartnerGiftDestinationAccess.LoadViaPPartner(PersonRow.FamilyKey, ASituation.GetDatabaseConnection().Transaction);

                if (GiftDestinationTable.Rows.Count > 0)
                {
                    foreach (PPartnerGiftDestinationRow Row in GiftDestinationTable.Rows)
                    {
                        // check if the gift destination is currently active
                        if ((Row.DateEffective <= DateTime.Today)
                            && (Row.IsDateExpiresNull() || ((Row.DateExpires >= DateTime.Today) && (Row.DateExpires != Row.DateEffective))))
                        {
                            ReturnValue = true;
                        }
                    }
                }
            }

            if (ReturnValue == true)
            {
                // Hide the line from the output
                FInvisibleRowCounter++;
                ASituation.GetParameters().Add("DONTDISPLAYROW", new TVariant(true), -1, -1, null, null, ReportingConsts.CALCULATIONPARAMETERS);
            }
            else
            {
                ASituation.GetParameters().Add("DONTDISPLAYROW", new TVariant(false), -1, -1, null, null, ReportingConsts.CALCULATIONPARAMETERS);
            }

            return ReturnValue;
        }
        /// <summary>
        /// Returns the cost for the outreach. There might be different charges of the outreach
        /// depending how long the attendee takes part.
        /// </summary>
        /// <param name="ASituation"></param>
        /// <returns></returns>
        private decimal GetOutreachCost(ref TRptSituation ASituation)
        {
            PcConferenceCostTable ConferenceCostTable;

            ConferenceCostTable = PcConferenceCostAccess.LoadViaPcConference(FConferenceKey, ASituation.GetDatabaseConnection().Transaction);

            foreach (PcConferenceCostRow Row in
                     ConferenceCostTable.Select("", PcConferenceCostTable.GetOptionDaysDBName() + " ASC"))
            {
                if (Row.OptionDays >= FAttendeeDays)
                {
                    return Row.Charge;
                }
            }

            return 0;
        }
        /// <summary>
        /// Determine the conference cost type. Either per day, per night, by outreach.
        /// </summary>
        /// <param name="ASituation">Current report situation. Used to get a database transacion</param>
        /// <param name="AConferenceKey">Unique partner key of the conference</param>
        /// <returns>true</returns>
        private bool DetermineConferenceCostType(ref TRptSituation ASituation, long AConferenceKey)
        {
            PcConferenceOptionTable ConferenceOptionTable;

            ConferenceOptionTable = PcConferenceOptionAccess.LoadViaPcConference(AConferenceKey, ASituation.GetDatabaseConnection().Transaction);

            FConferenceCostType = TConferenceCostTypeEnum.cctPerOutreach;

            foreach (DataRow Row in ConferenceOptionTable.Rows)
            {
                if ((String)Row[PcConferenceOptionTable.GetOptionTypeCodeDBName()] == "COST_PER_DAY")
                {
                    FConferenceCostType = TConferenceCostTypeEnum.cctPerDay;
                    break;
                }
                else if ((String)Row[PcConferenceOptionTable.GetOptionTypeCodeDBName()] == "COST_PER_NIGHT")
                {
                    FConferenceCostType = TConferenceCostTypeEnum.cctPerNight;
                }
            }

            return true;
        }
        /// <summary>
        /// Determines if the attendee has a special role on the conference
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="ACongressCode"></param>
        /// <returns></returns>
        private bool IsAttendeeARole(ref TRptSituation ASituation, String ACongressCode)
        {
            bool ReturnValue = false;

            PtCongressCodeTable CongressCodeTable;

            CongressCodeTable = PtCongressCodeAccess.LoadByPrimaryKey(ACongressCode, ASituation.GetDatabaseConnection().Transaction);

            if (CongressCodeTable.Rows.Count > 0)
            {
                ReturnValue = (bool)CongressCodeTable.Rows[0][PtCongressCodeTable.GetDiscountedDBName()];
            }

            return ReturnValue;
        }
        /// <summary>
        /// Gets the different discounts for this conference
        /// (Volunteer, Omer, Pre, Post)
        /// </summary>
        /// <param name="ASituation">Current report situation. Used to get a database transacion</param>
        /// <param name="AConferenceKey">Unique partner key of the conference</param>
        /// <returns>true if succussful</returns>
        private bool DetermineConferenceDiscounts(ref TRptSituation ASituation, long AConferenceKey)
        {
            PcDiscountTable DiscountTable;

            FParticipantDiscountAccommodationPre = 0;
            FParticipantDiscountConferencePre = 0;
            FRoleDiscountAccommodationConference = 0;
            FRoleDiscountAccommodationPre = 0;
            FRoleDiscountConferenceConference = 0;
            FRoleDiscountConferencePost = 0;
            FRoleDiscountConferencePre = 0;
            FVolunteerDiscountAccommodationConference = 0;
            FVolunteerDiscountAccommodationPre = 0;
            FVolunteerDiscountConferenceConference = 0;
            FVolunteerDiscountConferencePre = 0;

            // this does not seem to be used anywhere, see Mantis #412
            // FRoleDiscountAccommodationPost = 0;

            DiscountTable = PcDiscountAccess.LoadViaPcConference(AConferenceKey, ASituation.GetDatabaseConnection().Transaction);

            foreach (PcDiscountRow Row in DiscountTable.Rows)
            {
                if (Row.DiscountCriteriaCode == "ROLE")
                {
                    if (Row.CostTypeCode == "CONFERENCE")
                    {
                        if (Row.Validity == "PRE")
                        {
                            FRoleDiscountConferencePre = Row.Discount;
                        }
                        else if (Row.Validity == "CONF")
                        {
                            FRoleDiscountConferenceConference = Row.Discount;
                        }
                        else if (Row.Validity == "POST")
                        {
                            FRoleDiscountConferencePost = Row.Discount;
                        }
                    }
                    else if (Row.CostTypeCode == "ACCOMMODATION")
                    {
                        if (Row.Validity == "PRE")
                        {
                            FRoleDiscountAccommodationPre = Row.Discount;
                        }
                        else if (Row.Validity == "CONF")
                        {
                            FRoleDiscountAccommodationConference = Row.Discount;
                        }
                        else if (Row.Validity == "POST")
                        {
                            // this does not seem to be used anywhere, see Mantis #412
                            // FRoleDiscountAccommodationPost = Row.Discount;
                        }
                    }
                }
                else if (Row.DiscountCriteriaCode == "VOL")
                {
                    if (Row.CostTypeCode == "CONFERENCE")
                    {
                        if (Row.Validity == "PRE")
                        {
                            FVolunteerDiscountConferencePre = Row.Discount;
                        }
                        else if (Row.Validity == "CONF")
                        {
                            FVolunteerDiscountConferenceConference = Row.Discount;
                        }
                    }
                    else if (Row.CostTypeCode == "ACCOMMODATION")
                    {
                        if (Row.Validity == "PRE")
                        {
                            FVolunteerDiscountAccommodationPre = Row.Discount;
                        }
                        else if (Row.Validity == "CONF")
                        {
                            FVolunteerDiscountAccommodationConference = Row.Discount;
                        }
                    }
                }
                else if (Row.DiscountCriteriaCode == "OTHER")
                {
                    if (Row.CostTypeCode == "CONFERENCE")
                    {
                        if (Row.Validity == "PRE")
                        {
                            FParticipantDiscountConferencePre = Row.Discount;
                        }
                    }
                    else if (Row.CostTypeCode == "ACCOMMODATION")
                    {
                        if (Row.Validity == "PRE")
                        {
                            FParticipantDiscountAccommodationPre = Row.Discount;
                        }
                    }
                }
            }

            return true;
        }
        /// <summary>
        /// Returns the early or late charges of the attendee
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="ARegistrationDate"></param>
        /// <param name="AShortTermerRow">The row of the attendee from the personnel short termer table</param>
        /// <param name="EarlyPercent"></param>
        /// <param name="EarlyAmount"></param>
        /// <param name="LatePercent"></param>
        /// <param name="LateAmount"></param>
        private void GetEarlyLateCharges(ref TRptSituation ASituation, DateTime ARegistrationDate,
            PmShortTermApplicationRow AShortTermerRow, out int EarlyPercent,
            out decimal EarlyAmount, out int LatePercent, out decimal LateAmount)
        {
            EarlyAmount = 0;
            EarlyPercent = 0;
            LateAmount = 0;
            LatePercent = 0;

            PcEarlyLateTable EarlyLateTable;

            EarlyLateTable = PcEarlyLateAccess.LoadViaPcConference(FConferenceKey, ASituation.GetDatabaseConnection().Transaction);

            foreach (PcEarlyLateRow Row in EarlyLateTable.Rows)
            {
                if ((Row.Type)
                    && (ARegistrationDate.CompareTo(Row.Applicable) <= 0)
                    && ((AShortTermerRow.Departure.Value.Subtract(AShortTermerRow.Arrival.Value).Days * 2) > FConferenceDays))
                {
                    // Early
                    if (Row.AmountPercent)
                    {
                        EarlyAmount = Row.Amount;
                    }
                    else
                    {
                        EarlyPercent = Row.Percent;
                    }

                    // One record only
                    FConferenceFlags = FConferenceFlags + "E";
                    break;
                }

                if ((!Row.Type)
                    && (ARegistrationDate.CompareTo(Row.Applicable) >= 0))
                {
                    // Late
                    if (Row.AmountPercent)
                    {
                        LateAmount = Row.Amount;
                    }
                    else
                    {
                        LatePercent = Row.Percent;
                    }

                    // One record only
                    FConferenceFlags = FConferenceFlags + "L";
                    break;
                }
            }
        }
示例#22
0
        /// <summary>
        /// Get the passport details and restores them as parameters.
        /// If there is a passport with the MainPassport flag set, then use this passport.
        /// Otherwise use the most recent passport which has a passport number.
        /// </summary>
        /// <param name="APartnerKey">Partner key</param>
        /// <param name="ASituation">A current Report Situation</param>
        /// <returns>true if one passport was found, otherwise false</returns>
        public static PmPassportDetailsRow GetLatestPassport(Int64 APartnerKey, TRptSituation ASituation)
        {
            PmPassportDetailsTable PassportTable = null;
            PmPassportDetailsRow ResultPassportRow = null;

            StringCollection PassportCollumns = new StringCollection();
            StringCollection OrderList = new StringCollection();

            PassportCollumns.Add(PmPassportDetailsTable.GetPassportNationalityCodeDBName());
            PassportCollumns.Add(PmPassportDetailsTable.GetPassportNumberDBName());
            PassportCollumns.Add(PmPassportDetailsTable.GetDateOfExpirationDBName());
            PassportCollumns.Add(PmPassportDetailsTable.GetFullPassportNameDBName());
            OrderList.Add("ORDER BY " + PmPassportDetailsTable.GetDateOfExpirationDBName() + " DESC");

            PassportTable = PmPassportDetailsAccess.LoadViaPPerson(APartnerKey,
                PassportCollumns, ASituation.GetDatabaseConnection().Transaction,
                OrderList, 0, 0);

            // Look for MainPassport flag
            foreach (PmPassportDetailsRow Row in PassportTable.Rows)
            {
                if (!Row.IsMainPassportNull()
                    && Row.MainPassport)
                {
                    ResultPassportRow = Row;
                    break;
                }
            }

            // Look for the most recent passport with a passport number
            if (ResultPassportRow == null)
            {
                foreach (PmPassportDetailsRow Row in PassportTable.Rows)
                {
                    if (Row.PassportNumber.Length > 0)
                    {
                        ResultPassportRow = Row;
                        break;
                    }
                }
            }

            return ResultPassportRow;
        }
        /// <summary>
        /// Determines if the attendee is an omer.
        /// </summary>
        /// <param name="APartnerKey"></param>
        /// <param name="ASituation"></param>
        private void CheckPartnerTypeCode(long APartnerKey, ref TRptSituation ASituation)
        {
            PPartnerTypeTable PartnerTypeTable;

            PartnerTypeTable = PPartnerTypeAccess.LoadViaPPartner(APartnerKey, ASituation.GetDatabaseConnection().Transaction);

            foreach (PPartnerTypeRow Row in PartnerTypeTable.Rows)
            {
                // TODO ORGANIZATION SPECIFIC TypeCode
                if (Row.TypeCode.StartsWith("OMER"))
                {
                    FConferenceFlags = FConferenceFlags + "O";
                    return;
                }
            }
        }
        /// <summary>
        /// Adds the dates of one partner to the accommodation report
        /// </summary>
        /// <param name="AShortTermRow">The short term application row of the current partner</param>
        /// <param name="AAttendeeRow">The attendee row of the current partner</param>
        /// <param name="AStartDate">Start date of the conference</param>
        /// <param name="AEndDate">End date of the conference</param>
        /// <param name="AFromDate">Start date of the report</param>
        /// <param name="AToDate">End date of the report</param>
        /// <param name="AReportDetail">Indicator of the details of the report. Possible options: Brief, Full, Detail</param>
        /// <param name="ASituation">The current report situation</param>
        /// <returns></returns>
        private bool AddPartnerToAccom(PmShortTermApplicationRow AShortTermRow,
            PcAttendeeRow AAttendeeRow,
            DateTime AStartDate, DateTime AEndDate,
            DateTime AFromDate, DateTime AToDate,
            string AReportDetail, ref TRptSituation ASituation)
        {
            // if we have an actual arrival and departure date from the attendee row use it.
            if (AAttendeeRow != null)
            {
                if (!AAttendeeRow.IsActualArrNull())
                {
                    AShortTermRow.Arrival = AAttendeeRow.ActualArr;
                }

                if (!AAttendeeRow.IsActualDepNull())
                {
                    AShortTermRow.Departure = AAttendeeRow.ActualDep;
                }
            }

            if (AShortTermRow.IsArrivalNull())
            {
                AShortTermRow.Arrival = AStartDate;
            }

            if (AShortTermRow.IsDepartureNull())
            {
                AShortTermRow.Departure = AEndDate;
            }

            if ((AShortTermRow.Arrival <= AToDate)
                && (AShortTermRow.Departure >= AFromDate))
            {
                // this short term application covers the dates we examine

                PcRoomAllocTable TempTable = new PcRoomAllocTable();
                PcRoomAllocTable RoomAllocTable;
                PcRoomAllocRow TemplateRow = TempTable.NewRowTyped(false);
                TemplateRow.PartnerKey = AShortTermRow.PartnerKey;
                TemplateRow.ConferenceKey = AShortTermRow.StConfirmedOption;

                RoomAllocTable = PcRoomAllocAccess.LoadUsingTemplate(TemplateRow, ASituation.GetDatabaseConnection().Transaction);

                char Gender;
                int Age;
                string PartnerName;
                GetGenderAndAge(AShortTermRow.PartnerKey, AStartDate, out Gender, out Age, ref ASituation);
                PartnerName = TAccommodationReportCalculation.GetPartnerShortName(AShortTermRow.PartnerKey, ref ASituation);

                foreach (DataRow Row in RoomAllocTable.Rows)
                {
                    CheckRoomAllocation((PcRoomAllocRow)Row, AShortTermRow, AFromDate, AToDate,
                        AReportDetail, Gender, Age, PartnerName, ref ASituation);
                }

                if (RoomAllocTable.Rows.Count == 0)
                {
                    AddNoRoomBooking(AShortTermRow, AFromDate, AToDate, Gender, PartnerName);
                }
            }

            return true;
        }
        /// <summary>
        /// Calculates the financial details of one attendee and stores the value in FResultTable
        /// </summary>
        /// <param name="ASituation"></param>
        /// <param name="AAge"></param>
        /// <param name="APartnerKey"></param>
        /// <param name="AApplicationKey"></param>
        /// <param name="ARegistrationOfficeKey"></param>
        /// <param name="AHomeOfficeKey"></param>
        /// <param name="AOutreachType"></param>
        /// <param name="ARegistrationDate"></param>
        /// <param name="AFinanceDetails">Returns the conference costs</param>
        /// <param name="AAccommodation">Returns the accommodation costs</param>
        /// <returns></returns>
        public bool CalculateOneAttendeeFieldCost(ref TRptSituation ASituation, int AAge, long APartnerKey,
            int AApplicationKey, long ARegistrationOfficeKey,
            long AHomeOfficeKey,
            String AOutreachType, DateTime ARegistrationDate,
            out String AFinanceDetails, out String AAccommodation)
        {
            FCongressCosts = 0;
            FExtraCost = 0;
            FSupportCost = 0;
            FPreConferenceCosts = 0;
            FPostConferenceCosts = 0;
            FAccommodationCosts = 0;
            FPreAccommodationCosts = 0;
            FPostAccommodationCosts = 0;

            FIsCongressVolunteer = false;
            FIsCongressRole = false;
            FIsCongressOnly = false;
            FIsOutreachOnly = false;

            decimal ChildDiscount;
            decimal ChildDiscountAccommodation;

            bool InPercent;
            bool GeneralDiscountApplied = false;

            AFinanceDetails = "0.00";
            AAccommodation = "0.00";
            FConferenceFlags = " ";

            if (AAge < 0)
            {
                AAge = 0;
            }

            CheckPartnerTypeCode(APartnerKey, ref ASituation);

            PmShortTermApplicationTable ShortTermerTable;
            ShortTermerTable = PmShortTermApplicationAccess.LoadByPrimaryKey(APartnerKey, AApplicationKey,
                ARegistrationOfficeKey, ASituation.GetDatabaseConnection().Transaction);

            if (ShortTermerTable.Rows.Count < 1)
            {
                return false;
            }

            PmShortTermApplicationRow ShortTermerRow = (PmShortTermApplicationRow)ShortTermerTable.Rows[0];

            if (ShortTermerRow.StPreCongressCode == "")
            {
                ShortTermerRow.StPreCongressCode = ShortTermerRow.StCongressCode;
            }

            DateTime ArrivalDate = FConferenceStartDate;
            DateTime DepartureDate = FConferenceEndDate;

            if (!ShortTermerRow.IsArrivalNull())
            {
                ArrivalDate = ShortTermerRow.Arrival.Value;
            }

            if (!ShortTermerRow.IsDepartureNull())
            {
                DepartureDate = ShortTermerRow.Departure.Value;
            }

            FAttendeeDays = DepartureDate.Subtract(ArrivalDate).Days + 1;

            TAccommodationReportCalculation.GetChildDiscount(AAge, FConferenceKey, "CONFERENCE", out ChildDiscount, out InPercent, ref ASituation);

            if (!InPercent)
            {
                ChildDiscount = 0;
            }

            TAccommodationReportCalculation.GetChildDiscount(AAge,
                FConferenceKey,
                "ACCOMMODATION",
                out ChildDiscountAccommodation,
                out InPercent,
                ref ASituation);

            if (!InPercent)
            {
                ChildDiscountAccommodation = 0;
            }

            if ((ChildDiscountAccommodation > 0)
                || (ChildDiscount > 0))
            {
                FConferenceFlags = FConferenceFlags + "C";
            }

            decimal UsedConferenceDiscountPre = FParticipantDiscountConferencePre;
            decimal UsedAccommodationDiscountPre = FParticipantDiscountAccommodationPre;

            if (IsAttendeeARole(ref ASituation, ShortTermerRow.StCongressCode))
            {
                UsedConferenceDiscountPre = FRoleDiscountConferencePre;
                UsedAccommodationDiscountPre = FRoleDiscountAccommodationPre;
                FIsCongressRole = true;

                if (FRoleDiscountConferencePre != 0)
                {
                    GeneralDiscountApplied = true;
                }
            }

            DetermineConferenceBasicCharges(ref ASituation, ref ShortTermerRow, AOutreachType);

            DetermineOutreachSupplements(ref ASituation, AOutreachType, ShortTermerRow.StCongressCode, ChildDiscount);

            DetermineExtraCosts(ref ASituation, ShortTermerRow.PartnerKey);

            DetermineAccommodationCosts(ref ASituation, ShortTermerRow.PartnerKey);

            // ************************************************************
            // ************************************************************
            // * Now do the calculations
            // ************************************************************
            // ************************************************************

            if (ShortTermerRow.IsArrivalNull())
            {
                ShortTermerRow.Arrival = FConferenceStartDate;
            }

            if (ShortTermerRow.IsDepartureNull())
            {
                ShortTermerRow.Departure = FConferenceEndDate;
            }

            int CalculationDays = 0;

            if (FConferenceCostType != TConferenceCostTypeEnum.cctPerOutreach)
            {
                /*
                 * Calculations when charge by the day for all
                 * Note: volunteers and short stays override this calculation
                 * Note: this does not include pre and post congress stays
                 */
                CalculationDays = GetDaysAtCongress(ref ASituation, ShortTermerRow,
                    ShortTermerRow.Arrival.Value,
                    ShortTermerRow.Departure.Value);

                if (FConferenceCostType == TConferenceCostTypeEnum.cctPerDay)
                {
                    CalculationDays++;
                }

                FCongressCosts = CalculationDays * FConferenceDayRate * (100 - ChildDiscount) / 100;

                if (FIsCongressRole)
                {
                    FCongressCosts = FCongressCosts * (100 - FRoleDiscountConferenceConference) / 100;

                    if (FRoleDiscountConferenceConference != 0)
                    {
                        GeneralDiscountApplied = true;
                    }
                }

                FOutreachCosts = 0;
            }
            else
            {
                /*
                 * Calculations when charging by outreach length
                 * Note: volunteers and short stays override this calculation
                 * Note: this does not include pre and post congress stays
                 */
                decimal TmpCost = GetOutreachCost(ref ASituation);

                FCongressCosts = FConferenceRate * (100 - ChildDiscount) / 100;

                if (FIsCongressRole)
                {
                    FCongressCosts = FConferenceRate *
                                     (100 - FRoleDiscountConferenceConference) / 100;

                    if (FRoleDiscountConferenceConference != 0)
                    {
                        GeneralDiscountApplied = true;
                    }

                    // No child discount for outreach
                    FOutreachCosts = (TmpCost - FConferenceRate) *
                                     (100 - FRoleDiscountConferencePost) / 100;

                    if (FRoleDiscountConferencePost != 0)
                    {
                        GeneralDiscountApplied = true;
                    }
                }
            }

            if (ShortTermerRow.StOutreachOnlyFlag)
            {
                // Reset when outreach only
                FCongressCosts = 0;
            }

            if (ShortTermerRow.StCongressCode == "VOL")
            {
                /*
                 * Volunteers during the congress
                 * NOTE: will override an above calculation for the congress charge
                 * Note: this does not include pre and post congress stays
                 */
                FIsCongressVolunteer = true;
                int Nights = GetDaysAtCongress(ref ASituation, ShortTermerRow, ShortTermerRow.Arrival.Value,
                    ShortTermerRow.Departure.Value);

                if (FConferenceCostType == TConferenceCostTypeEnum.cctPerDay)
                {
                    Nights++;
                }

                FCongressCosts = Nights * FConferenceDayRate *
                                 (100 - FVolunteerDiscountConferenceConference) / 100 *
                                 (100 - ChildDiscount) / 100;

                FAccommodationCosts = FAccommodationCosts *
                                      (100 - FVolunteerDiscountAccommodationConference) / 100 *
                                      (100 - ChildDiscountAccommodation) / 100;
            }
            else
            {
                FAccommodationCosts = FAccommodationCosts * (100 - ChildDiscountAccommodation) / 100;

                if (FIsCongressRole)
                {
                    FAccommodationCosts = FAccommodationCosts * (100 - FRoleDiscountAccommodationConference) / 100;
                }
            }

            if (ShortTermerRow.Arrival.Value.CompareTo(FAttendeeStartDate) < 0)
            {
                /*
                 * Pre-conference charging, which is always by the day *
                 * Note: short stays override this calculation
                 */

                CalculationDays = GetRoomAllocatedNightsBetween(ref ASituation, ShortTermerRow.PartnerKey,
                    ShortTermerRow.Arrival.Value, FAttendeeStartDate);

                if ((FConferenceCostType == TConferenceCostTypeEnum.cctPerDay)
                    && (ShortTermerRow.Departure.Value.CompareTo(FAttendeeStartDate) < 0))
                {
                    /* a day only needs to be added if the person leaves before the conference
                     * starts, otherwise the daily charge is taken into consideration with the
                     * conference days
                     */
                    CalculationDays++;
                }

                if (ShortTermerRow.StPreCongressCode == "VOL")
                {
                    // Volunteers potentially have a different dscount rate
                    FPreConferenceCosts = CalculationDays * FConferenceDayRate *
                                          (100 - ChildDiscount) / 100 *
                                          (100 - FVolunteerDiscountConferencePre) / 100;

                    FPreAccommodationCosts = FPreAccommodationCosts *
                                             (100 - ChildDiscountAccommodation) / 100 *
                                             (100 - FVolunteerDiscountAccommodationPre) / 100;
                }
                else
                {
                    // everyone else
                    FPreConferenceCosts = CalculationDays * FConferenceDayRate *
                                          (100 - ChildDiscount) / 100 *
                                          (100 - UsedConferenceDiscountPre) / 100;

                    FPreAccommodationCosts = FPreAccommodationCosts *
                                             (100 - ChildDiscountAccommodation) / 100 *
                                             (100 - UsedAccommodationDiscountPre) / 100;
                }

                FConferenceFlags = FConferenceFlags + "P";
            }             // End of pre conference calculation

            if (ShortTermerRow.Departure.Value.CompareTo(FConferenceEndDate) > 0)
            {
                /* Post-conference charging, which is always by the day
                 * For Conference costs only relevent for Congress only people
                 * Note: short stays override this calculation
                 */

                if (FIsCongressOnly)
                {
                    CalculationDays = GetRoomAllocatedNightsBetween(ref ASituation, ShortTermerRow.PartnerKey,
                        FConferenceEndDate, ShortTermerRow.Departure.Value);

                    if ((FConferenceCostType == TConferenceCostTypeEnum.cctPerDay)
                        && (ShortTermerRow.Arrival.Value.CompareTo(FConferenceEndDate) > 0))
                    {
                        /* a day only needs to be added if the person arrives after the conference
                         * ends, otherwise the daily charge is taken into consideration with the
                         * conference days
                         */
                        CalculationDays++;
                    }

                    if (ShortTermerRow.StCongressCode == "VOL")
                    {
                        FPostConferenceCosts = CalculationDays * FConferenceDayRate *
                                               (100 - ChildDiscount) / 100 *
                                               (100 - FVolunteerDiscountConferenceConference) / 100;
                    }
                    else
                    {
                        FPostConferenceCosts = CalculationDays * FConferenceDayRate * (100 - ChildDiscount) / 100;

                        if (FIsCongressRole)
                        {
                            FPostConferenceCosts = FPostConferenceCosts * (100 - FRoleDiscountConferenceConference) / 100;

                            if (FRoleDiscountConferenceConference != 0)
                            {
                                GeneralDiscountApplied = true;
                            }
                        }
                    }
                }

                if (ShortTermerRow.StCongressCode == "VOL")
                {
                    FPostAccommodationCosts = FPostAccommodationCosts *
                                              (100 - ChildDiscount) / 100 *
                                              (100 - FVolunteerDiscountAccommodationConference) / 100;
                }
                else
                {
                    FPostAccommodationCosts = FPostAccommodationCosts * (100 - ChildDiscount) / 100;

                    if (FIsCongressRole)
                    {
                        FPostAccommodationCosts = FPostAccommodationCosts * (100 - FRoleDiscountAccommodationConference) / 100;
                    }
                }
            }

            /*
             * Short stay.   NOTE: overrides all the above charges
             * NOTE: will override an above calculation for the congress charge
             */
            if (FConferenceCostType == TConferenceCostTypeEnum.cctPerOutreach)
            {
                // consider short stay only if it is not on a daily basis
                if (((ShortTermerRow.Departure.Value.Subtract(ShortTermerRow.Arrival.Value).Days * 2) <= FConferenceDays)
                    && (ShortTermerRow.StCongressCode != "VOL")
                    && (!ShortTermerRow.StOutreachOnlyFlag))
                {
                    FCongressCosts = ShortTermerRow.Departure.Value.Subtract(ShortTermerRow.Arrival.Value).Days * FConferenceDayRate *
                                     (100 - ChildDiscount) / 100;

                    if (FIsCongressRole)
                    {
                        FCongressCosts = FCongressCosts * (100 - FRoleDiscountConferenceConference) / 100;

                        if (FRoleDiscountConferenceConference != 0)
                        {
                            GeneralDiscountApplied = true;
                        }
                    }
                }
            }

            // Early and late booking charges
            decimal EarlyAmount, LateAmount;
            int EarlyPercent, LatePercent;
            GetEarlyLateCharges(ref ASituation, ARegistrationDate, ShortTermerRow, out EarlyPercent, out EarlyAmount,
                out LatePercent, out LateAmount);

            FCongressCosts = FCongressCosts - (EarlyAmount * (100 - ChildDiscount) / 100);
            FCongressCosts = FCongressCosts * (100 - EarlyPercent) / 100;
            FCongressCosts = FCongressCosts - (LateAmount * (100 - ChildDiscount) / 100);
            FCongressCosts = FCongressCosts * (100 - LatePercent) / 100;

            // Clear any negative values
            if (FCongressCosts < 0)
            {
                FCongressCosts = 0;
            }

            if (FOutreachCosts < 0)
            {
                FOutreachCosts = 0;
            }

            AFinanceDetails = StringHelper.FormatUsingCurrencyCode(
                (decimal)(FOutreachCosts + FCongressCosts + FExtraCost + FSupportCost + FPreConferenceCosts + FPostConferenceCosts),
                FConferenceCurrency);
            AAccommodation = StringHelper.FormatUsingCurrencyCode(
                (decimal)(FAccommodationCosts + FPreAccommodationCosts + FPostAccommodationCosts),
                FConferenceCurrency);

            AFinanceDetails = AFinanceDetails + FConferenceFlags;
            FUsedConferenceFlags = FUsedConferenceFlags + FConferenceFlags;

            if (GeneralDiscountApplied)
            {
                AFinanceDetails = AFinanceDetails + "*";
                FUsedConferenceFlags = FUsedConferenceFlags + "*";
            }

            String FieldName = TAccommodationReportCalculation.GetPartnerShortName(AHomeOfficeKey, ref ASituation);

            if ((AHomeOfficeKey == 0)
                || (FieldName == ""))
            {
                FieldName = "PARTNERS WITH NO FIELD";
            }

            AddCalculationsToResultTable(FieldName, AAge, ShortTermerRow, ref ASituation);

            AddCalculationsToResultTable("REPORT SUMMARY", AAge, ShortTermerRow, ref ASituation);

            return true;
        }
        /// <summary>
        /// Calculates the cost of the room for one person for the given number of days.
        /// </summary>
        /// <param name="ARow">Room allocation row for the room booking</param>
        /// <param name="ANumberOfBookedDays">number of booked days</param>
        /// <param name="ARoomRow">the row index on the result table to which this calculation refers</param>
        /// <param name="AAge">age of the person who is in the room</param>
        /// <param name="AConferenceKey">conference key of the current conference</param>
        /// <param name="ASituation">The current report situation</param>
        /// <returns></returns>
        private bool CalculateRoomCost(PcRoomAllocRow ARow, int ANumberOfBookedDays, int ARoomRow,
            int AAge, long AConferenceKey, ref TRptSituation ASituation)
        {
            PcRoomTable RoomTable;

            RoomTable = PcRoomAccess.LoadByPrimaryKey(ARow.VenueKey, ARow.BuildingCode, ARow.RoomNumber,
                ASituation.GetDatabaseConnection().Transaction);

            if (RoomTable.Rows.Count > 0)
            {
                PcRoomRow RoomRow = (PcRoomRow)RoomTable.Rows[0];

                decimal cost = RoomRow.BedCost * ANumberOfBookedDays;
                decimal ChildDiscount;
                bool InPercent;

                if (TAccommodationReportCalculation.GetChildDiscount(AAge, AConferenceKey, "ACCOMMODATION", out ChildDiscount, out InPercent,
                        ref ASituation))
                {
                    if (InPercent)
                    {
                        cost = cost * (100 - ChildDiscount) / 100;
                    }
                    else
                    {
                        // At the moment we ignore if the child discount is not set up as percent
                        cost = RoomRow.BedCost * ANumberOfBookedDays;
                    }
                }

                FAccommodationTable.Rows[ARoomRow]["Total Cost"] =
                    (decimal)FAccommodationTable.Rows[ARoomRow]["Total Cost"] + cost;
            }

            return true;
        }
        /// <summary>
        /// Get a list of all the different child discounts available for this conference.
        /// </summary>
        /// <param name="AgeList"></param>
        /// <param name="ASituation"></param>
        /// <returns></returns>
        private bool GetChildDiscountList(out List <int>AgeList, ref TRptSituation ASituation)
        {
            AgeList = new List <int>();

            PcDiscountTable DiscountTable = new PcDiscountTable();
            PcDiscountRow TemplateRow = DiscountTable.NewRowTyped(false);

            TemplateRow.ConferenceKey = FConferenceKey;
            TemplateRow.DiscountCriteriaCode = "CHILD";
            TemplateRow.Validity = "ALWAYS";

            StringCollection OrderList = new StringCollection();
            OrderList.Add(" ORDER BY " + PcDiscountTable.GetUpToAgeDBName() + " ASC");

            DiscountTable = PcDiscountAccess.LoadUsingTemplate(TemplateRow, null, null,
                ASituation.GetDatabaseConnection().Transaction, OrderList, 0, 0);

            int PreviousAge = -1;

            foreach (PcDiscountRow DiscountRow in DiscountTable.Rows)
            {
                // we might get the same age two times (for accommodation discount and for conference discount)
                // But we need the age only once.
                if (PreviousAge != DiscountRow.UpToAge)
                {
                    AgeList.Add(DiscountRow.UpToAge);
                    PreviousAge = DiscountRow.UpToAge;
                }
            }

            return true;
        }
        /// <summary>
        /// Get the child discount for
        /// </summary>
        /// <param name="AAge">age of the person</param>
        /// <param name="AConferenceKey">conference key</param>
        /// <param name="ACostType">Defines the type of discount (e.g. ACCOMMODATION or CONFERENCE)</param>
        /// <param name="ADiscount">discount the person gets</param>
        /// <param name="AInPercent">Type of discaount: True - discount is in percent. False - discount is the amount</param>
        /// <param name="ASituation">The current report situation</param>
        /// <returns></returns>
        public static bool GetChildDiscount(int AAge, long AConferenceKey, String ACostType,
            out decimal ADiscount, out bool AInPercent, ref TRptSituation ASituation)
        {
            ADiscount = 0.0M;
            AInPercent = false;

            PcDiscountTable DiscountTable;

            PcDiscountTable TmpTable = new PcDiscountTable();
            PcDiscountRow TemplateRow = TmpTable.NewRowTyped(false);

            TemplateRow.ConferenceKey = AConferenceKey;
            TemplateRow.CostTypeCode = ACostType;
            TemplateRow.DiscountCriteriaCode = "CHILD";
            TemplateRow.Validity = "ALWAYS";

            StringCollection OrderList = new StringCollection();
            OrderList.Add(" ORDER BY " + PcDiscountTable.GetUpToAgeDBName() + " ASC");

            DiscountTable = PcDiscountAccess.LoadUsingTemplate(TemplateRow, null, null,
                ASituation.GetDatabaseConnection().Transaction, OrderList, 0, 0);

            foreach (PcDiscountRow DiscountRow in DiscountTable.Rows)
            {
                if ((!DiscountRow.IsUpToAgeNull())
                    && (DiscountRow.UpToAge >= AAge))
                {
                    ADiscount = DiscountRow.Discount;
                    AInPercent = DiscountRow.Percentage;

                    return true;
                }
            }

            return false;
        }
        private int GetChildDiscountAge(long AConferenceKey, ref TRptSituation ASituation)
        {
            int DiscountAge = 0;

            PcDiscountTable DiscountTable;

            DiscountTable = PcDiscountAccess.LoadViaPcConference(AConferenceKey, ASituation.GetDatabaseConnection().Transaction);

            foreach (DataRow CurrentRow in DiscountTable.Rows)
            {
                if ((string)CurrentRow[PcDiscountTable.GetDiscountCriteriaCodeDBName()] == "CHILD")
                {
                    DiscountAge = (int)CurrentRow[PcDiscountTable.GetUpToAgeDBName()];
                    return DiscountAge;
                }
            }

            return DiscountAge;
        }