示例#1
0
        private List <FlatRate> GetFlatRates(CPRateRQ oRequest, List <FlatRate> oFlatRates)
        {
            List <FlatRate> lstRates = new List <FlatRate>();

            try
            {
                TimeSpan tsTimeParked   = oRequest.ExitDT - oRequest.EntryDT;
                int      nMinutesParked = (int)Math.Ceiling(tsTimeParked.TotalSeconds / 60.0);   // Round up to get total minutes or part thereof

                foreach (var r in oFlatRates)
                {
                    // Check if there exists Conditions for the Entry Day of the week
                    var conditions = r.Conditions.Where(a => a.DayOfTheWeek == oRequest.EntryDT.DayOfWeek).ToList();
                    foreach (var c in conditions)
                    {
                        // Go further and figure out if we entered during the entry period and exited during the exit period for the Condition

                        // Determine the Date range for the Entry
                        string   strEntryStart = System.String.Format("{0:yyyy-MM-dd} {1}", oRequest.EntryDT, c.EntryStartTime);
                        DateTime dtEntryStart  = Convert.ToDateTime(strEntryStart);

                        string   strEntryEnd = System.String.Format("{0:yyyy-MM-dd} {1}", dtEntryStart.AddDays(c.EntryEndAddDays), c.EntryEndTime);
                        DateTime dtEntryEnd  = Convert.ToDateTime(strEntryEnd);

                        if (dtEntryEnd <= dtEntryStart)
                        {
                            dtEntryEnd = dtEntryEnd.AddDays(1);
                        }

                        // Determine the date range for the Exit
                        string   strExitStart = System.String.Format("{0:yyyy-MM-dd} {1}", dtEntryStart.AddDays(c.DaysBetweenEntryExit), c.ExitStartTime);
                        DateTime dtExitStart  = Convert.ToDateTime(strExitStart);

                        string   strExitEnd = System.String.Format("{0:yyyy-MM-dd} {1}", dtExitStart.AddDays(c.ExitEndAddDays), c.ExitEndTime);
                        DateTime dtExitEnd  = Convert.ToDateTime(strExitEnd);

                        if (dtExitEnd <= dtExitStart)
                        {
                            dtExitEnd = dtExitEnd.AddDays(1);
                        }

                        // Put in an extra check to make sure we don't go over the time period - E.g. this would prevent them getting the weekend rate if they stayed for a week
                        int nMaxMinutes = (int)Math.Ceiling((dtExitEnd - dtEntryStart).TotalSeconds / 60.0);

                        if (oRequest.EntryDT >= dtEntryStart && oRequest.EntryDT <= dtEntryEnd && oRequest.ExitDT >= dtExitStart && oRequest.ExitDT <= dtExitEnd && nMinutesParked <= nMaxMinutes)
                        {
                            lstRates.Add(r);
                            break;
                        }
                    }
                }
            }
            catch (Exception)
            {
                return(new List <FlatRate>());
            }

            return(lstRates);
        }
        public string GetRate([FromUri] DateTime dtEntry, [FromUri] DateTime dtExit, [FromBody] Rates oRateCard)
        {
            CPRateRQ oInput = new CPRateRQ()
            {
                EntryDT = dtEntry, ExitDT = dtExit
            };

            string sRate = GetCalculatedRate(oInput, oRateCard);

            return(sRate);
        }
示例#3
0
        public void TestStandardRates()
        {
            // Requirement:
            //         0 - 1 Hours : $5
            //         1 - 2 Hours : $10
            //         2 - 3 Hours : $15
            //         3+ Hours : $20      flat rate for each calendar day of parking

            var engine = new CarparkRE_Lib.RateEngine();
            var ret    = engine.LoadRates("CarParkRates.json");

            Assert.IsTrue(ret == 0);

            DateTime dtTest = new DateTime(2021, 4, 15);
            CPRateRQ rq     = new CPRateRQ();

            // Standard Rate - 47 Mins
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(9).AddMinutes(47);     // Thursday 9:47 AM
            var rs = engine.CalculateParkingCharge(rq);

            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 5);

            // Standard Rate - 1 Hour 47 Mins
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(10).AddMinutes(47);    // Thursday 10:47 AM
            rs         = engine.CalculateParkingCharge(rq);
            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 10);

            // Standard Rate - 2 Hours 47 Mins
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(11).AddMinutes(47);    // Thursday 11:47 AM
            rs         = engine.CalculateParkingCharge(rq);
            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 15);

            // Standard Rate - 3 Hours 47 Mins
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(12).AddMinutes(47);    // Thursday 12:47
            rs         = engine.CalculateParkingCharge(rq);
            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 20);

            // Standard Rate - 2 Days 7 Hours 47 Mins - Maximum Rate $20 per day
            rq.EntryDT = dtTest.AddHours(9);                            // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddDays(2).AddHours(16).AddMinutes(47); // Saturday 16:47 (4:47 PM)
            rs         = engine.CalculateParkingCharge(rq);
            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 60);
        }
