Created
September 23, 2011 12:18
-
-
Save dotjosh/1237210 to your computer and use it in GitHub Desktop.
Ayende blog tax solution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using NUnit.Framework; | |
namespace TaxAyende | |
{ | |
internal class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var taxableAmount = new TaxCalculator().CalculateTax(17000); | |
Console.WriteLine(taxableAmount); | |
Console.ReadLine(); | |
} | |
} | |
public class TaxCalculator | |
{ | |
private static TaxRate[] _taxRates = new[] | |
{ | |
TaxRate.Create(10, 0, 5070), | |
TaxRate.Create(14, 5070, 8660), | |
TaxRate.Create(23, 8660, 14070), | |
TaxRate.Create(30, 14070, 21240), | |
TaxRate.Create(33, 21240, 40230), | |
TaxRate.Create(45, 40230, decimal.MaxValue) | |
}; | |
public decimal CalculateTax(decimal amount) | |
{ | |
return _taxRates.Sum(tr => tr.TaxableAmount(amount)); | |
} | |
} | |
public class TaxRate | |
{ | |
public decimal Percentage { get; set; } | |
public decimal Min { get; set; } | |
public decimal Max { get; set; } | |
public static TaxRate Create(decimal percentage, decimal min, decimal max) | |
{ | |
return new TaxRate { Percentage = percentage, Min = min, Max = max }; | |
} | |
private decimal LargestTaxableAmount | |
{ | |
get { return Max - Min; } | |
} | |
public decimal TaxableAmount(decimal amount) | |
{ | |
return amount >= Min | |
? Percentage * .01m * Math.Min(amount - Min, LargestTaxableAmount) | |
: 0; | |
} | |
} | |
[TestFixture] | |
public class Tests | |
{ | |
[Test] | |
public void Tax10() | |
{ | |
var calc = new TaxCalculator(); | |
decimal tax = calc.CalculateTax(5000); | |
Assert.AreEqual(500, tax); | |
} | |
[Test] | |
public void Tax14() | |
{ | |
var calc = new TaxCalculator(); | |
decimal tax = calc.CalculateTax(5800); | |
Assert.AreEqual(609.2m, tax); | |
} | |
[Test] | |
public void Tax23() | |
{ | |
var calc = new TaxCalculator(); | |
decimal tax = calc.CalculateTax(9000); | |
Assert.AreEqual(1087.8m, tax); | |
} | |
[Test] | |
public void Tax30() | |
{ | |
var calc = new TaxCalculator(); | |
decimal tax = calc.CalculateTax(15000); | |
Assert.AreEqual(2532.9m, tax); | |
} | |
[Test] | |
public void Tax45() | |
{ | |
var calc = new TaxCalculator(); | |
decimal tax = calc.CalculateTax(50000); | |
Assert.AreEqual(15068.1m, tax); | |
} | |
} | |
} |
Well from a domain/business perspective, the original tax ranges were correct e.g. the 14% tax rate would not include 5070), So that would be the better way to define the tax rate table for our business users, that table would probably map directly to some configuration screen in the UI.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Exactly, it should be 5070 up to 8660. well it should actually be x > 5070 & x <= 8660 makes more sence. I guess I'm just being painfull. :)