Beispiel #1
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        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();
        }
Beispiel #5
0
        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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        /// <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));
        }
Beispiel #10
0
        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));
 }