diff --git a/src/TaxTools.Core/TaxLimitation/CalculationParameters.cs b/src/TaxTools.Core/TaxLimitation/CalculationParameters.cs index e89e43a..85aee57 100644 --- a/src/TaxTools.Core/TaxLimitation/CalculationParameters.cs +++ b/src/TaxTools.Core/TaxLimitation/CalculationParameters.cs @@ -4,7 +4,8 @@ public class CalculationParameters { public int ExemptionQualifyYear { get; set; } public int CalculationYear { get; set; } - public bool EnableSB2Calculation { get; set; } + public bool EnableSB4Calculation { get; set; } + public bool EnableSB23Calculation { get; set; } public Dictionary YearDetails { get; } public CalculationParameters() diff --git a/src/TaxTools.Core/TaxLimitation/CalculationResult.cs b/src/TaxTools.Core/TaxLimitation/CalculationResult.cs index 81f2b93..9075641 100644 --- a/src/TaxTools.Core/TaxLimitation/CalculationResult.cs +++ b/src/TaxTools.Core/TaxLimitation/CalculationResult.cs @@ -13,10 +13,18 @@ public class CalculationResultDetail public decimal AdditionalImprovement { get; set; } public int TaxableValue { get; set; } public decimal SB12Reduction { get; set; } + //2023 only public decimal? SB2Reduction { get; set; } - public decimal RunningTotal => Math.Max(StartingAmount + AdditionalImprovement - SB12Reduction - (SB2Reduction ?? 0), 0); + //2025 only + public decimal? SB4Reduction { get; set; } + //2025 only + public decimal? SB23Reduction { get; set; } + public decimal RunningTotal => Math.Max(StartingAmount + AdditionalImprovement - SB12Reduction + - (SB2Reduction ?? 0) - (SB4Reduction ?? 0) - (SB23Reduction ?? 0), 0); public string SB12CalculationText { get; set; } public string SB2CalculationText { get; set; } + public string SB4CalculationText { get; set; } + public string SB23CalculationText { get; set; } } } diff --git a/src/TaxTools.Core/TaxLimitation/Calculator.cs b/src/TaxTools.Core/TaxLimitation/Calculator.cs index aaae8e2..bd7a818 100644 --- a/src/TaxTools.Core/TaxLimitation/Calculator.cs +++ b/src/TaxTools.Core/TaxLimitation/Calculator.cs @@ -65,31 +65,79 @@ private static CalculationResultDetail CalculateYear(CalculationParameters param } else { - if (!parameters.EnableSB2Calculation || parameters.CalculationYear != 2023) - return result; - - var sb = new StringBuilder(); - if (parameters.ExemptionQualifyYear < 2022) - { - var prevYear = parameters.YearDetails[year - 1]; - var exemptAmount = 15000 * (prevYear.OwnershipPercent / 100); - result.SB2Reduction = Math.Round(exemptAmount * prevYear.TaxRate / 100, 2); - sb.Append($"({exemptAmount:N0} x {prevYear.TaxRate} / 100) + "); - } - if (parameters.ExemptionQualifyYear < 2023) + switch (parameters.CalculationYear) { - var exemptAmount = 60000 * (curYear.OwnershipPercent / 100); - var sb2Amount = Math.Round(exemptAmount * curYear.TaxRate / 100, 2); - if (result.SB2Reduction == null) - result.SB2Reduction = sb2Amount; - else - result.SB2Reduction += sb2Amount; - sb.Append($"({exemptAmount:N0} x {curYear.TaxRate} / 100)"); + case 2023: + Handle2023Calculation(parameters, year, result, curYear); + break; + case 2025: + Handle2025Calculation(parameters, result, curYear); + break; } - result.SB2CalculationText = sb.ToString(); } return result; } + + private static void Handle2023Calculation(CalculationParameters parameters, int year, CalculationResultDetail result, + CalculationParameterYearDetail curYear) + { + var sb = new StringBuilder(); + if (parameters.ExemptionQualifyYear < 2022) + { + var prevYear = parameters.YearDetails[year - 1]; + var exemptAmount = 15000 * (prevYear.OwnershipPercent / 100); + result.SB2Reduction = Math.Round(exemptAmount * prevYear.TaxRate / 100, 2); + sb.Append($"({exemptAmount:N0} x {prevYear.TaxRate} / 100) + "); + } + + if (parameters.ExemptionQualifyYear < 2023) + { + var exemptAmount = 60000 * (curYear.OwnershipPercent / 100); + var sb2Amount = Math.Round(exemptAmount * curYear.TaxRate / 100, 2); + if (result.SB2Reduction == null) + result.SB2Reduction = sb2Amount; + else + result.SB2Reduction += sb2Amount; + sb.Append($"({exemptAmount:N0} x {curYear.TaxRate} / 100)"); + } + + result.SB2CalculationText = sb.ToString(); + } + + private static void Handle2025Calculation(CalculationParameters parameters, CalculationResultDetail result, + CalculationParameterYearDetail curYear) + { + if (parameters.ExemptionQualifyYear > 2024) + return; + + if (parameters.EnableSB4Calculation) + { + var sb = new StringBuilder(); + var exemptAmount = 40000 * (curYear.OwnershipPercent / 100); + var amount = Math.Round(exemptAmount * curYear.TaxRate / 100, 2); + if (result.SB4Reduction == null) + result.SB4Reduction = amount; + else + result.SB4Reduction += amount; + sb.Append($"({exemptAmount:N0} x {curYear.TaxRate} / 100)"); + + result.SB4CalculationText = sb.ToString(); + } + + if (parameters.EnableSB23Calculation) + { + var sb = new StringBuilder(); + var exemptAmount = 50000 * (curYear.OwnershipPercent / 100); + var amount = Math.Round(exemptAmount * curYear.TaxRate / 100, 2); + if (result.SB23Reduction == null) + result.SB23Reduction = amount; + else + result.SB23Reduction += amount; + sb.Append($"({exemptAmount:N0} x {curYear.TaxRate} / 100)"); + + result.SB23CalculationText = sb.ToString(); + } + } } } diff --git a/src/TaxTools/Pages/TaxLimitationCalculator/DetailModel.cs b/src/TaxTools/Pages/TaxLimitationCalculator/DetailModel.cs index 09bbfa1..ee440d5 100644 --- a/src/TaxTools/Pages/TaxLimitationCalculator/DetailModel.cs +++ b/src/TaxTools/Pages/TaxLimitationCalculator/DetailModel.cs @@ -23,8 +23,9 @@ public class DetailModel public bool MCRPopulated { get; set; } public bool TaxRatePopulated { get; set; } - public bool RequireSB2Data => _parent.EnableSB2Calculation && - (( _parent.ExemptionQualifyYear <= 2022 && Year == 2023) || (_parent.ExemptionQualifyYear <= 2021 && Year == 2022)); + public bool RequireAdditionalData => (_parent.ExemptionQualifyYear <= 2022 && Year == 2023) + || (_parent.ExemptionQualifyYear <= 2021 && Year == 2022) + || (_parent.ExemptionQualifyYear <= 2024 && Year == 2025 && (_parent.EnableSB4Calculation || _parent.EnableSB23Calculation)); public DetailModel(CalculatorModel parent, int year) { @@ -45,7 +46,8 @@ public class CalculatorModel [Range(1900, 2050, ErrorMessage = "Exemption Qualify Year must be greater than 1900")] public int ExemptionQualifyYear { get; set; } - public bool EnableSB2Calculation { get; set; } + public bool EnableSB4Calculation { get; set; } + public bool EnableSB23Calculation { get; set; } [ValidateComplexType] public List Details { get; set; } @@ -53,8 +55,9 @@ public class CalculatorModel public CalculatorModel() { Details = new List(); - EnableSB2Calculation = true; - TaxYear = 2023; + EnableSB4Calculation = true; + EnableSB23Calculation = true; + TaxYear = 2024; } } } diff --git a/src/TaxTools/Pages/TaxLimitationCalculator/Index.razor b/src/TaxTools/Pages/TaxLimitationCalculator/Index.razor index 7d74b34..5ab3641 100644 --- a/src/TaxTools/Pages/TaxLimitationCalculator/Index.razor +++ b/src/TaxTools/Pages/TaxLimitationCalculator/Index.razor @@ -14,7 +14,6 @@ } else { - @@ -23,10 +22,13 @@ else
-

This tool has been provided by Spindlemedia to aid in understanding the tax limitation calculation.

+

This tool has been provided by Spindlemedia to aid in understanding the tax limitation calculation. For any feedback please email us at contact@spindlemedia.com.

+
+
+

Preliminary 2025 support for SB4 and SB23 has been added.

-

New for 2024: For multi-owner accounts, you must enter just the homesite taxable value for the ceiling owner(s)

+

For multi-owner accounts, you must enter just the homesite taxable value for the ceiling owner(s)

Steps: diff --git a/src/TaxTools/Pages/TaxLimitationCalculator/LimitationCalculator.razor b/src/TaxTools/Pages/TaxLimitationCalculator/LimitationCalculator.razor index 9a250b0..d9bb56e 100644 --- a/src/TaxTools/Pages/TaxLimitationCalculator/LimitationCalculator.razor +++ b/src/TaxTools/Pages/TaxLimitationCalculator/LimitationCalculator.razor @@ -5,6 +5,23 @@ + @if (_model.TaxYear == 2025) + { +

+
+ + +
+
+ +
+
+ + +
+
+ } +
@if (_model.DistrictId is null) @@ -59,36 +76,30 @@ }
- @if (_model.EnableSB2Calculation) - { -
- @if (detail.RequireSB2Data) - { -
- - -
- } -
- } +
+ @if (detail.RequireAdditionalData) + { +
+ + +
+ } +
- @if (_model.EnableSB2Calculation) - { -
- @if (detail.RequireSB2Data) - { -
- - -
- } -
- } +
+ @if (detail.RequireAdditionalData) + { +
+ + +
+ } +
} @@ -106,10 +117,15 @@ Ceiling Adjustments Taxable Value SB 12 Reduction - @if (_model.EnableSB2Calculation) + @if (_model.TaxYear == 2023) { SB 2 Reduction } + else if (_model.TaxYear == 2025) + { + SB 4 Reduction + SB 23 Reduction + } Running Total @@ -117,50 +133,46 @@ @for (var i = 0; i < _calculationResult.Details.Count; i++) { var detail = _calculationResult.Details[i]; - if (i < _calculationResult.Details.Count - 1) - { - - @detail.Year - @detail.StartingAmount.ToString("C2") - @(i == 0 ? "N/A" : detail.AdditionalImprovement.ToString("C2")) - @(detail.TaxableValue.ToString("N0")) - @detail.SB12Reduction.ToString("C2") - @if (_model.EnableSB2Calculation) + var firstOrFinal = i == 0 || i == _calculationResult.Details.Count - 1; + + + @detail.Year + @detail.StartingAmount.ToString("C2") + @(firstOrFinal ? "N/A" : detail.AdditionalImprovement.ToString("C2")) + @(firstOrFinal ? "N/A" : detail.TaxableValue.ToString("N0")) + @detail.SB12Reduction.ToString("C2") + @if (_model.TaxYear == 2023) + { + if (detail.SB2Reduction.HasValue) { - if (detail.SB2Reduction.HasValue) - { - @detail.SB2Reduction.Value.ToString("C2") - } - else - { - N/A - } + @detail.SB2Reduction.Value.ToString("C2") } - @detail.RunningTotal.ToString("C2") - - } - else - { - - @detail.Year - @detail.StartingAmount.ToString("C2") - @detail.AdditionalImprovement.ToString("C2") - N/A - N/A - @if (_model.EnableSB2Calculation) + else { - if (detail.SB2Reduction.HasValue) - { - @detail.SB2Reduction.Value.ToString("C2") - } - else - { - N/A - } + N/A } - @detail.RunningTotal.ToString("C2") - - } + } + else if (_model.TaxYear == 2025) + { + if (detail.SB4Reduction.HasValue) + { + @detail.SB4Reduction.Value.ToString("C2") + } + else + { + N/A + } + if (detail.SB23Reduction.HasValue) + { + @detail.SB23Reduction.Value.ToString("C2") + } + else + { + N/A + } + } + @detail.RunningTotal.ToString("C2") + } @@ -252,7 +264,8 @@ { ExemptionQualifyYear = _model.ExemptionQualifyYear, CalculationYear = _model.TaxYear, - EnableSB2Calculation = _model.EnableSB2Calculation + EnableSB4Calculation = _model.EnableSB4Calculation, + EnableSB23Calculation = _model.EnableSB23Calculation }; foreach (var detail in _model.Details) diff --git a/src/TaxTools/Pages/TaxLimitationCalculator/TaxRateConditionallyRequired.cs b/src/TaxTools/Pages/TaxLimitationCalculator/TaxRateConditionallyRequired.cs index 341ae8a..fafd01f 100644 --- a/src/TaxTools/Pages/TaxLimitationCalculator/TaxRateConditionallyRequired.cs +++ b/src/TaxTools/Pages/TaxLimitationCalculator/TaxRateConditionallyRequired.cs @@ -7,7 +7,7 @@ public class TaxRateConditionallyRequired : ValidationAttribute protected override ValidationResult IsValid(object value, ValidationContext context) { var model = (DetailModel)context.ObjectInstance; - if (!model.RequireSB2Data) + if (!model.RequireAdditionalData) return ValidationResult.Success; var taxRate = value as decimal?;