diff --git a/extra/taxes/authors.txt b/extra/taxes/authors.txt new file mode 100644 index 0000000000..7c1b2f2279 --- /dev/null +++ b/extra/taxes/authors.txt @@ -0,0 +1 @@ +Doug Coleman diff --git a/extra/taxes/summary.txt b/extra/taxes/summary.txt new file mode 100644 index 0000000000..e983139ccb --- /dev/null +++ b/extra/taxes/summary.txt @@ -0,0 +1 @@ +Calculate federal and state tax withholdings diff --git a/extra/taxes/taxes-tests.factor b/extra/taxes/taxes-tests.factor new file mode 100644 index 0000000000..4091156558 --- /dev/null +++ b/extra/taxes/taxes-tests.factor @@ -0,0 +1,98 @@ +USING: kernel money taxes tools.test ; +IN: temporary + +[ + 426 23 +] [ + 12000 2008 3 f net biweekly + dollars/cents +] unit-test + +[ + 426 23 +] [ + 12000 2008 3 t net biweekly + dollars/cents +] unit-test + +[ + 684 4 +] [ + 20000 2008 3 f net biweekly + dollars/cents +] unit-test + + + +[ + 804 58 +] [ + 24000 2008 3 f net biweekly + dollars/cents +] unit-test + +[ + 831 31 +] [ + 24000 2008 3 t net biweekly + dollars/cents +] unit-test + + +[ + 780 81 +] [ + 24000 2008 3 f net biweekly + dollars/cents +] unit-test + +[ + 818 76 +] [ + 24000 2008 3 t net biweekly + dollars/cents +] unit-test + + +[ + 2124 39 +] [ + 78250 2008 3 f net biweekly + dollars/cents +] unit-test + +[ + 2321 76 +] [ + 78250 2008 3 t net biweekly + dollars/cents +] unit-test + + +[ + 2612 63 +] [ + 100000 2008 3 f net biweekly + dollars/cents +] unit-test + +[ + 22244 52 +] [ + 1000000 2008 3 f net biweekly + dollars/cents +] unit-test + +[ + 578357 40 +] [ + 1000000 2008 3 f net + dollars/cents +] unit-test + +[ + 588325 41 +] [ + 1000000 2008 3 t net + dollars/cents +] unit-test diff --git a/extra/taxes/taxes.factor b/extra/taxes/taxes.factor new file mode 100644 index 0000000000..0f51d7ab6a --- /dev/null +++ b/extra/taxes/taxes.factor @@ -0,0 +1,140 @@ +USING: arrays assocs kernel math math.intervals namespaces +sequences combinators.lib money ; +IN: taxes + +: monthly ( x -- y ) 12 / ; +: semimonthly ( x -- y ) 24 / ; +: biweekly ( x -- y ) 26 / ; +: weekly ( x -- y ) 52 / ; +: daily ( x -- y ) 360 / ; + +! Each employee fills out a w4 +TUPLE: w4 year allowances married? ; +C: w4 + +: allowance ( -- x ) 3500 ; inline + +: calculate-w4-allowances ( w4 -- x ) + w4-allowances allowance * ; + +! Withhold: FICA, Medicare, Federal (FICA is social security) +: fica-tax-rate ( -- x ) DECIMAL: .062 ; inline + +! Base rate -- income over this rate is not taxed +TUPLE: fica-base-unknown ; +: fica-base-rate ( year -- x ) + H{ + { 2008 102000 } + { 2007 97500 } + } at* [ T{ fica-base-unknown } throw ] unless ; + +: fica-tax ( salary w4 -- x ) + w4-year fica-base-rate min fica-tax-rate * ; + +! Employer tax only, not withheld +: futa-tax-rate ( -- x ) DECIMAL: .062 ; inline + +! No base rate for medicare; all wages subject +: medicare-tax-rate ( -- x ) DECIMAL: .0145 ; inline +: medicare-tax ( salary w4 -- x ) drop medicare-tax-rate * ; + +MIXIN: collector +GENERIC: adjust-allowances ( salary w4 collector -- newsalary ) +GENERIC: withholding ( salary w4 collector -- x ) +GENERIC: net ( salary w4 collector -- x ) + +TUPLE: tax-table single married ; + +: ( single married class -- obj ) + >r tax-table construct-boa r> construct-delegate ; + +: tax-bracket-range dup second swap first - ; + +: tax-bracket ( tax salary triples -- tax salary ) + [ [ tax-bracket-range min ] keep third * + ] 2keep + tax-bracket-range [-] ; + +: tax ( salary triples -- x ) + 0 -rot [ tax-bracket ] each drop ; + +: marriage-table ( w4 tax-table -- triples ) + swap w4-married? + [ tax-table-married ] [ tax-table-single ] if ; + +: federal-tax ( salary w4 tax-table -- n ) + [ adjust-allowances ] 2keep marriage-table tax ; + +! http://www.irs.gov/pub/irs-pdf/p15.pdf +! Table 7 ANNUAL Payroll Period + +: federal-single ( -- triples ) + { + { 0 2650 DECIMAL: 0 } + { 2650 10300 DECIMAL: .10 } + { 10300 33960 DECIMAL: .15 } + { 33960 79725 DECIMAL: .25 } + { 79725 166500 DECIMAL: .28 } + { 166500 359650 DECIMAL: .33 } + { 359650 1/0. DECIMAL: .35 } + } ; + +: federal-married ( -- triples ) + { + { 0 8000 DECIMAL: 0 } + { 8000 23550 DECIMAL: .10 } + { 23550 72150 DECIMAL: .15 } + { 72150 137850 DECIMAL: .25 } + { 137850 207700 DECIMAL: .28 } + { 207700 365100 DECIMAL: .33 } + { 365100 1/0. DECIMAL: .35 } + } ; + +TUPLE: federal ; +INSTANCE: federal collector +: ( -- obj ) + federal-single federal-married federal ; + +M: federal adjust-allowances ( salary w4 collector -- newsalary ) + drop calculate-w4-allowances - ; + +M: federal withholding ( salary w4 tax-table -- x ) + [ federal-tax ] 3keep drop + [ fica-tax ] 2keep + medicare-tax + + ; + +M: federal net ( salary w4 collector -- x ) + >r dupd r> withholding - ; + +M: collector net ( salary w4 collector -- x ) + >r dupd r> + [ withholding ] 3keep + drop withholding + - ; + + +! Minnesota +: minnesota-single ( -- triples ) + { + { 0 1950 DECIMAL: 0 } + { 1950 23750 DECIMAL: .0535 } + { 23750 73540 DECIMAL: .0705 } + { 73540 1/0. DECIMAL: .0785 } + } ; + +: minnesota-married ( -- triples ) + { + { 0 7400 DECIMAL: 0 } + { 7400 39260 DECIMAL: .0535 } + { 39260 133980 DECIMAL: .0705 } + { 133980 1/0. DECIMAL: .0785 } + } ; + +TUPLE: minnesota ; +INSTANCE: minnesota collector +: ( -- obj ) + minnesota-single minnesota-married minnesota ; + +M: minnesota adjust-allowances ( salary w4 collector -- newsalary ) + drop calculate-w4-allowances - ; + +M: minnesota withholding ( salary w4 collector -- x ) + [ adjust-allowances ] 2keep marriage-table tax ;