/// <summary> /// Calculate Charge /// </summary> public RaHireGroup CalculateCharge(DateTime recCreatedDate, DateTime rAStDate, DateTime rAEndDate, DateTime stDate, DateTime eDate, Int64 operationId, Int64 hireGroupDetailId, Int32 outOdometer, Int32 inOdometer, List <TariffType> oTariffTypeList) { PricingStrategy objPs = PricingStrategyFactory.GetPricingStrategy(recCreatedDate, rAStDate, rAEndDate, operationId, oTariffTypeList); if (objPs == null) { throw new CaresException(Resources.RentalAgreement.RentalAgreement.TariffTypeNotDefinedForRentalCharge, null); } List <StandardRate> standardRates = standardRateRepository.GetForRaBilling(objPs.TariffType.TariffTypeCode, hireGroupDetailId, recCreatedDate).ToList(); if (standardRates.Count == 0) { throw new CaresException(Resources.RentalAgreement.RentalAgreement.StandardTariffRateNotDefinedForRentalCharge, null); } StandardRate otStRate = standardRates[0]; RaHireGroup tmp = objPs.CalculateRentalCharge(stDate, eDate, otStRate); // need to get RA vehicle as well for calculating Excess Mileage Charge for edit case tmp.TotalExcMileage = objPs.GetExcessMileage(outOdometer, inOdometer, tmp.AllowedMileage ?? 0); tmp.TotalExcMileageCharge = objPs.GetExcessMileageCharge(tmp.TotalExcMileage, (float)tmp.ExcessMileageRt); return(tmp); }
public void Calculate_StandardRate_TotalPrice_Minutes_LessThan180() { //Arrange var standardRate = new StandardRate(); //Act var result = standardRate.TotalPrice(150); //Assert Assert.AreEqual(result, 15.00m); }
public void Calculate_StandardRate_TotalPrice_Minutes_GreatherThan180() { //Arrange var standardRate = new StandardRate(); //Act var result = standardRate.TotalPrice(200); //Assert Assert.AreEqual(result, 20.00m); }
/// <summary> /// Create entity from web model /// </summary> public static ApiModels.StandardRate CreateFrom(this StandardRate source) { return(new ApiModels.StandardRate { StandardRtId = source.StandardRtId, ChildStandardRtId = source.ChildStandardRtId, HireGroupDetailId = source.HireGroupDetailId, StandardRtMainId = source.StandardRtMainId, AllowMileage = source.AllowedMileage, ExcessMileageCharge = source.ExcessMileageChrg, StandardRt = source.StandardRt, EndDt = source.StandardRtEndDt, StartDate = source.StandardRtStartDt, RevisionNumber = source.RevisionNumber }); }
public CarParkingFeeDetails GetCarParkingPriceDetails(DateTime EntryDateTime, DateTime ExitDateTime) { //Early bird rate //Entry: 6-9Am //Exit: 330-1130PM if ((EntryDateTime.TimeOfDay.TotalMinutes >= 360 && EntryDateTime.TimeOfDay.TotalMinutes <= 540) && (ExitDateTime.TimeOfDay.TotalMinutes >= 930 && ExitDateTime.TimeOfDay.TotalMinutes <= 1410)) { return new CarParkingFeeDetails { Rate = new EarlyBirdRate() } } ; //Night rate //Entry: 6-12PM //Exit: 6AM Next day if ((EntryDateTime.TimeOfDay.TotalMinutes >= 1080 && EntryDateTime.TimeOfDay.TotalMinutes <= 1440 && (EntryDateTime.DayOfWeek != DayOfWeek.Saturday || EntryDateTime.DayOfWeek != DayOfWeek.Sunday)) && (ExitDateTime.TimeOfDay.TotalMinutes <= 360 && ExitDateTime.Day == EntryDateTime.Day + 1)) { return new CarParkingFeeDetails { Rate = new NightRate() } } ; //Weekend rate //Entry: Anytime after Friday Midnight //Exit: Anytime before Sunday Midnight if ((EntryDateTime.TimeOfDay.TotalMinutes >= 1 && (EntryDateTime.DayOfWeek == DayOfWeek.Saturday || EntryDateTime.DayOfWeek == DayOfWeek.Sunday)) && (ExitDateTime.TimeOfDay.TotalMinutes <= 1440 && (ExitDateTime.DayOfWeek == DayOfWeek.Sunday || ExitDateTime.DayOfWeek == DayOfWeek.Saturday))) { return new CarParkingFeeDetails { Rate = new WeekendRate() } } ; var totalMinutes = ExitDateTime.TimeOfDay.TotalMinutes - EntryDateTime.TimeOfDay.TotalMinutes; var standardRate = new StandardRate(); return(new CarParkingFeeDetails { Rate = standardRate, TotalParkingFee = standardRate.TotalPrice(totalMinutes) }); } } }
public void Mapping_StandardRate_ToEntryResponse_IsCorrect() { //arrange var standardRate = new StandardRate { TotalPrice = 10, Name = "Test Rate Name", Type = "Test Rate Type" }; var entryRequest = BuildEntryRequest(DateTime.Now.AddHours(-1).ToString(), DateTime.Now.ToString()); //act var result = EntryResponse.FromStandardRate(standardRate, entryRequest); //assert Assert.AreEqual(standardRate.TotalPrice, result.Amount, "Amount not match"); Assert.AreEqual(standardRate.Type, result.RateType, "Rate Type not match"); Assert.AreEqual(standardRate.Name, result.RateName, "Rate Name not match"); Assert.AreEqual(entryRequest.RegistrationNo, result.RegistrationNo, "Registration No not match"); Assert.AreEqual(entryRequest.EntryTime, result.EntryTime, "Entry Time not match"); Assert.AreEqual(entryRequest.ExitTime, result.ExitTime, "Exit Time not match"); }
/// <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); }
/// <summary> /// Acquire correct rate based on business rules /// </summary> /// <param name="enter">Entry time</param> /// <param name="exit"Exit time</param> /// <returns>Instance of Rate</returns> public Rate GetCorrectRate(DateTime enter, DateTime exit) { Rate earlyBird = new EarlyBirdRate(); Rate nightRate = new NightRate(); Rate standardRate = new StandardRate(); DayOfWeek dow = enter.DayOfWeek; if (enter >= earlyBird.EnterStartTime && enter <= earlyBird.EnterEndTime) { if (exit >= earlyBird.ExitStartTime && exit <= earlyBird.ExitEndTime) { return(earlyBird); } else { return(standardRate); } } else if (enter >= nightRate.EnterStartTime && enter <= nightRate.EnterEndTime) { if ((dow == DayOfWeek.Saturday) || (dow == DayOfWeek.Sunday)) { return(standardRate); } int dayDifference = exit.Day - enter.Day; if ((dayDifference == 1) && exit.Hour <= 6) { return(nightRate); } else { return(standardRate); } } else { return(standardRate); } }
public virtual IParkingRate CreateParkingRate(RateName rateType) { IParkingRate parkingRate = null; switch (rateType) { case RateName.Standard: parkingRate = new StandardRate("Standard Rate"); break; case RateName.Night: parkingRate = new NightRate("Night Rate"); break; case RateName.EarlyBird: parkingRate = new EarlyBirdRate("Early Bird Rate"); break; case RateName.Weekend: parkingRate = new WeekendRate("Weekend Rate"); break; } return(parkingRate); }
public override RaHireGroup CalculateRentalCharge(DateTime StartDate, DateTime EndDate, StandardRate tSTrate) { RaHireGroup oRentalCharge = null; //calculate total rental duration as a time span object TimeSpan dtSpan = EndDate - StartDate; TimeSpan ChargeSpan; TimeSpan GraceSpan; //convert rental duration to minutes for standardization float RentalDurationInMinutes = GetDurationInMinutes(dtSpan, Convert.ToInt32(TariffType.MeasurementUnitId)); //convert tariff type FromDuration to Minute for standardization float TariffDurationFrom = GetDurationInMinutes(TariffType.DurationFrom, Convert.ToInt32(TariffType.MeasurementUnitId)); //convert tariff type ToDuration to Minute for standardization float TariffDurationTo = GetDurationInMinutes(TariffType.DurationTo, Convert.ToInt32(TariffType.MeasurementUnitId)); //convert tariff type GracePeriod to Minute for standardization float TariffGracePeriod = GetDurationInMinutes((float)TariffType.GracePeriod, Convert.ToInt32(TariffType.MeasurementUnitId)); //set rental charge object common parameters oRentalCharge = new RaHireGroup(); oRentalCharge.RentalChargeStartDate = StartDate; oRentalCharge.RentalChargeEndDate = EndDate; oRentalCharge.TariffTypeCode = TariffType.TariffTypeCode; //condition 1: if rental duration lies between From and To if (RentalDurationInMinutes >= TariffDurationFrom && RentalDurationInMinutes <= TariffDurationTo) { oRentalCharge.StandardRate = tSTrate.StandardRt; oRentalCharge.TotalStandardCharge = tSTrate.StandardRt; //excess milage charge for edit case oRentalCharge.ExcessMileageRt = tSTrate.ExcessMileageChrg; oRentalCharge.TotalExcMileageCharge = 0; oRentalCharge.GraceDay = 0; oRentalCharge.GraceHour = 0; oRentalCharge.GraceMinute = 0; oRentalCharge.ChargedDay = dtSpan.Days; oRentalCharge.ChargedHour = dtSpan.Hours; oRentalCharge.ChargedMinute = dtSpan.Minutes; oRentalCharge.AllowedMileage = tSTrate.AllowedMileage; } else { GraceSpan = GetGrace(RentalDurationInMinutes, TariffDurationTo, Convert.ToInt32(TariffType.MeasurementUnitId), TariffGracePeriod); ChargeSpan = new TimeSpan(dtSpan.Days - GraceSpan.Days, dtSpan.Hours - GraceSpan.Hours, dtSpan.Minutes - GraceSpan.Minutes, 0); float ChargeDuration = GetDurationInMinutes(ChargeSpan, Convert.ToInt32(TariffType.MeasurementUnitId)); oRentalCharge.TotalStandardCharge = (float)Math.Round((ChargeDuration / TariffDurationTo) * tSTrate.StandardRt, base.DecimalRounding, MidpointRounding.AwayFromZero); oRentalCharge.StandardRate = tSTrate.StandardRt; //excess milage charge for edit case //drop off charge oRentalCharge.DropOffCharge = 0; oRentalCharge.ExcessMileageRt = tSTrate.ExcessMileageChrg; oRentalCharge.TotalExcMileageCharge = 0; oRentalCharge.AllowedMileage = tSTrate.AllowedMileage; oRentalCharge.GraceDay = GraceSpan.Days; oRentalCharge.GraceHour = GraceSpan.Hours; oRentalCharge.GraceMinute = GraceSpan.Minutes; oRentalCharge.ChargedDay = ChargeSpan.Days; oRentalCharge.ChargedHour = ChargeSpan.Hours; oRentalCharge.ChargedMinute = ChargeSpan.Minutes; } return(oRentalCharge); }
public abstract RaHireGroup CalculateRentalCharge(DateTime StartDate, DateTime EndDate, StandardRate tSTrate);
public StandardRateTests() { _rate = new StandardRate(); }
/// <summary> /// Generates Rental Charge /// </summary> public override RaHireGroup CalculateRentalCharge(DateTime StartDate, DateTime EndDate, StandardRate tSTrate) { RaHireGroup oRentalCharge = null; //calculate total rental duration as a time span object TimeSpan dtSpan = EndDate - StartDate; TimeSpan ChargeSpan; TimeSpan GraceSpan; //convert rental duration to minutes for standardization float RentalDurationInMinutes = GetDurationInMinutes(dtSpan, Convert.ToInt32(TariffType.MeasurementUnitId)); //convert tariff type FromDuration to Minute for standardization float TariffDurationFrom = GetDurationInMinutes(TariffType.DurationFrom, Convert.ToInt32(TariffType.MeasurementUnitId)); //convert tariff type ToDuration to Minute for standardization float TariffDurationTo = GetDurationInMinutes(TariffType.DurationTo, Convert.ToInt32(TariffType.MeasurementUnitId)); //convert tariff type GracePeriod to Minute for standardization float TariffGracePeriod = GetDurationInMinutes((float)TariffType.GracePeriod, Convert.ToInt32(TariffType.MeasurementUnitId)); //set rental charge object common parameters oRentalCharge = new RaHireGroup(); oRentalCharge.RentalChargeStartDate = StartDate; oRentalCharge.RentalChargeEndDate = EndDate; oRentalCharge.TariffTypeCode = this.TariffType.TariffTypeCode; //condition 1: if rental duration lies between From and To if (RentalDurationInMinutes >= TariffDurationFrom && RentalDurationInMinutes <= TariffDurationTo) { oRentalCharge.StandardRate = (float)tSTrate.StandardRt; oRentalCharge.TotalStandardCharge = (float)tSTrate.StandardRt; //excess milage charge for edit case oRentalCharge.ExcessMileageRt = (float)tSTrate.ExcessMileageChrg; oRentalCharge.TotalExcMileageCharge = 0; oRentalCharge.AllowedMileage = tSTrate.AllowedMileage; oRentalCharge.GraceDay = 0; oRentalCharge.GraceHour = 0; oRentalCharge.GraceMinute = 0; oRentalCharge.ChargedDay = dtSpan.Days; oRentalCharge.ChargedHour = dtSpan.Hours; oRentalCharge.ChargedMinute = dtSpan.Minutes; } else { Int16 Quotient = Int16.Parse(Math.Floor(Convert.ToDouble(RentalDurationInMinutes / TariffDurationTo)).ToString()); //check if grace is applicable or not float y = RentalDurationInMinutes % TariffDurationTo; // since RentalDurationInMinutes % TariffDurationTo gives us how many units the rental duration is greater than TariffDurationTo, // the y part gives us the remainder of those units.if y times this.TariffType.DurationTo is less than and equal to this.TariffType.Graceperiod , then grace is applicable //if (y * this.TariffType.DurationTo <= this.TariffType.GracePeriod) if (y <= this.TariffType.GracePeriod) { GraceSpan = GetGrace(RentalDurationInMinutes, TariffDurationTo, Quotient); } else { GraceSpan = new TimeSpan(0, 0, 0, 0); } ChargeSpan = new TimeSpan(dtSpan.Days - GraceSpan.Days, dtSpan.Hours - GraceSpan.Hours, dtSpan.Minutes - GraceSpan.Minutes, 0); float ChargeDuration = GetDurationInMinutes(ChargeSpan, Convert.ToInt32(this.TariffType.MeasurementUnitId)); oRentalCharge.TotalStandardCharge = (float)Math.Round(((float)Math.Ceiling(Convert.ToDouble((ChargeDuration / TariffDurationTo)))) * tSTrate.StandardRt, base.DecimalRounding, MidpointRounding.AwayFromZero); oRentalCharge.StandardRate = tSTrate.StandardRt; //excess milage charge for edit case //drop off charge oRentalCharge.DropOffCharge = 0; oRentalCharge.ExcessMileageRt = tSTrate.ExcessMileageChrg; oRentalCharge.TotalExcMileageCharge = 0; oRentalCharge.GraceDay = GraceSpan.Days; oRentalCharge.GraceHour = GraceSpan.Hours; oRentalCharge.GraceMinute = GraceSpan.Minutes; oRentalCharge.ChargedDay = ChargeSpan.Days; oRentalCharge.ChargedHour = ChargeSpan.Hours; oRentalCharge.ChargedMinute = ChargeSpan.Minutes; oRentalCharge.AllowedMileage = tSTrate.AllowedMileage; } return(oRentalCharge); }
/// <summary> /// Add Tariff Rate /// </summary> /// <param name="standardRateMain"></param> /// <returns></returns> public TariffRateContent SaveTariffRate(StandardRateMain standardRateMain) { TariffType tariffType = tariffTypeRepository.Find(long.Parse(standardRateMain.TariffTypeCode)); standardRateMain.TariffTypeCode = tariffType.TariffTypeCode; #region Add if (standardRateMain.StandardRtMainId == 0) { StandardRateValidation(standardRateMain, true); standardRateMain.UserDomainKey = standardRateMainRepository.UserDomainKey; standardRateMain.IsActive = true; standardRateMain.IsDeleted = false; standardRateMain.IsPrivate = false; standardRateMain.IsReadOnly = false; standardRateMain.RecCreatedDt = DateTime.Now; standardRateMain.RecLastUpdatedDt = DateTime.Now; standardRateMain.RecCreatedBy = standardRateMainRepository.LoggedInUserIdentity; standardRateMain.RecLastUpdatedBy = standardRateMainRepository.LoggedInUserIdentity; standardRateMain.RowVersion = 0; //set child (Standard Rate in Standard Rate Main) properties #region Standard Rate in Standard Rate Main if (standardRateMain.StandardRates != null) { // set properties foreach (StandardRate item in standardRateMain.StandardRates) { item.IsActive = true; item.IsDeleted = false; item.IsPrivate = false; item.IsReadOnly = false; item.RecCreatedDt = DateTime.Now; item.RecLastUpdatedDt = DateTime.Now; item.RecCreatedBy = standardRateMainRepository.LoggedInUserIdentity; item.RecLastUpdatedBy = standardRateMainRepository.LoggedInUserIdentity; item.UserDomainKey = standardRateMainRepository.UserDomainKey; } } #endregion standardRateMainRepository.Add(standardRateMain); standardRateMainRepository.SaveChanges(); } #endregion #region Edit else { StandardRateValidation(standardRateMain, false); if (standardRateMain.StandardRates != null) { foreach (StandardRate standardRate in standardRateMain.StandardRates) { standardRate.IsActive = true; standardRate.IsDeleted = false; standardRate.IsPrivate = false; standardRate.IsReadOnly = false; standardRate.RecCreatedDt = DateTime.Now; standardRate.RecLastUpdatedDt = DateTime.Now; standardRate.RecCreatedBy = standardRateMainRepository.LoggedInUserIdentity; standardRate.RecLastUpdatedBy = standardRateMainRepository.LoggedInUserIdentity; standardRate.UserDomainKey = standardRateMainRepository.UserDomainKey; standardRate.StandardRtMainId = standardRateMain.StandardRtMainId; if (standardRate.StandardRtId > 0) { long oldRecordId = standardRate.StandardRtId; standardRate.StandardRtId = 0; standardRate.RevisionNumber = standardRate.RevisionNumber + 1; standardRateRepository.Add(standardRate); standardRateRepository.SaveChanges(); StandardRate oldStandardRate = standardRateRepository.Find(oldRecordId); oldStandardRate.ChildStandardRtId = standardRate.StandardRtId; standardRateRepository.SaveChanges(); } else { standardRateRepository.Add(standardRate); standardRateRepository.SaveChanges(); } } } } #endregion return(new TariffRateContent { StandardRtMainId = standardRateMain.StandardRtMainId, StandardRtMainCode = standardRateMain.StandardRtMainCode, StandardRtMainName = standardRateMain.StandardRtMainName, StandardRtMainDescription = standardRateMain.StandardRtMainDescription, StartDt = standardRateMain.StartDt, EndDt = standardRateMain.EndDt, TariffTypeId = tariffType.TariffTypeId, TariffTypeCodeName = tariffType.TariffTypeCode + " - " + tariffType.TariffTypeName, OperationId = tariffType.OperationId, OperationCodeName = tariffType.Operation.OperationCode + " - " + tariffType.Operation.OperationName, }); }