/// <summary>
        /// Calculates Total Allowances
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="maritalStatus">Marital status</param>
        /// <param name="stateOfResidency">State of residency</param>
        /// <param name="numInCollege">Number in college</param>
        /// <param name="numInHousehold">Number in household</param>
        /// <param name="employablePersons">People capable of employment. Exact definition varies depending on
        /// role. If the role is "Parent", for example, <see cref="employablePersons"/> refers to the parents.
        /// If the role is "IndependentStudent", <see cref="employablePersons"/> refers to the student and
        /// spouse</param>
        /// <param name="totalIncome">Total income</param>
        /// <param name="incomeTaxPaid">U.S. income tax paid</param>
        /// <returns>"Total Allowances"</returns>
        public double CalculateTotalAllowances(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            UnitedStatesStateOrTerritory stateOfResidency,
            int numInCollege,
            int numInHousehold,
            List <HouseholdMember> employablePersons,
            double totalIncome,
            double incomeTaxPaid)
        {
            double totalAllowances = 0;

            // Income Tax Paid
            totalAllowances += CalculateIncomeTaxAllowance(incomeTaxPaid);

            // State Tax
            totalAllowances += CalculateStateTaxAllowance(role, stateOfResidency, totalIncome);

            // Social Security Tax
            totalAllowances += employablePersons
                               .Where(person => person.IsWorking)
                               .Sum(person => CalculateSocialSecurityTaxAllowance(person.WorkIncome));

            // Employment Expense Allowance
            if (role != EfcCalculationRole.DependentStudent)
            {
                totalAllowances += CalculateEmploymentExpenseAllowance(role, maritalStatus, employablePersons);
            }

            // Income Protection Allowance
            totalAllowances += CalculateIncomeProtectionAllowance(role, maritalStatus, numInCollege, numInHousehold);

            return(Math.Round(totalAllowances < 0 ? 0 : totalAllowances, MidpointRounding.AwayFromZero));
        }