示例#4
0
        public void APITestCheapestRate()
        {
            // Requirements:
            //         The customer should get the cheapest deal based on the rules which apply to the time period

            var engine = new RateEngineController();

            DateTime dtTest = new DateTime(2021, 4, 15);
            CPRateRQ rq     = new CPRateRQ();

            // Crossover Case: Qualifies for Standard Rate - 7 Hours 47 Mins ($20) or Early Bird Rate ($13)
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(16).AddMinutes(47);    // Thursday 16:47 (4:47 PM)
            var rs = JsonConvert.DeserializeObject <CPRateRS>(engine.GetRate(rq.EntryDT, rq.ExitDT, GetRates()));

            Assert.IsTrue(rs.RateName == "Early Bird");
            Assert.IsTrue(rs.TotalPrice == 13);
        }
示例#5
0
        public void APITestStandardRate()
        {
            var engine = new RateEngineController();

            DateTime dtTest = new DateTime(2021, 4, 15);
            CPRateRQ rq     = new CPRateRQ();

            // Standard Rate - 47 Mins
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(9).AddMinutes(47);     // Thursday 9:47 AM
            var rs = JsonConvert.DeserializeObject <CPRateRS>(engine.GetRate(rq.EntryDT, rq.ExitDT, GetRates()));

            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 5);

            // Standard Rate - 1 Hour 47 Mins
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(10).AddMinutes(47);    // Thursday 10:47 AM
            rs         = JsonConvert.DeserializeObject <CPRateRS>(engine.GetRate(rq.EntryDT, rq.ExitDT, GetRates()));
            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 10);

            // Standard Rate - 2 Hours 47 Mins
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(11).AddMinutes(47);    // Thursday 11:47 AM
            rs         = JsonConvert.DeserializeObject <CPRateRS>(engine.GetRate(rq.EntryDT, rq.ExitDT, GetRates()));
            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 15);

            // Standard Rate - 3 Hours 47 Mins
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(12).AddMinutes(47);    // Thursday 12:47
            rs         = JsonConvert.DeserializeObject <CPRateRS>(engine.GetRate(rq.EntryDT, rq.ExitDT, GetRates()));
            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 20);

            // Standard Rate - 2 Days 7 Hours 47 Mins - Maximum Rate $20 per day
            rq.EntryDT = dtTest.AddHours(9);                               // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddDays(2).AddHours(16).AddMinutes(47);    // Saturday 16:47 (4:47 PM)
            rs         = JsonConvert.DeserializeObject <CPRateRS>(engine.GetRate(rq.EntryDT, rq.ExitDT, GetRates()));
            Assert.IsTrue(rs.RateName == "Standard Rate");
            Assert.IsTrue(rs.TotalPrice == 60);
        }
示例#6
0
        /// <summary>
        /// Determines the Rate and Amount to charge the customer for Parking
        /// </summary>
        /// <param name="oRequest">Is an Object from the CarparkRE Library that contains the EntryDateTime and ExitDateTime of the customers parking session</param>
        /// <returns></returns>
        public CPRateRS CalculateParkingCharge(CPRateRQ oRequest)
        {
            CPRateRS oRet = new CPRateRS();

            try
            {
                // Make sure we have some rates loaded
                if (_mRates.RateCount() == 0)
                {
                    return(oRet);
                }

                // Begin with the Standard Rate as the parking charge by default
                oRet.RateName   = _mRates.StandardRates.Name;
                oRet.TotalPrice = GetStandardRateAmount(oRequest, GetStandardRates());

                // Find any flat rates that apply
                List <FlatRate> lstFlatRates = GetFlatRates(oRequest, GetFlatRates());

                // Select the cheapest rate for the customer, default is the Standard Rate
                foreach (var r in lstFlatRates)
                {
                    if (r.Amount < oRet.TotalPrice)
                    {
                        // Overwrite the default Standard Rate with the Flat Rate instead
                        oRet.RateName   = r.Name;
                        oRet.TotalPrice = r.Amount;
                    }
                }
            }
            catch (Exception e)
            {
                // Record any errors in the return object
                oRet = new CPRateRS()
                {
                    ErrorHResult = e.HResult,
                    ErrorMsg     = e.ToString()
                };
            }

            return(oRet);
        }
