/// <summary> /// Requests a product type from the user via the Console object. /// </summary> /// <returns>Returns product type.</returns> static Model.ProductType RequestProductType() { Console.WriteLine("Please enter engagement product type"); foreach (var _productType in Data.ProductType.GetProductTypes()) { Console.WriteLine(_productType.ProductTypeId.ToString() + " - " + _productType.Name); } var productTypeId = int.Parse(Console.ReadLine()); var productType = new Model.ProductType { ProductTypeId = -1 }; foreach (var _productType in Data.ProductType.GetProductTypes()) { if (_productType.ProductTypeId == productTypeId) { productType = _productType; break; } } if (productType.ProductTypeId != -1) { return(productType); } else { Console.WriteLine("Invalid entry."); return(RequestProductType()); } }
public static decimal CalculateAnnualFee(Model.ProductType productType, DateTime billingDate, DateTime clientFeeScheduleDate, decimal planAssetValue, int tierLevel = 0) { var annualFee = 0m; annualFee = Program.CalculateAnnualFee(productType, billingDate, clientFeeScheduleDate, planAssetValue, tierLevel); return(annualFee); }
/// <summary> /// Returns the appropriate invoice fee for a given billing date based on a given product's annual fee. /// </summary> /// <param name="annualFee">The annual fee for the product type.</param> /// <param name="productType">The product type for the engagement.</param> /// <returns>Returns invoice fee.</returns> /// <remarks>I should clean up this code, and perhaps make the logic feed from a data source.</remarks> public static decimal CalculateInvoiceFee(decimal annualFee, Model.ProductType productType, DateTime invoiceDate, DateTime startDate) { var invoiceFee = 0m; if (productType.BillingFrequency == "Quarterly" && productType.BillingLength == "Ongoing") { // add logic here to identify engagements that have started in previous quarter // seperate invoice for beginning engagements that are in advance and started previous quarter // ex: start = 6/15, billing = 6/30, invoice = only 15 days of invoice fee invoiceFee = annualFee / 4; } else if (productType.BillingFrequency == "Quarterly" && productType.BillingLength == "Annual") { var beginningOfQuarter1 = DateTime.Parse("01/01/" + startDate.Year.ToString()); var endingOfQuarter1 = DateTime.Parse("03/31/" + startDate.Year.ToString()); var beginningOfQuarter2 = DateTime.Parse("04/01/" + startDate.Year.ToString()); var endingOfQuarter2 = DateTime.Parse("06/30/" + startDate.Year.ToString()); var beginningOfQuater3 = DateTime.Parse("07/01/" + startDate.Year.ToString()); var endingOfQuarter3 = DateTime.Parse("09/30/" + startDate.Year.ToString()); if (invoiceDate.Year > startDate.Year) { invoiceFee = annualFee / 4; } else if (startDate >= beginningOfQuarter1 && startDate <= endingOfQuarter1) { invoiceFee = annualFee / 3; } else if (startDate >= beginningOfQuarter2 && startDate <= endingOfQuarter2) { invoiceFee = annualFee / 2; if (invoiceDate > endingOfQuarter3) { invoiceFee = invoiceFee + 0.01m; } } else if (startDate >= beginningOfQuater3 && startDate <= endingOfQuarter3) { invoiceFee = annualFee; } else { invoiceFee = annualFee; } } else if (productType.BillingFrequency == "Monthly" && productType.BillingLength == "Ongoing") { invoiceFee = annualFee / 12; } else { invoiceFee = annualFee; } return(invoiceFee); }
public GeneratorInvoice(CRM.Model.Engagement engagement, Generator generator) { this._generator = generator; this._engagement = engagement; this._engagementProductType = engagement.GetProductTypeDetail(); this._engagementEffectiveDate = (DateTime)engagement.EffectiveDate; this._engagementTerminationDate = engagement.ContractTerminationDate; this._engagementTierLevel = (int)engagement.Tier; this._isNewEngagement = engagement.IsNewOnBillingDate(generator.BillingDate); this._isTerminatedEngagement = engagement.IsTerminatedOnBillingDate(generator.BillingDate); this._planAssetValue = this.getPlanAssets(engagement, generator); this.calculateInvoiceFeesAndCredits(); }
public static decimal ProRataInvoiceFeeForNew(Model.ProductType productType, decimal invoiceFee, DateTime startDate) { // Vendor Monitoring if (productType.BillingLength == "Annual") { return(invoiceFee); } var beginningOfQuarter1 = DateTime.Parse("01/01/" + startDate.Year.ToString()); var endingOfQuarter1 = DateTime.Parse("03/31/" + startDate.Year.ToString()); var beginningOfQuarter2 = DateTime.Parse("04/01/" + startDate.Year.ToString()); var endingOfQuarter2 = DateTime.Parse("06/30/" + startDate.Year.ToString()); var beginningOfQuarter3 = DateTime.Parse("07/01/" + startDate.Year.ToString()); var endingOfQuarter3 = DateTime.Parse("09/30/" + startDate.Year.ToString()); var beginningOfQuarter4 = DateTime.Parse("10/01/" + startDate.Year.ToString()); var endingOfQuarter4 = DateTime.Parse("12/31/" + startDate.Year.ToString()); var beginningOfQuarter5 = DateTime.Parse("01/01/" + (startDate.Year + 1).ToString()); // only beginning of day for accuracy startDate = startDate.Date; var totalDays = 0d; var remainingDays = 0d; if (startDate >= beginningOfQuarter1 && startDate <= endingOfQuarter1) { totalDays = (beginningOfQuarter2 - beginningOfQuarter1).TotalDays; remainingDays = (beginningOfQuarter2 - startDate).TotalDays; } else if (startDate >= beginningOfQuarter2 && startDate <= endingOfQuarter2) { totalDays = (beginningOfQuarter3 - beginningOfQuarter2).TotalDays; remainingDays = (beginningOfQuarter3 - startDate).TotalDays; } else if (startDate >= beginningOfQuarter3 && startDate <= endingOfQuarter3) { totalDays = (beginningOfQuarter4 - beginningOfQuarter3).TotalDays; remainingDays = (beginningOfQuarter4 - startDate).TotalDays; } else if (startDate >= beginningOfQuarter4 && startDate <= endingOfQuarter4) { totalDays = (beginningOfQuarter5 - beginningOfQuarter4).TotalDays; remainingDays = (beginningOfQuarter5 - startDate).TotalDays; } return(invoiceFee * (decimal)(remainingDays / totalDays)); }
public static decimal CalculateInvoiceFee(decimal annualFee, Model.ProductType productType, DateTime billingDate, DateTime clientFeeScheduleDate, bool isTerminatedEngagement, bool isNewEngagement, DateTime engagementStartDate) { var invoiceFee = CalculateOriginalInvoiceFee(annualFee, productType, billingDate, clientFeeScheduleDate); if (isTerminatedEngagement && isNewEngagement) { throw new NotImplementedException(); } else if (isTerminatedEngagement) { invoiceFee = 0m; } else if (isNewEngagement) { invoiceFee = Program.ProRataInvoiceFeeForNew(productType, invoiceFee, (DateTime)engagementStartDate); } return(invoiceFee); }
public static InvoiceCalculation.Model.BillingType GetInvoiceBillingType(Model.ProductType productType, DateTime clientFeeScheduleDate, DateTime billingDate, bool isNew) { var result = Model.BillingType.InAdvanced; var feeSchedules = Data.FeeSchedule .GetFeeSchedules(productType, clientFeeScheduleDate, billingDate) .OrderByDescending(x => x.EndDate ?? DateTime.MaxValue) .ThenByDescending(x => x.StartDate) .ToList(); if (feeSchedules.Count == 0) { if (productType.BillingSchedule == "In Arrears") { result = Model.BillingType.InArrears; } else if (productType.BillingSchedule == "In Advanced") { result = Model.BillingType.InAdvanced; } else { result = Model.BillingType.InAdvanced; //throw new Exception("Product Type does not have a valid billing schedule"); } if (isNew && result == Model.BillingType.InAdvanced) { return(Model.BillingType.InArrears); } return(result); } result = feeSchedules[0].BillingType; if (isNew && result == Model.BillingType.InAdvanced) { return(Model.BillingType.InArrears); } return(result); }
/// <summary> /// Returns the annual fee for a given product type. /// </summary> /// <param name="productType">The product type for the engagement.</param> /// <returns>Returns annual fee.</returns> public static decimal CalculateAnnualFee(Model.ProductType productType, DateTime billingDate, DateTime clientFeeScheduleDate, decimal assetValue, int tierLevel = 0) { var annualFee = 0m; var feeSchedules = Data.FeeSchedule.GetFeeSchedules(productType, clientFeeScheduleDate, billingDate); if (productType.IsTierOnly == 1) { foreach (var feeSchedule in feeSchedules) { if (feeSchedule.TierLevel == tierLevel) { annualFee = feeSchedule.AnnualFeeFixed; break; } } return(annualFee); } foreach (var feeSchedule in feeSchedules) { var greaterThan = assetValue >= feeSchedule.AssetSizeMinimum; var lessThan = assetValue <= feeSchedule.AssetSizeMaximum || feeSchedule.AssetSizeMaximum.Equals(0m); if (feeSchedule.EndDate < billingDate) { continue; } if (greaterThan && lessThan) { annualFee = annualFee + ((assetValue - feeSchedule.AssetSizeMinimum) * feeSchedule.AnnualFeePercentage) + feeSchedule.AnnualFeeFixed; } else if (greaterThan && !lessThan) { annualFee = annualFee + ((feeSchedule.AssetSizeMaximum - feeSchedule.AssetSizeMinimum) * feeSchedule.AnnualFeePercentage) + feeSchedule.AnnualFeeFixed; } } return(annualFee); }
/// <summary> /// Recursively runs the invoice calculator program until the console is closed. /// </summary> /// <param name="productType"></param> public static void RunCalculator(Model.ProductType productType) { var billingDate = RequestDateTime("Please enter billing date"); var clientFeeScheduleDate = RequestDateTime("Please enter client fee schedule date"); var assetValue = RequestDecimal("Please enter plan asset value"); var annualFee = 0m; if (productType.IsTierOnly == 1) { var tierLevel = RequestInt("Please enter engagement tier level"); annualFee = CalculateAnnualFee(productType, billingDate, clientFeeScheduleDate, assetValue, tierLevel); } else { annualFee = CalculateAnnualFee(productType, billingDate, clientFeeScheduleDate, assetValue); } Console.WriteLine("Annual fee is " + string.Format("{0:C}", annualFee)); var invoiceFee = CalculateInvoiceFee(annualFee, productType, billingDate, clientFeeScheduleDate); Console.WriteLine("Invoice fee is " + string.Format("{0:C}", invoiceFee)); }
public static decimal CalculateCredit(decimal invoiceFee, DateTime terminationDate, Model.ProductType productType) { var credit = 0m; if (productType.BillingLength == "Annual") { return(invoiceFee); } // only beginning of day for accuracy terminationDate = terminationDate.Date; var beginningOfQuarter1 = DateTime.Parse("01/01/" + terminationDate.Year.ToString()); var endingOfQuarter1 = DateTime.Parse("03/31/" + terminationDate.Year.ToString()); var beginningOfQuarter2 = DateTime.Parse("04/01/" + terminationDate.Year.ToString()); var endingOfQuarter2 = DateTime.Parse("06/30/" + terminationDate.Year.ToString()); var beginningOfQuarter3 = DateTime.Parse("07/01/" + terminationDate.Year.ToString()); var endingOfQuarter3 = DateTime.Parse("09/30/" + terminationDate.Year.ToString()); var beginningOfQuarter4 = DateTime.Parse("10/01/" + terminationDate.Year.ToString()); var endingOfQuarter4 = DateTime.Parse("12/31/" + terminationDate.Year.ToString()); var beginningOfQuarter5 = DateTime.Parse("01/01/" + (terminationDate.Year + 1).ToString()); var totalDays = 0d; var remainingDays = 0d; if (terminationDate >= beginningOfQuarter1 && terminationDate <= endingOfQuarter1) { totalDays = (beginningOfQuarter2 - beginningOfQuarter1).TotalDays; remainingDays = (beginningOfQuarter2 - terminationDate).TotalDays; } else if (terminationDate >= beginningOfQuarter2 && terminationDate <= endingOfQuarter2) { totalDays = (beginningOfQuarter3 - beginningOfQuarter2).TotalDays; remainingDays = (beginningOfQuarter3 - terminationDate).TotalDays; } else if (terminationDate >= beginningOfQuarter3 && terminationDate <= endingOfQuarter3) { totalDays = (beginningOfQuarter4 - beginningOfQuarter3).TotalDays; remainingDays = (beginningOfQuarter4 - terminationDate).TotalDays; } else if (terminationDate >= beginningOfQuarter4 && terminationDate <= endingOfQuarter4) { totalDays = (beginningOfQuarter5 - beginningOfQuarter4).TotalDays; remainingDays = (beginningOfQuarter5 - terminationDate).TotalDays; } // 1 subtracted to numerator to pick up full day of billing on termination //credit = invoiceFee * (decimal)((remainingDays - 1d) / totalDays); credit = invoiceFee * (decimal)((remainingDays) / totalDays); return(credit); }
public static decimal CalculateInvoiceCredit(bool isTerminatedEngagement, decimal invoiceFee, DateTime?terminationDate, Model.ProductType productType) { var invoiceCredit = 0m; if (isTerminatedEngagement) { invoiceCredit = Program.CalculateCredit(invoiceFee, (DateTime)terminationDate, productType); } return(invoiceCredit); }
public static decimal CalculateOriginalInvoiceFee(decimal annualFee, Model.ProductType productType, DateTime billingDate, DateTime clientFeeScheduleDate) { return(Program.CalculateInvoiceFee(annualFee, productType, billingDate, clientFeeScheduleDate)); }