Exemple #2
0
        /// <summary>
        /// Calculates State and Other Tax allowance
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="stateOfResidency">State of residency</param>
        /// <param name="totalIncome">Total income</param>
        /// <returns>State and Other Tax allowance</returns>
        public double CalculateStateTaxAllowance(
            EfcCalculationRole role,
            UnitedStatesStateOrTerritory stateOfResidency,
            double totalIncome)
        {
            double stateTaxAllowance = 0;

            switch (role)
            {
            // For Parents and Independent Students With Dependents, use the "Parent" State Tax Allowance chart
            case EfcCalculationRole.Parent:
            case EfcCalculationRole.IndependentStudentWithDependents:
                if (totalIncome < _constants.StateTaxAllowanceIncomeThreshold)
                {
                    stateTaxAllowance =
                        (_constants.ParentStateTaxAllowancePercents[(int)stateOfResidency] * 0.01) * totalIncome;
                }
                else
                {
                    stateTaxAllowance =
                        ((_constants.ParentStateTaxAllowancePercents[(int)stateOfResidency] - 1) * 0.01)
                        * totalIncome;
                }
                break;

            // For Dependent Students and Independent Students Without Dependents, use the "Student" State Tax Allowance chart
            case EfcCalculationRole.DependentStudent:
            case EfcCalculationRole.IndependentStudentWithoutDependents:
                stateTaxAllowance =
                    (_constants.StudentStateTaxAllowancePercents[(int)stateOfResidency] * 0.01) * totalIncome;
                break;
            }

            return(Math.Round(stateTaxAllowance < 0 ? 0 : stateTaxAllowance, MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates "Employmement Expense Allowance"
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="maritalStatus">Marital status</param>
        /// <param name="employablePersons">People capable of employment. Exact definition varies depending on
        /// role. If the role is "Parent", for example, <see cref="employablePersons"/> refers to the parents.
        /// If the role is "IndependentStudent", <see cref="employablePersons"/> refers to the student and
        /// spouse</param>
        /// <returns>"Employment Expense Allowance"</returns>
        public double CalculateEmploymentExpenseAllowance(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            List <HouseholdMember> employablePersons)
        {
            if (employablePersons == null ||
                !employablePersons.Any() ||
                (role == EfcCalculationRole.DependentStudent) ||
                (role == EfcCalculationRole.IndependentStudentWithoutDependents &&
                 maritalStatus == MaritalStatus.SingleSeparatedDivorced))
            {
                return(0);
            }

            IEnumerable <HouseholdMember> incomeEarners
                = employablePersons
                  .Where(ep => ep.IsWorking)
                  .OrderBy(ie => ie.WorkIncome);

            // Not all of the employable persons are working
            if (incomeEarners.Count() != employablePersons.Count())
            {
                return(0);
            }

            // Use the lesser of the incomes for the calculation
            double lowestIncome         = incomeEarners.First().WorkIncome;
            double adjustedLowestIncome = (lowestIncome * _constants.EmploymentExpensePercent);

            double employmentExpenseAllowance = adjustedLowestIncome > _constants.EmploymentExpenseMaximum
                ? _constants.EmploymentExpenseMaximum : adjustedLowestIncome;

            return(Math.Round(employmentExpenseAllowance < 0 ? 0 : employmentExpenseAllowance,
                              MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates Total Allowances
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="maritalStatus">Marital status</param>
        /// <param name="stateOfResidency">State of residency</param>
        /// <param name="numInCollege">Number in college</param>
        /// <param name="numInHousehold">Number in household</param>
        /// <param name="employablePersons">People capable of employment. Exact definition varies depending on
        /// role. If the role is "Parent", for example, <see cref="employablePersons"/> refers to the parents.
        /// If the role is "IndependentStudent", <see cref="employablePersons"/> refers to the student and
        /// spouse</param>
        /// <param name="totalIncome">Total income</param>
        /// <param name="incomeTaxPaid">U.S. income tax paid</param>
        /// <returns>"Total Allowances"</returns>
        public double CalculateTotalAllowances(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            UnitedStatesStateOrTerritory stateOfResidency,
            int numInCollege,
            int numInHousehold,
            List<HouseholdMember> employablePersons,
            double totalIncome,
            double incomeTaxPaid)
        {
            double totalAllowances = 0;

            // Income Tax Paid
            totalAllowances += CalculateIncomeTaxAllowance(incomeTaxPaid);

            // State Tax
            totalAllowances += CalculateStateTaxAllowance(role, stateOfResidency, totalIncome);

            // Social Security Tax
            totalAllowances += employablePersons
                                    .Where(person => person.IsWorking)
                                    .Sum(person => CalculateSocialSecurityTaxAllowance(person.WorkIncome));

            // Employment Expense Allowance
            if (role != EfcCalculationRole.DependentStudent)
            {
                totalAllowances += CalculateEmploymentExpenseAllowance(role, maritalStatus, employablePersons);
            }

            // Income Protection Allowance
            totalAllowances += CalculateIncomeProtectionAllowance(role, maritalStatus, numInCollege, numInHousehold);

            return Math.Round(totalAllowances < 0 ? 0 : totalAllowances, MidpointRounding.AwayFromZero);
        }
Exemple #5
0
        /// <summary>
        /// Calculates "Employmement Expense Allowance"
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="maritalStatus">Marital status</param>
        /// <param name="employablePersons">People capable of employment. Exact definition varies depending on
        /// role. If the role is "Parent", for example, <see cref="employablePersons"/> refers to the parents.
        /// If the role is "IndependentStudent", <see cref="employablePersons"/> refers to the student and
        /// spouse</param>
        /// <returns>"Employment Expense Allowance"</returns>
        public double CalculateEmploymentExpenseAllowance(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            List <HouseholdMember> employablePersons)
        {
            if (employablePersons == null ||
                employablePersons.Count == 0 ||
                (role == EfcCalculationRole.DependentStudent) ||
                (role == EfcCalculationRole.IndependentStudentWithoutDependents &&
                 maritalStatus == MaritalStatus.SingleSeparatedDivorced))
            {
                return(0);
            }

            // Create a list of working Household Members
            List <HouseholdMember> incomeEarners = new List <HouseholdMember>();

            foreach (HouseholdMember person in employablePersons)
            {
                if (person.IsWorking)
                {
                    incomeEarners.Add(person);
                }
            }

            // Not all of the employable persons are working
            if (incomeEarners.Count != employablePersons.Count)
            {
                return(0);
            }

            HouseholdMember lowestIncomeEarner = incomeEarners[0];

            foreach (HouseholdMember person in incomeEarners)
            {
                if (person.WorkIncome < lowestIncomeEarner.WorkIncome)
                {
                    lowestIncomeEarner = person;
                }
            }

            // Use the lesser of the incomes for the calculation
            double lowestIncome         = lowestIncomeEarner.WorkIncome;
            double adjustedLowestIncome = (lowestIncome * _constants.EmploymentExpensePercent);

            double employmentExpenseAllowance = adjustedLowestIncome > _constants.EmploymentExpenseMaximum
                ? _constants.EmploymentExpenseMaximum : adjustedLowestIncome;

            return(Math.Round(employmentExpenseAllowance < 0 ? 0 : employmentExpenseAllowance,
                              MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates Net Worth contribution
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="cashSavingsCheckings">Cash, savings, and checkings value</param>
        /// <param name="investmentNetWorth">Net worth of investments</param>
        /// <param name="businessFarmNetWorth">Net worth of business and/or investment farm</param>
        /// <returns>Net Worth contribution</returns>
        public double CalculateNetWorth(
            EfcCalculationRole role,
            double cashSavingsCheckings,
            double investmentNetWorth,
            double businessFarmNetWorth)
        {
            double netWorth = 0;

            netWorth += CalculateCashSavingsCheckingsContribution(cashSavingsCheckings);
            netWorth += CalculateInvestmentNetWorthContribution(investmentNetWorth);
            netWorth += CalculateAdjustedBusinessFarmNetWorthContribution(role, businessFarmNetWorth);

            return(Math.Round(netWorth, MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates Available Income
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="totalIncome">Total income</param>
        /// <param name="totalAllowances">Total allowances</param>
        /// <returns></returns>
        public double CalculateAvailableIncome(EfcCalculationRole role, double totalIncome, double totalAllowances)
        {
            double availableIncome = Math.Round(totalIncome - totalAllowances, MidpointRounding.AwayFromZero);

            // The available income for Dependent Students and Independent Students Without Depends is
            // multiplied by an assessment percent
            if (role == EfcCalculationRole.DependentStudent || role == EfcCalculationRole.IndependentStudentWithoutDependents)
            {
                return availableIncome < 0
                    ? 0
                    : Math.Round(availableIncome * _constants.AiAssessmentPercent, MidpointRounding.AwayFromZero);
            }

            return availableIncome;
        }
Exemple #8
0
        /// <summary>
        /// Calculates Contribution from Adjusted Available Income (AAI)
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="adjustedAvailableIncome">Adjusted Available Income</param>
        /// <returns>"Contribution from AAI"</returns>
        public double CalculateContributionFromAai(EfcCalculationRole role, double adjustedAvailableIncome)
        {
            if (role == EfcCalculationRole.DependentStudent ||
                role == EfcCalculationRole.IndependentStudentWithoutDependents)
            {
                return(Math.Round(adjustedAvailableIncome < 0 ? 0 : adjustedAvailableIncome,
                                  MidpointRounding.AwayFromZero));
            }

            if (adjustedAvailableIncome < _constants.AaiContributionRanges[0])
            {
                return(0);
            }

            int baseRange = 0;
            int index     = 0;

            // Loop through AAIContributionRanges until adjustedAvailableIncome param is within range
            for (int i = 0; i < _constants.AaiContributionRanges.Length; i++)
            {
                index = i;

                // If at end of ranges, set baseAmount to maximum range
                if (i == _constants.AaiContributionRanges.Length - 1)
                {
                    baseRange = _constants.AaiContributionRanges[i];
                    break;
                }

                // If adjustedAvailableIncome is within range
                if (adjustedAvailableIncome < _constants.AaiContributionRanges[i + 1])
                {
                    // If adjustedAvailableIncome is within first range, there is no baseAmount;
                    // otherwise, assign standard baseAmount
                    baseRange = (i == 0) ? 0 : _constants.AaiContributionRanges[i];
                    break;
                }
            }

            // Contribution From AAI =
            //      (Base Amount for Range)
            //          + (((Adjusted Available Income) - (Lowest Value of Range)) * (Percent for Range))
            double contributionFromAai =
                _constants.AaiContributionBases[index]
                + ((adjustedAvailableIncome - baseRange) * (_constants.AaiContributionPercents[index] * 0.01));

            return(Math.Round((contributionFromAai < 0) ? 0 : contributionFromAai, MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates the Adjusted Net Worth of Business/Farm contribution
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="businessFarmNetWorth">Net worth of business and/or investment farm</param>
        /// <returns></returns>
        public double CalculateAdjustedBusinessFarmNetWorthContribution(
            EfcCalculationRole role,
            double businessFarmNetWorth)
        {
            if (role == EfcCalculationRole.DependentStudent)
            {
                return(Math.Round(businessFarmNetWorth < 0 ? 0 : businessFarmNetWorth, MidpointRounding.AwayFromZero));
            }

            int baseRange = 0;

            int index    = 0;
            int maxIndex = _constants.BusinessFarmNetWorthAdjustmentRanges.Length - 1;

            // Loop through BusinessFarmNetWorthAdjustmentContributionRanges until businessFarmNetWorth
            // param is within range
            for (int i = 0; i < _constants.BusinessFarmNetWorthAdjustmentRanges.Length; i++)
            {
                index = i;

                // If at end of ranges, set baseAmount to maximum range
                if (i == maxIndex)
                {
                    baseRange = _constants.BusinessFarmNetWorthAdjustmentRanges[i];
                    break;
                }

                // If businessFarmNetWorth is within range
                if (businessFarmNetWorth < _constants.BusinessFarmNetWorthAdjustmentRanges[i + 1])
                {
                    // If businessFarmNetWorth is within first range, there is no baseAmount
                    // Otherwise, assign standard baseAmount
                    baseRange = (i == 0) ? 0 : _constants.BusinessFarmNetWorthAdjustmentRanges[i];
                    break;
                }
            }

            // Contribution From AAI =
            //      (Base Amount for Range)
            //          + (((Business Farm Net Worth) - (Lowest Value of Range)) * (Percent for Range))
            double adjustedBusinessFarmNetWorth =
                _constants.BusinessFarmNetWorthAdjustmentBases[index]
                + ((businessFarmNetWorth - baseRange)
                   * (_constants.BusinessFarmNetWorthAdjustmentPercents[index] * 0.01));

            return(Math.Round((adjustedBusinessFarmNetWorth < 0) ? 0 : adjustedBusinessFarmNetWorth,
                              MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates Contribution From Assets
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="maritalStatus">Marital Status</param>
        /// <param name="age">Age</param>
        /// <param name="cashSavingsCheckings">Cash, savings, and checkings value</param>
        /// <param name="investmentNetWorth">Net worth of investments</param>
        /// <param name="businessFarmNetWorth">Net worth of business and/or investment farm</param>
        /// <returns>"Contribution From Assets"</returns>
        public double CalculateContributionFromAssets(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            int age,
            double cashSavingsCheckings,
            double investmentNetWorth,
            double businessFarmNetWorth)
        {
            double contributionFromAssets = 0;

            if (role == EfcCalculationRole.DependentStudent)
            {
                contributionFromAssets
                    += CalculateNetWorth(role, cashSavingsCheckings, investmentNetWorth, businessFarmNetWorth);
            }
            else
            {
                contributionFromAssets
                    += CalculateDiscretionaryNetWorth(role, maritalStatus, age, cashSavingsCheckings,
                                                      investmentNetWorth, businessFarmNetWorth);
            }

            double assetRate = 1;

            switch (role)
            {
            case EfcCalculationRole.Parent:
                assetRate = _constants.DependentParentAssetRate;
                break;

            case EfcCalculationRole.DependentStudent:
                assetRate = _constants.DependentStudentAssetRate;
                break;

            case EfcCalculationRole.IndependentStudentWithDependents:
                assetRate = _constants.IndependentWithDependentsAssetRate;
                break;

            case EfcCalculationRole.IndependentStudentWithoutDependents:
                assetRate = _constants.IndependentWithoutDependentsAssetRate;
                break;
            }

            contributionFromAssets *= assetRate;

            return(Math.Round(contributionFromAssets < 0 ? 0 : contributionFromAssets, MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates Contribution From Assets
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="maritalStatus">Marital Status</param>
        /// <param name="age">Age</param>
        /// <param name="cashSavingsCheckings">Cash, savings, and checkings value</param>
        /// <param name="investmentNetWorth">Net worth of investments</param>
        /// <param name="businessFarmNetWorth">Net worth of business and/or investment farm</param>
        /// <returns>"Contribution From Assets"</returns>
        public double CalculateContributionFromAssets(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            int age,
            double cashSavingsCheckings,
            double investmentNetWorth,
            double businessFarmNetWorth)
        {
            double contributionFromAssets = 0;

            if (role == EfcCalculationRole.DependentStudent)
            {
                contributionFromAssets
                    += CalculateNetWorth(role, cashSavingsCheckings, investmentNetWorth, businessFarmNetWorth);
            }
            else
            {
                contributionFromAssets
                    += CalculateDiscretionaryNetWorth(role, maritalStatus, age, cashSavingsCheckings,
                                                        investmentNetWorth, businessFarmNetWorth);
            }

            double assetRate = 1;

            switch (role)
            {
                case EfcCalculationRole.Parent:
                    assetRate = _constants.DependentParentAssetRate;
                    break;

                case EfcCalculationRole.DependentStudent:
                    assetRate = _constants.DependentStudentAssetRate;
                    break;

                case EfcCalculationRole.IndependentStudentWithDependents:
                    assetRate = _constants.IndependentWithDependentsAssetRate;
                    break;

                case EfcCalculationRole.IndependentStudentWithoutDependents:
                    assetRate = _constants.IndependentWithoutDependentsAssetRate;
                    break;
            }

            contributionFromAssets *= assetRate;

            return Math.Round(contributionFromAssets < 0 ? 0 : contributionFromAssets, MidpointRounding.AwayFromZero);
        }
        /// <summary>
        /// Calculates Discretionary Net Worth contribution
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="maritalStatus">Marital Status</param>
        /// <param name="age">Age</param>
        /// <param name="cashSavingsCheckings">Cash, savings, and checkings value</param>
        /// <param name="investmentNetWorth">Net worth of investments</param>
        /// <param name="businessFarmNetWorth">Net worth of business and/or investment farm</param>
        /// <returns>"Discretionary Net Worth" contribution</returns>
        public double CalculateDiscretionaryNetWorth(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            int age,
            double cashSavingsCheckings,
            double investmentNetWorth,
            double businessFarmNetWorth)
        {
            double discretionaryNetWorth = 0;

            discretionaryNetWorth +=
                CalculateNetWorth(role, cashSavingsCheckings, investmentNetWorth, businessFarmNetWorth);

            discretionaryNetWorth -=
                CalculateAssetProtectionAllowance(maritalStatus, age);

            return(Math.Round(discretionaryNetWorth, MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates State and Other Tax allowance
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="stateOfResidency">State of residency</param>
        /// <param name="totalIncome">Total income</param>
        /// <returns>State and Other Tax allowance</returns>
        public double CalculateStateTaxAllowance(
            EfcCalculationRole role,
            UnitedStatesStateOrTerritory stateOfResidency,
            double totalIncome)
        {
            double stateTaxAllowance = 0;

            switch (role)
            {
                // For Parents and Independent Students With Dependents, use the "Parent" State Tax Allowance chart
                case EfcCalculationRole.Parent:
                case EfcCalculationRole.IndependentStudentWithDependents:
                    if (totalIncome < _constants.StateTaxAllowanceIncomeThreshold)
                    {
                        stateTaxAllowance =
                            (_constants.ParentStateTaxAllowancePercents[(int)stateOfResidency] * 0.01) * totalIncome;
                    }
                    else
                    {
                        stateTaxAllowance =
                            ((_constants.ParentStateTaxAllowancePercents[(int)stateOfResidency] - 1) * 0.01)
                                * totalIncome;
                    }
                    break;

                // For Dependent Students and Independent Students Without Dependents, use the "Student" State Tax Allowance chart
                case EfcCalculationRole.DependentStudent:
                case EfcCalculationRole.IndependentStudentWithoutDependents:
                    stateTaxAllowance =
                        (_constants.StudentStateTaxAllowancePercents[(int)stateOfResidency] * 0.01) * totalIncome;
                    break;
            }

            return Math.Round(stateTaxAllowance < 0 ? 0 : stateTaxAllowance, MidpointRounding.AwayFromZero);
        }
        /// <summary>
        /// Calculates "Employmement Expense Allowance"
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="maritalStatus">Marital status</param>
        /// <param name="employablePersons">People capable of employment. Exact definition varies depending on
        /// role. If the role is "Parent", for example, <see cref="employablePersons"/> refers to the parents.
        /// If the role is "IndependentStudent", <see cref="employablePersons"/> refers to the student and
        /// spouse</param>
        /// <returns>"Employment Expense Allowance"</returns>
        public double CalculateEmploymentExpenseAllowance(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            List<HouseholdMember> employablePersons)
        {
            if (employablePersons == null
                || employablePersons.Count == 0
                || (role == EfcCalculationRole.DependentStudent)
                || (role == EfcCalculationRole.IndependentStudentWithoutDependents
                        && maritalStatus == MaritalStatus.SingleSeparatedDivorced))
            {
                return 0;
            }

            // Create a list of working Household Members
            List<HouseholdMember> incomeEarners = new List<HouseholdMember>();

            foreach (HouseholdMember person in employablePersons)
            {
                if (person.IsWorking)
                {
                    incomeEarners.Add(person);
                }
            }

            // Not all of the employable persons are working
            if (incomeEarners.Count != employablePersons.Count)
            {
                return 0;
            }

            HouseholdMember lowestIncomeEarner = incomeEarners[0];
            foreach (HouseholdMember person in incomeEarners)
            {
                if (person.WorkIncome < lowestIncomeEarner.WorkIncome)
                {
                    lowestIncomeEarner = person;
                }
            }

            // Use the lesser of the incomes for the calculation
            double lowestIncome = lowestIncomeEarner.WorkIncome;
            double adjustedLowestIncome = (lowestIncome * _constants.EmploymentExpensePercent);

            double employmentExpenseAllowance = adjustedLowestIncome > _constants.EmploymentExpenseMaximum
                ? _constants.EmploymentExpenseMaximum : adjustedLowestIncome;

            return Math.Round(employmentExpenseAllowance < 0 ? 0 : employmentExpenseAllowance,
                MidpointRounding.AwayFromZero);
        }
        /// <summary>
        /// Calculates Income Protection Allowance
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="maritalStatus">Marital status</param>
        /// <param name="numInCollege">Number in college</param>
        /// <param name="numInHousehold">Number in household</param>
        /// <returns>"Income Protection Allowance"</returns>
        public double CalculateIncomeProtectionAllowance(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            int numInCollege,
            int numInHousehold)
        {
            if (numInCollege > numInHousehold || numInCollege <= 0 || numInHousehold <= 0)
            {
                return 0;
            }

            double incomeProtectionAllowance = 0;

            switch (role)
            {
                case EfcCalculationRole.IndependentStudentWithDependents:
                case EfcCalculationRole.Parent:

                    // Determine the appropriate charts to use for Income Protection Allowance values
                    int[,] incomeProtectionAllowances = (role == EfcCalculationRole.Parent)
                        ? _constants.DependentParentIncomeProtectionAllowances
                        : _constants.IndependentWithDependentsIncomeProtectionAllowances;

                    int additionalStudentAllowance = (role == EfcCalculationRole.Parent)
                        ? _constants.DependentAdditionalStudentAllowance
                        : _constants.IndependentAdditionalStudentAllowance;

                    int additionalFamilyAllowance = (role == EfcCalculationRole.Parent)
                        ? _constants.DependentAdditionalFamilyAllowance
                        : _constants.IndependentAdditionalFamilyAllowance;

                    // If number of children in the household exceeds table range, add additionalFamilyAllowance
                    // for each additional child
                    int maxHouseholdCount = incomeProtectionAllowances.GetLength(0) - 1;
                    int householdCount = numInHousehold;

                    if (numInHousehold > maxHouseholdCount)
                    {
                        // Set number in household to maximum table range
                        householdCount = maxHouseholdCount;
                        incomeProtectionAllowance += (numInHousehold - maxHouseholdCount) * additionalFamilyAllowance;
                    }

                    // If number of children in college exceeds table range, add additionalStudentAllowance
                    // for each additional child
                    int maxCollegeCount = incomeProtectionAllowances.GetLength(1) - 1;
                    int collegeCount = numInCollege;

                    if (numInCollege > maxCollegeCount)
                    {
                        // Set number in college to maximum table range
                        collegeCount = maxCollegeCount;
                        incomeProtectionAllowance -= (numInCollege - maxCollegeCount) * additionalStudentAllowance;
                    }

                    // Add standard incomeProtectionAllowance value
                    incomeProtectionAllowance += incomeProtectionAllowances[householdCount, collegeCount];

                    break;

                case EfcCalculationRole.IndependentStudentWithoutDependents:

                    if (maritalStatus == MaritalStatus.SingleSeparatedDivorced)
                    {
                        incomeProtectionAllowance
                            = _constants.SingleIndependentWithoutDependentsIncomeProtectionAllowance;
                    }
                    else
                    {
                        // If spouse is enrolled at least 1/2 time, then use the Income Protection Allowance value
                        // for Single/Separated/Divorced
                        incomeProtectionAllowance = (numInCollege > 1) ?
                            _constants.SingleIndependentWithoutDependentsIncomeProtectionAllowance
                                : _constants.MarriedIndependentWithoutDependentsIncomeProtectionAllowance;
                    }

                    break;

                case EfcCalculationRole.DependentStudent:

                    incomeProtectionAllowance = _constants.DependentStudentIncomeProtectionAllowance;

                    break;
            }

            return Math.Round(incomeProtectionAllowance < 0 ? 0 : incomeProtectionAllowance,
                MidpointRounding.AwayFromZero);
        }
        /// <summary>
        /// Calculates student contribution (PC) and expected family contribution (EFC) for an independent student
        /// </summary>
        /// <param name="args">Parameters for the calculation</param>
        /// <returns>Student contribution (PC) and expected family contribution (EFC) for an independent student</returns>
        public EfcProfile GetIndependentEfcProfile(IndependentEfcCalculatorArguments args)
        {
            if (args.NumberInCollege <= 0 ||
                args.MonthsOfEnrollment <= 0 ||
                args.Student == null)
            {
                return(new EfcProfile(0, 0, 0, 0));
            }

            EfcCalculationRole role = (args.HasDependents)
                                          ? EfcCalculationRole.IndependentStudentWithDependents
                                          : EfcCalculationRole.IndependentStudentWithoutDependents;

            double workIncome = 0;

            List <HouseholdMember> householdMembers = new List <HouseholdMember> {
                args.Student
            };

            workIncome += args.Student.IsWorking ? args.Student.WorkIncome : 0;

            if (args.Spouse != null)
            {
                if (args.Spouse.IsWorking)
                {
                    workIncome += args.Spouse.WorkIncome;
                }

                householdMembers.Add(args.Spouse);
            }

            double simpleIncome = (args.AreTaxFilers) ? args.AdjustedGrossIncome : workIncome;

            // Determine Auto Zero EFC eligibility
            if (args.IsQualifiedForSimplified &&
                role == EfcCalculationRole.IndependentStudentWithDependents &&
                simpleIncome <= _constants.AutoZeroEfcMax)
            {
                return(new EfcProfile(0, 0, 0, 0));
            }

            // Student's Total Income
            double totalIncome = _incomeCalculator.CalculateTotalIncome(
                args.AdjustedGrossIncome,
                workIncome,
                args.AreTaxFilers,
                args.UntaxedIncomeAndBenefits,
                args.AdditionalFinancialInfo);

            // Student's Total Allowances
            double totalAllowances = _allowanceCalculator.CalculateTotalAllowances(
                role,
                args.MaritalStatus,
                args.StateOfResidency,
                args.NumberInCollege,
                args.NumberInHousehold,
                householdMembers,
                totalIncome,
                args.IncomeTaxPaid);

            // Student's Available Income (Contribution from Available Income)
            double availableIncome = _incomeCalculator.CalculateAvailableIncome(role, totalIncome, totalAllowances);

            // Determine Simplified EFC Equation Eligibility
            bool useSimplified = (args.IsQualifiedForSimplified && simpleIncome <= _constants.SimplifiedEfcMax);

            // Student's Contribution From Assets
            double assetContribution = 0;

            if (!useSimplified)
            {
                assetContribution = _assetContributionCalculator.CalculateContributionFromAssets(
                    role,
                    args.MaritalStatus,
                    args.Age,
                    args.CashSavingsCheckings,
                    args.InvestmentNetWorth,
                    args.BusinessFarmNetWorth);
            }

            // Student's Adjusted Available Income
            double adjustedAvailableIncome = availableIncome + assetContribution;

            // Student Contribution From AAI
            double studentContributionFromAai
                = _aaiContributionCalculator.CalculateContributionFromAai(role, adjustedAvailableIncome);

            // Student's Contribution
            double studentContribution = Math.Round(studentContributionFromAai / args.NumberInCollege,
                                                    MidpointRounding.AwayFromZero);

            // Modify Student's Available Income based on months of enrollment
            if (args.MonthsOfEnrollment < DefaultMonthsOfEnrollment)
            {
                // LESS than default months of enrollment
                double monthlyContribution = Math.Round(studentContribution / DefaultMonthsOfEnrollment);
                studentContribution = monthlyContribution * args.MonthsOfEnrollment;
            }

            // For MORE than default months of enrollment, the standard contribution is used

            EfcProfile profile = new EfcProfile(studentContribution, 0, studentContribution, 0);

            return(profile);
        }
        /// <summary>
        /// Calculates "Employmement Expense Allowance"
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="maritalStatus">Marital status</param>
        /// <param name="employablePersons">People capable of employment. Exact definition varies depending on
        /// role. If the role is "Parent", for example, <see cref="employablePersons"/> refers to the parents.
        /// If the role is "IndependentStudent", <see cref="employablePersons"/> refers to the student and
        /// spouse</param>
        /// <returns>"Employment Expense Allowance"</returns>
        public double CalculateEmploymentExpenseAllowance(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            List<HouseholdMember> employablePersons)
        {
            if (employablePersons == null
                || !employablePersons.Any()
                || (role == EfcCalculationRole.DependentStudent)
                || (role == EfcCalculationRole.IndependentStudentWithoutDependents
                        && maritalStatus == MaritalStatus.SingleSeparatedDivorced))
            {
                return 0;
            }

            IEnumerable<HouseholdMember> incomeEarners
                = employablePersons
                    .Where(ep => ep.IsWorking)
                    .OrderBy(ie => ie.WorkIncome);

            // Not all of the employable persons are working
            if (incomeEarners.Count() != employablePersons.Count())
            {
                return 0;
            }

            // Use the lesser of the incomes for the calculation
            double lowestIncome = incomeEarners.First().WorkIncome;
            double adjustedLowestIncome = (lowestIncome * _constants.EmploymentExpensePercent);

            double employmentExpenseAllowance = adjustedLowestIncome > _constants.EmploymentExpenseMaximum
                ? _constants.EmploymentExpenseMaximum : adjustedLowestIncome;

            return Math.Round(employmentExpenseAllowance < 0 ? 0 : employmentExpenseAllowance,
                MidpointRounding.AwayFromZero);
        }
        /// <summary>
        /// Calculates Net Worth contribution
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="cashSavingsCheckings">Cash, savings, and checkings value</param>
        /// <param name="investmentNetWorth">Net worth of investments</param>
        /// <param name="businessFarmNetWorth">Net worth of business and/or investment farm</param>
        /// <returns>Net Worth contribution</returns>
        public double CalculateNetWorth(
            EfcCalculationRole role,
            double cashSavingsCheckings,
            double investmentNetWorth,
            double businessFarmNetWorth)
        {
            double netWorth = 0;

            netWorth += CalculateCashSavingsCheckingsContribution(cashSavingsCheckings);
            netWorth += CalculateInvestmentNetWorthContribution(investmentNetWorth);
            netWorth += CalculateAdjustedBusinessFarmNetWorthContribution(role, businessFarmNetWorth);

            return Math.Round(netWorth, MidpointRounding.AwayFromZero);
        }
        /// <summary>
        /// Calculates the Adjusted Net Worth of Business/Farm contribution
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="businessFarmNetWorth">Net worth of business and/or investment farm</param>
        /// <returns></returns>
        public double CalculateAdjustedBusinessFarmNetWorthContribution(
            EfcCalculationRole role,
            double businessFarmNetWorth)
        {
            if (role == EfcCalculationRole.DependentStudent)
            {
                return Math.Round(businessFarmNetWorth < 0 ? 0 : businessFarmNetWorth, MidpointRounding.AwayFromZero);
            }

            int baseRange = 0;

            int index = 0;
            int maxIndex = _constants.BusinessFarmNetWorthAdjustmentRanges.Length - 1;

            // Loop through BusinessFarmNetWorthAdjustmentContributionRanges until businessFarmNetWorth
            // param is within range
            for (int i = 0; i < _constants.BusinessFarmNetWorthAdjustmentRanges.Length; i++)
            {
                index = i;

                // If at end of ranges, set baseAmount to maximum range
                if (i == maxIndex)
                {
                    baseRange = _constants.BusinessFarmNetWorthAdjustmentRanges[i];
                    break;
                }

                // If businessFarmNetWorth is within range
                if (businessFarmNetWorth < _constants.BusinessFarmNetWorthAdjustmentRanges[i + 1])
                {
                    // If businessFarmNetWorth is within first range, there is no baseAmount
                    // Otherwise, assign standard baseAmount
                    baseRange = (i == 0) ? 0 : _constants.BusinessFarmNetWorthAdjustmentRanges[i];
                    break;
                }
            }

            // Contribution From AAI = 
            //      (Base Amount for Range)
            //          + (((Business Farm Net Worth) - (Lowest Value of Range)) * (Percent for Range))
            double adjustedBusinessFarmNetWorth =
                _constants.BusinessFarmNetWorthAdjustmentBases[index]
                    + ((businessFarmNetWorth - baseRange)
                    * (_constants.BusinessFarmNetWorthAdjustmentPercents[index] * 0.01));

            return Math.Round((adjustedBusinessFarmNetWorth < 0) ? 0 : adjustedBusinessFarmNetWorth,
                MidpointRounding.AwayFromZero);
        }
Exemple #20
0
        /// <summary>
        /// Calculates Income Protection Allowance
        /// </summary>
        /// <param name="role">Subject's role within the calculation</param>
        /// <param name="maritalStatus">Marital status</param>
        /// <param name="numInCollege">Number in college</param>
        /// <param name="numInHousehold">Number in household</param>
        /// <returns>"Income Protection Allowance"</returns>
        public double CalculateIncomeProtectionAllowance(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            int numInCollege,
            int numInHousehold)
        {
            if (numInCollege > numInHousehold || numInCollege <= 0 || numInHousehold <= 0)
            {
                return(0);
            }

            double incomeProtectionAllowance = 0;

            switch (role)
            {
            case EfcCalculationRole.IndependentStudentWithDependents:
            case EfcCalculationRole.Parent:

                // Determine the appropriate charts to use for Income Protection Allowance values
                int[,] incomeProtectionAllowances = (role == EfcCalculationRole.Parent)
                        ? _constants.DependentParentIncomeProtectionAllowances
                        : _constants.IndependentWithDependentsIncomeProtectionAllowances;

                int additionalStudentAllowance = (role == EfcCalculationRole.Parent)
                        ? _constants.DependentAdditionalStudentAllowance
                        : _constants.IndependentAdditionalStudentAllowance;

                int additionalFamilyAllowance = (role == EfcCalculationRole.Parent)
                        ? _constants.DependentAdditionalFamilyAllowance
                        : _constants.IndependentAdditionalFamilyAllowance;

                // If number of children in the household exceeds table range, add additionalFamilyAllowance
                // for each additional child
                int maxHouseholdCount = incomeProtectionAllowances.GetLength(0) - 1;
                int householdCount    = numInHousehold;

                if (numInHousehold > maxHouseholdCount)
                {
                    // Set number in household to maximum table range
                    householdCount             = maxHouseholdCount;
                    incomeProtectionAllowance += (numInHousehold - maxHouseholdCount) * additionalFamilyAllowance;
                }

                // If number of children in college exceeds table range, add additionalStudentAllowance
                // for each additional child
                int maxCollegeCount = incomeProtectionAllowances.GetLength(1) - 1;
                int collegeCount    = numInCollege;

                if (numInCollege > maxCollegeCount)
                {
                    // Set number in college to maximum table range
                    collegeCount = maxCollegeCount;
                    incomeProtectionAllowance -= (numInCollege - maxCollegeCount) * additionalStudentAllowance;
                }

                // Add standard incomeProtectionAllowance value
                incomeProtectionAllowance += incomeProtectionAllowances[householdCount, collegeCount];

                break;

            case EfcCalculationRole.IndependentStudentWithoutDependents:

                if (maritalStatus == MaritalStatus.SingleSeparatedDivorced)
                {
                    incomeProtectionAllowance
                        = _constants.SingleIndependentWithoutDependentsIncomeProtectionAllowance;
                }
                else
                {
                    // If spouse is enrolled at least 1/2 time, then use the Income Protection Allowance value
                    // for Single/Separated/Divorced
                    incomeProtectionAllowance = (numInCollege > 1) ?
                                                _constants.SingleIndependentWithoutDependentsIncomeProtectionAllowance
                                : _constants.MarriedIndependentWithoutDependentsIncomeProtectionAllowance;
                }

                break;

            case EfcCalculationRole.DependentStudent:

                incomeProtectionAllowance = _constants.DependentStudentIncomeProtectionAllowance;

                break;
            }

            return(Math.Round(incomeProtectionAllowance < 0 ? 0 : incomeProtectionAllowance,
                              MidpointRounding.AwayFromZero));
        }
        /// <summary>
        /// Calculates Discretionary Net Worth contribution
        /// </summary>
        /// <param name="role">Role of the subject within the calculation</param>
        /// <param name="maritalStatus">Marital Status</param>
        /// <param name="age">Age</param>
        /// <param name="cashSavingsCheckings">Cash, savings, and checkings value</param>
        /// <param name="investmentNetWorth">Net worth of investments</param>
        /// <param name="businessFarmNetWorth">Net worth of business and/or investment farm</param>
        /// <returns>"Discretionary Net Worth" contribution</returns>
        public double CalculateDiscretionaryNetWorth(
            EfcCalculationRole role,
            MaritalStatus maritalStatus,
            int age,
            double cashSavingsCheckings,
            double investmentNetWorth,
            double businessFarmNetWorth)
        {
            double discretionaryNetWorth = 0;

            discretionaryNetWorth +=
                CalculateNetWorth(role, cashSavingsCheckings, investmentNetWorth, businessFarmNetWorth);

            discretionaryNetWorth -=
                CalculateAssetProtectionAllowance(maritalStatus, age);

            return Math.Round(discretionaryNetWorth, MidpointRounding.AwayFromZero);
        }