示例#7
0
        /// <summary>
        /// Figures out the Standard Rates to apply for the given carpark session
        /// </summary>
        /// <param name="oRequest">Is an Object from the CarparkRE Library that contains the EntryDateTime and ExitDateTime of the customers parking session</param>
        /// <param name="oStdRates">Standard Rates as loded from the LoadRates function</param>
        /// <returns></returns>
        private decimal GetStandardRateAmount(CPRateRQ oRequest, StandardRate oStdRates)
        {
            decimal dAmount = 0;

            try
            {
                // Determine the total hours parked ot match with our Standard Rates
                TimeSpan  tsTimeParked  = oRequest.ExitDT - oRequest.EntryDT;
                int       nHoursParked  = (int)Math.Ceiling(tsTimeParked.TotalSeconds / 3600.0); // Round up to get total hours or part thereof
                TimeLimit oTimeSelected = null;

                // Check if we need to apply the max standard rate
                if (nHoursParked > oStdRates.MaxAmountHours)
                {
                    // Check if they get the max standard rate multiple times - E.g. been there for multiple calendar days
                    while (nHoursParked >= oStdRates.MaxAmountHours)
                    {
                        dAmount      += oStdRates.MaxAmount;
                        nHoursParked -= oStdRates.MaxAmountHours;
                    }

                    // Make sure we add on the remainder from the Standard Rate. E.g. Charged max amount for 2 days and then for 2 hours on the last day
                    if (nHoursParked > 0)
                    {
                        oTimeSelected = oStdRates.TimeLimits.FirstOrDefault(a => nHoursParked > a.StartHours && nHoursParked <= a.EndHours);
                        dAmount      += oTimeSelected != null ? oTimeSelected.Amount : 0;
                    }
                }
                else
                {
                    // Hours in the carpark are less than the maximum hours before we click over for a second flat rate, so find the appopriate one
                    oTimeSelected = oStdRates.TimeLimits.FirstOrDefault(a => nHoursParked > a.StartHours && nHoursParked <= a.EndHours);
                    dAmount       = oTimeSelected != null ? oTimeSelected.Amount : 0;
                }
            }
            catch (Exception)
            {
                return(dAmount);
            }

            return(dAmount);
        }
示例#8
0
        public void TestCheapestRate()
        {
            // Requirements:
            //         The customer should get the cheapest deal based on the rules which apply to the time period

            var engine = new CarparkRE_Lib.RateEngine();
            var ret    = engine.LoadRates("CarParkRates.json");

            Assert.IsTrue(ret == 0);

            DateTime dtTest = new DateTime(2021, 4, 15);
            CPRateRQ rq     = new CPRateRQ();

            // Crossover Case: Qualifies for Standard Rate - 7 Hours 47 Mins ($20) or Early Bird Rate ($13)
            rq.EntryDT = dtTest.AddHours(9);                    // Thursday 9:00 AM
            rq.ExitDT  = dtTest.AddHours(16).AddMinutes(47);    // Thursday 16:47 (4:47 PM)
            var rs = engine.CalculateParkingCharge(rq);

            Assert.IsTrue(rs.RateName == "Early Bird");
            Assert.IsTrue(rs.TotalPrice == 13);
        }
示例#9
0
        public void APITestEarlyBird()
        {
            // Requirements:
            //         Name: Early Bird
            //         Type: Flat Rate
            //         Total Price: $13.00
            //         Entry Condition: Enter between 6:00 AM to 9:00 AM
            //         Exit Condition: Exit between 3:30 PM to 11:30 PM

            var engine = new RateEngineController();

            DateTime dtTest = new DateTime(2021, 4, 15);
            CPRateRQ rq     = new CPRateRQ();

            rq.EntryDT = dtTest.AddHours(6).AddMinutes(30);        // Thursday 06:30 AM
            rq.ExitDT  = dtTest.AddHours(16).AddMinutes(30);       // Thursday 16:30 (4:30 PM)

            var rs = JsonConvert.DeserializeObject <CPRateRS>(engine.GetRate(rq.EntryDT, rq.ExitDT, GetRates()));

            Assert.IsTrue(rs.RateName == "Early Bird");
            Assert.IsTrue(rs.TotalPrice == 13);
        }
示例#10
0
        public void APITestWeekendRate()
        {
            // Requirements:
            //         Name: Weekend Rate
            //         Type: Flat Rate
            //         Total Price: $10.00
            //         Entry Condition: Enter anytime past midnight on Friday
            //         Exit Condition: Exit any time before midnight on Sunday

            var engine = new RateEngineController();

            DateTime dtTest = new DateTime(2021, 4, 17);
            CPRateRQ rq     = new CPRateRQ();

            // Weekend Rate
            rq.EntryDT = dtTest.AddMinutes(12);                             // Saturday 00:12 AM
            rq.ExitDT  = dtTest.AddDays(1).AddHours(12).AddMinutes(47);     // Sunday 12:47 PM
            var rs = JsonConvert.DeserializeObject <CPRateRS>(engine.GetRate(rq.EntryDT, rq.ExitDT, GetRates()));

            Assert.IsTrue(rs.RateName == "Weekend Rate");
            Assert.IsTrue(rs.TotalPrice == 10);
        }