python-taxes 0.1.0__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,309 @@
1
+ from decimal import Decimal
2
+
3
+ from .. import MAX, RateRow
4
+
5
+ standard_schedule = {
6
+ 2023: [
7
+ RateRow(
8
+ min=Decimal("0.00"),
9
+ max=Decimal("14799.99"),
10
+ withhold_amount=Decimal("0.00"),
11
+ percent=0,
12
+ ),
13
+ RateRow(
14
+ min=Decimal("14800.00"),
15
+ max=Decimal("36799.99"),
16
+ withhold_amount=Decimal("0.00"),
17
+ percent=10,
18
+ ),
19
+ RateRow(
20
+ min=Decimal("36800.00"),
21
+ max=Decimal("104249.99"),
22
+ withhold_amount=Decimal("2200.00"),
23
+ percent=12,
24
+ ),
25
+ RateRow(
26
+ min=Decimal("104250.00"),
27
+ max=Decimal("205549.99"),
28
+ withhold_amount=Decimal("10294.00"),
29
+ percent=22,
30
+ ),
31
+ RateRow(
32
+ min=Decimal("205550.00"),
33
+ max=Decimal("378999.99"),
34
+ withhold_amount=Decimal("32580.00"),
35
+ percent=24,
36
+ ),
37
+ RateRow(
38
+ min=Decimal("379000.00"),
39
+ max=Decimal("477299.99"),
40
+ withhold_amount=Decimal("74208.00"),
41
+ percent=32,
42
+ ),
43
+ RateRow(
44
+ min=Decimal("477300.00"),
45
+ max=Decimal("708549.99"),
46
+ withhold_amount=Decimal("105664.00"),
47
+ percent=35,
48
+ ),
49
+ RateRow(
50
+ min=Decimal("708550.00"),
51
+ max=MAX,
52
+ withhold_amount=Decimal("186601.50"),
53
+ percent=37,
54
+ ),
55
+ ],
56
+ 2024: [
57
+ RateRow(
58
+ min=Decimal("0.00"),
59
+ max=Decimal("16299.99"),
60
+ withhold_amount=Decimal("0.00"),
61
+ percent=0,
62
+ ),
63
+ RateRow(
64
+ min=Decimal("16300.00"),
65
+ max=Decimal("39499.99"),
66
+ withhold_amount=Decimal("0.00"),
67
+ percent=10,
68
+ ),
69
+ RateRow(
70
+ min=Decimal("39500.00"),
71
+ max=Decimal("110599.99"),
72
+ withhold_amount=Decimal("2320.00"),
73
+ percent=12,
74
+ ),
75
+ RateRow(
76
+ min=Decimal("110600.00"),
77
+ max=Decimal("217349.99"),
78
+ withhold_amount=Decimal("10852.00"),
79
+ percent=22,
80
+ ),
81
+ RateRow(
82
+ min=Decimal("217350.00"),
83
+ max=Decimal("400199.99"),
84
+ withhold_amount=Decimal("34337.00"),
85
+ percent=24,
86
+ ),
87
+ RateRow(
88
+ min=Decimal("400200.00"),
89
+ max=Decimal("503749.99"),
90
+ withhold_amount=Decimal("78221.00"),
91
+ percent=32,
92
+ ),
93
+ RateRow(
94
+ min=Decimal("503750.00"),
95
+ max=Decimal("747499.99"),
96
+ withhold_amount=Decimal("111357.00"),
97
+ percent=35,
98
+ ),
99
+ RateRow(
100
+ min=Decimal("747500.00"),
101
+ max=MAX,
102
+ withhold_amount=Decimal("196669.50"),
103
+ percent=37,
104
+ ),
105
+ ],
106
+ 2025: [
107
+ RateRow(
108
+ min=Decimal("0.00"),
109
+ max=Decimal("17099.99"),
110
+ withhold_amount=Decimal("0.00"),
111
+ percent=0,
112
+ ),
113
+ RateRow(
114
+ min=Decimal("17100.00"),
115
+ max=Decimal("40949.9"),
116
+ withhold_amount=Decimal("0.00"),
117
+ percent=10,
118
+ ),
119
+ RateRow(
120
+ min=Decimal("40950.00"),
121
+ max=Decimal("114049.9"),
122
+ withhold_amount=Decimal("2385.00"),
123
+ percent=12,
124
+ ),
125
+ RateRow(
126
+ min=Decimal("114050.00"),
127
+ max=Decimal("223799.9"),
128
+ withhold_amount=Decimal("11157.00"),
129
+ percent=22,
130
+ ),
131
+ RateRow(
132
+ min=Decimal("223800.00"),
133
+ max=Decimal("411699.9"),
134
+ withhold_amount=Decimal("35302.00"),
135
+ percent=24,
136
+ ),
137
+ RateRow(
138
+ min=Decimal("411700.00"),
139
+ max=Decimal("518149.9"),
140
+ withhold_amount=Decimal("80398.00"),
141
+ percent=32,
142
+ ),
143
+ RateRow(
144
+ min=Decimal("518150.00"),
145
+ max=Decimal("768699.99"),
146
+ withhold_amount=Decimal("114462.00"),
147
+ percent=35,
148
+ ),
149
+ RateRow(
150
+ min=Decimal("768700.00"),
151
+ max=MAX,
152
+ withhold_amount=Decimal("202154.50"),
153
+ percent=37,
154
+ ),
155
+ ],
156
+ }
157
+
158
+ multiple_jobs = {
159
+ 2023: [
160
+ RateRow(
161
+ min=Decimal("0.00"),
162
+ max=Decimal("13849.99"),
163
+ withhold_amount=Decimal("0.00"),
164
+ percent=0,
165
+ ),
166
+ RateRow(
167
+ min=Decimal("13850.00"),
168
+ max=Decimal("24849.99"),
169
+ withhold_amount=Decimal("0.00"),
170
+ percent=10,
171
+ ),
172
+ RateRow(
173
+ min=Decimal("24850.00"),
174
+ max=Decimal("58574.99"),
175
+ withhold_amount=Decimal("1100.00"),
176
+ percent=12,
177
+ ),
178
+ RateRow(
179
+ min=Decimal("58575.00"),
180
+ max=Decimal("109224.99"),
181
+ withhold_amount=Decimal("5147.00"),
182
+ percent=22,
183
+ ),
184
+ RateRow(
185
+ min=Decimal("109225.00"),
186
+ max=Decimal("195949.99"),
187
+ withhold_amount=Decimal("16290.00"),
188
+ percent=24,
189
+ ),
190
+ RateRow(
191
+ min=Decimal("195950.00"),
192
+ max=Decimal("245099.99"),
193
+ withhold_amount=Decimal("37104.00"),
194
+ percent=32,
195
+ ),
196
+ RateRow(
197
+ min=Decimal("245100.00"),
198
+ max=Decimal("360724.99"),
199
+ withhold_amount=Decimal("52832.00"),
200
+ percent=35,
201
+ ),
202
+ RateRow(
203
+ min=Decimal("360725.00"),
204
+ max=MAX,
205
+ withhold_amount=Decimal("93300.75"),
206
+ percent=37,
207
+ ),
208
+ ],
209
+ 2024: [
210
+ RateRow(
211
+ min=Decimal("0.00"),
212
+ max=Decimal("14599.99"),
213
+ withhold_amount=Decimal("0.00"),
214
+ percent=0,
215
+ ),
216
+ RateRow(
217
+ min=Decimal("14600.00"),
218
+ max=Decimal("26199.99"),
219
+ withhold_amount=Decimal("0.00"),
220
+ percent=10,
221
+ ),
222
+ RateRow(
223
+ min=Decimal("26200.00"),
224
+ max=Decimal("61749.99"),
225
+ withhold_amount=Decimal("1160.00"),
226
+ percent=12,
227
+ ),
228
+ RateRow(
229
+ min=Decimal("61750.00"),
230
+ max=Decimal("115124.99"),
231
+ withhold_amount=Decimal("5426.00"),
232
+ percent=22,
233
+ ),
234
+ RateRow(
235
+ min=Decimal("115125.00"),
236
+ max=Decimal("206549.99"),
237
+ withhold_amount=Decimal("17168.50"),
238
+ percent=24,
239
+ ),
240
+ RateRow(
241
+ min=Decimal("206550.00"),
242
+ max=Decimal("258324.99"),
243
+ withhold_amount=Decimal("39110.50"),
244
+ percent=32,
245
+ ),
246
+ RateRow(
247
+ min=Decimal("258325.00"),
248
+ max=Decimal("380199.99"),
249
+ withhold_amount=Decimal("55678.50"),
250
+ percent=35,
251
+ ),
252
+ RateRow(
253
+ min=Decimal("380200.00"),
254
+ max=MAX,
255
+ withhold_amount=Decimal("98334.75"),
256
+ percent=37,
257
+ ),
258
+ ],
259
+ 2025: [
260
+ RateRow(
261
+ min=Decimal("0.00"),
262
+ max=Decimal("14999.99"),
263
+ withhold_amount=Decimal("0.00"),
264
+ percent=0,
265
+ ),
266
+ RateRow(
267
+ min=Decimal("15000.00"),
268
+ max=Decimal("26924.99"),
269
+ withhold_amount=Decimal("0.00"),
270
+ percent=10,
271
+ ),
272
+ RateRow(
273
+ min=Decimal("26925.00"),
274
+ max=Decimal("63474.99"),
275
+ withhold_amount=Decimal("1192.50"),
276
+ percent=12,
277
+ ),
278
+ RateRow(
279
+ min=Decimal("63475.00"),
280
+ max=Decimal("118349.99"),
281
+ withhold_amount=Decimal("5578.50"),
282
+ percent=22,
283
+ ),
284
+ RateRow(
285
+ min=Decimal("118350.00"),
286
+ max=Decimal("212299.99"),
287
+ withhold_amount=Decimal("17651.00"),
288
+ percent=24,
289
+ ),
290
+ RateRow(
291
+ min=Decimal("212300.00"),
292
+ max=Decimal("265524.99"),
293
+ withhold_amount=Decimal("40199.00"),
294
+ percent=32,
295
+ ),
296
+ RateRow(
297
+ min=Decimal("265525.00"),
298
+ max=Decimal("390799.99"),
299
+ withhold_amount=Decimal("57231.00"),
300
+ percent=35,
301
+ ),
302
+ RateRow(
303
+ min=Decimal("390800.00"),
304
+ max=MAX,
305
+ withhold_amount=Decimal("101077.25"),
306
+ percent=37,
307
+ ),
308
+ ],
309
+ }
@@ -0,0 +1,309 @@
1
+ from decimal import Decimal
2
+
3
+ from .. import MAX, RateRow
4
+
5
+ standard_schedule = {
6
+ 2023: [
7
+ RateRow(
8
+ min=Decimal("0.00"),
9
+ max=Decimal("5249.99"),
10
+ withhold_amount=Decimal("0.00"),
11
+ percent=0,
12
+ ),
13
+ RateRow(
14
+ min=Decimal("5250.00"),
15
+ max=Decimal("16249.99"),
16
+ withhold_amount=Decimal("0.00"),
17
+ percent=10,
18
+ ),
19
+ RateRow(
20
+ min=Decimal("16250.00"),
21
+ max=Decimal("49974.99"),
22
+ withhold_amount=Decimal("1100.00"),
23
+ percent=12,
24
+ ),
25
+ RateRow(
26
+ min=Decimal("49975.00"),
27
+ max=Decimal("100624.99"),
28
+ withhold_amount=Decimal("5147.00"),
29
+ percent=22,
30
+ ),
31
+ RateRow(
32
+ min=Decimal("100625.00"),
33
+ max=Decimal("187349.99"),
34
+ withhold_amount=Decimal("16290.00"),
35
+ percent=24,
36
+ ),
37
+ RateRow(
38
+ min=Decimal("187350.00"),
39
+ max=Decimal("236499.99"),
40
+ withhold_amount=Decimal("37104.00"),
41
+ percent=32,
42
+ ),
43
+ RateRow(
44
+ min=Decimal("236500.00"),
45
+ max=Decimal("583374.99"),
46
+ withhold_amount=Decimal("52832.00"),
47
+ percent=35,
48
+ ),
49
+ RateRow(
50
+ min=Decimal("583375.00"),
51
+ max=MAX,
52
+ withhold_amount=Decimal("174238.25"),
53
+ percent=37,
54
+ ),
55
+ ],
56
+ 2024: [
57
+ RateRow(
58
+ min=Decimal("0.00"),
59
+ max=Decimal("5999.99"),
60
+ withhold_amount=Decimal("0.00"),
61
+ percent=0,
62
+ ),
63
+ RateRow(
64
+ min=Decimal("6000.00"),
65
+ max=Decimal("17599.99"),
66
+ withhold_amount=Decimal("0.00"),
67
+ percent=10,
68
+ ),
69
+ RateRow(
70
+ min=Decimal("17600.00"),
71
+ max=Decimal("53149.99"),
72
+ withhold_amount=Decimal("1160.00"),
73
+ percent=12,
74
+ ),
75
+ RateRow(
76
+ min=Decimal("53150.00"),
77
+ max=Decimal("106524.99"),
78
+ withhold_amount=Decimal("5426.00"),
79
+ percent=22,
80
+ ),
81
+ RateRow(
82
+ min=Decimal("106525.00"),
83
+ max=Decimal("197949.99"),
84
+ withhold_amount=Decimal("17168.50"),
85
+ percent=24,
86
+ ),
87
+ RateRow(
88
+ min=Decimal("197950.00"),
89
+ max=Decimal("249724.99"),
90
+ withhold_amount=Decimal("39110.50"),
91
+ percent=32,
92
+ ),
93
+ RateRow(
94
+ min=Decimal("249725.00"),
95
+ max=Decimal("615349.99"),
96
+ withhold_amount=Decimal("55678.50"),
97
+ percent=35,
98
+ ),
99
+ RateRow(
100
+ min=Decimal("615350.00"),
101
+ max=MAX,
102
+ withhold_amount=Decimal("183647.25"),
103
+ percent=37,
104
+ ),
105
+ ],
106
+ 2025: [
107
+ RateRow(
108
+ min=Decimal("0.00"),
109
+ max=Decimal("6399.99"),
110
+ withhold_amount=Decimal("0.00"),
111
+ percent=0,
112
+ ),
113
+ RateRow(
114
+ min=Decimal("6400.00"),
115
+ max=Decimal("18324.99"),
116
+ withhold_amount=Decimal("0.00"),
117
+ percent=10,
118
+ ),
119
+ RateRow(
120
+ min=Decimal("18325.00"),
121
+ max=Decimal("54874.99"),
122
+ withhold_amount=Decimal("1192.50"),
123
+ percent=12,
124
+ ),
125
+ RateRow(
126
+ min=Decimal("54875.00"),
127
+ max=Decimal("109749.99"),
128
+ withhold_amount=Decimal("5578.50"),
129
+ percent=22,
130
+ ),
131
+ RateRow(
132
+ min=Decimal("109750.00"),
133
+ max=Decimal("203699.99"),
134
+ withhold_amount=Decimal("17651.00"),
135
+ percent=24,
136
+ ),
137
+ RateRow(
138
+ min=Decimal("203700.00"),
139
+ max=Decimal("256924.99"),
140
+ withhold_amount=Decimal("40199.00"),
141
+ percent=32,
142
+ ),
143
+ RateRow(
144
+ min=Decimal("256925.00"),
145
+ max=Decimal("632749.99"),
146
+ withhold_amount=Decimal("57231.00"),
147
+ percent=35,
148
+ ),
149
+ RateRow(
150
+ min=Decimal("632750.00"),
151
+ max=MAX,
152
+ withhold_amount=Decimal("188769.75"),
153
+ percent=37,
154
+ ),
155
+ ],
156
+ }
157
+
158
+ multiple_jobs = {
159
+ 2023: [
160
+ RateRow(
161
+ min=Decimal("0.00"),
162
+ max=Decimal("6924.99"),
163
+ withhold_amount=Decimal("0.00"),
164
+ percent=0,
165
+ ),
166
+ RateRow(
167
+ min=Decimal("6925.00"),
168
+ max=Decimal("12424.99"),
169
+ withhold_amount=Decimal("0.00"),
170
+ percent=10,
171
+ ),
172
+ RateRow(
173
+ min=Decimal("12425.00"),
174
+ max=Decimal("29287.99"),
175
+ withhold_amount=Decimal("550.00"),
176
+ percent=12,
177
+ ),
178
+ RateRow(
179
+ min=Decimal("29288.00"),
180
+ max=Decimal("54612.99"),
181
+ withhold_amount=Decimal("2573.50"),
182
+ percent=22,
183
+ ),
184
+ RateRow(
185
+ min=Decimal("54613.00"),
186
+ max=Decimal("97974.99"),
187
+ withhold_amount=Decimal("8145.00"),
188
+ percent=24,
189
+ ),
190
+ RateRow(
191
+ min=Decimal("97975.00"),
192
+ max=Decimal("122549.99"),
193
+ withhold_amount=Decimal("18552.00"),
194
+ percent=32,
195
+ ),
196
+ RateRow(
197
+ min=Decimal("122550.00"),
198
+ max=Decimal("295987.99"),
199
+ withhold_amount=Decimal("26416.00"),
200
+ percent=35,
201
+ ),
202
+ RateRow(
203
+ min=Decimal("295988.00"),
204
+ max=MAX,
205
+ withhold_amount=Decimal("87119.13"),
206
+ percent=37,
207
+ ),
208
+ ],
209
+ 2024: [
210
+ RateRow(
211
+ min=Decimal("0.00"),
212
+ max=Decimal("7299.99"),
213
+ withhold_amount=Decimal("0.00"),
214
+ percent=0,
215
+ ),
216
+ RateRow(
217
+ min=Decimal("7300.00"),
218
+ max=Decimal("13099.99"),
219
+ withhold_amount=Decimal("0.00"),
220
+ percent=10,
221
+ ),
222
+ RateRow(
223
+ min=Decimal("13100.00"),
224
+ max=Decimal("30874.99"),
225
+ withhold_amount=Decimal("580.00"),
226
+ percent=12,
227
+ ),
228
+ RateRow(
229
+ min=Decimal("30875.00"),
230
+ max=Decimal("57562.99"),
231
+ withhold_amount=Decimal("2713.00"),
232
+ percent=22,
233
+ ),
234
+ RateRow(
235
+ min=Decimal("57563.00"),
236
+ max=Decimal("103274.99"),
237
+ withhold_amount=Decimal("8584.25"),
238
+ percent=24,
239
+ ),
240
+ RateRow(
241
+ min=Decimal("103275.00"),
242
+ max=Decimal("129162.99"),
243
+ withhold_amount=Decimal("19555.25"),
244
+ percent=32,
245
+ ),
246
+ RateRow(
247
+ min=Decimal("129163.00"),
248
+ max=Decimal("311974.99"),
249
+ withhold_amount=Decimal("27839.25"),
250
+ percent=35,
251
+ ),
252
+ RateRow(
253
+ min=Decimal("311975.00"),
254
+ max=MAX,
255
+ withhold_amount=Decimal("91823.63"),
256
+ percent=37,
257
+ ),
258
+ ],
259
+ 2025: [
260
+ RateRow(
261
+ min=Decimal("0.00"),
262
+ max=Decimal("7499.99"),
263
+ withhold_amount=Decimal("0.00"),
264
+ percent=0,
265
+ ),
266
+ RateRow(
267
+ min=Decimal("7500.00"),
268
+ max=Decimal("13462.99"),
269
+ withhold_amount=Decimal("0.00"),
270
+ percent=10,
271
+ ),
272
+ RateRow(
273
+ min=Decimal("13463.00"),
274
+ max=Decimal("31737.99"),
275
+ withhold_amount=Decimal("596.25"),
276
+ percent=12,
277
+ ),
278
+ RateRow(
279
+ min=Decimal("31738.00"),
280
+ max=Decimal("59174.99"),
281
+ withhold_amount=Decimal("2789.25"),
282
+ percent=22,
283
+ ),
284
+ RateRow(
285
+ min=Decimal("59175.00"),
286
+ max=Decimal("106149.99"),
287
+ withhold_amount=Decimal("8825.50"),
288
+ percent=24,
289
+ ),
290
+ RateRow(
291
+ min=Decimal("106150.00"),
292
+ max=Decimal("132762.99"),
293
+ withhold_amount=Decimal("20099.50"),
294
+ percent=32,
295
+ ),
296
+ RateRow(
297
+ min=Decimal("132763.00"),
298
+ max=Decimal("320674.99"),
299
+ withhold_amount=Decimal("28615.50"),
300
+ percent=35,
301
+ ),
302
+ RateRow(
303
+ min=Decimal("320675.00"),
304
+ max=MAX,
305
+ withhold_amount=Decimal("94384.88"),
306
+ percent=37,
307
+ ),
308
+ ],
309
+ }
@@ -0,0 +1,89 @@
1
+ from decimal import Decimal
2
+ from typing import Annotated, Literal
3
+
4
+ from pydantic import StrictBool, validate_call
5
+
6
+ from python_taxes import currency_field
7
+ from python_taxes.federal import rounding
8
+
9
+ STANDARD_PERCENT = Decimal("1.45") / 100
10
+
11
+ SELF_EMPLOYED_PERCENT = Decimal("2.9") / 100
12
+
13
+ ADDITIONAL_PERCENT = Decimal("0.9") / 100
14
+
15
+ DEFAULT_THRESHOLD = Decimal("200000")
16
+
17
+ status_threshold = {
18
+ "single": DEFAULT_THRESHOLD,
19
+ "married": Decimal("250000"),
20
+ "separate": Decimal("125000"),
21
+ "hoh": DEFAULT_THRESHOLD,
22
+ }
23
+
24
+
25
+ @validate_call
26
+ def required_withholding(
27
+ taxable_wages: Annotated[Decimal, currency_field],
28
+ taxable_wages_ytd: Annotated[Decimal, currency_field] = Decimal("0.00"),
29
+ self_employed: StrictBool = False,
30
+ rounded: StrictBool = False,
31
+ ) -> Decimal:
32
+ """Calculate required amount to withhold regardless of filing status.
33
+
34
+ Parameters:
35
+ taxable_wages -- Wages earned this period
36
+ taxable_wages_ytd -- Wages earned this year
37
+ self_employed -- True if self-employed (default False)
38
+ rounded -- Round to nearest whole dollar amount (default False)
39
+ """
40
+
41
+ if self_employed:
42
+ tax_rate = SELF_EMPLOYED_PERCENT
43
+ taxable_wages = taxable_wages * (Decimal("92.35") / 100)
44
+ taxable_wages_ytd = taxable_wages_ytd * (Decimal("92.35") / 100)
45
+ else:
46
+ tax_rate = STANDARD_PERCENT
47
+
48
+ if (
49
+ taxable_wages > DEFAULT_THRESHOLD
50
+ or (taxable_wages_ytd + taxable_wages) > DEFAULT_THRESHOLD
51
+ ):
52
+ tax_rate = tax_rate + ADDITIONAL_PERCENT
53
+
54
+ return (taxable_wages * tax_rate).quantize(rounding[rounded])
55
+
56
+
57
+ @validate_call
58
+ def additional_withholding(
59
+ taxable_wages_ytd: Annotated[Decimal, currency_field],
60
+ filing_status: Literal["single", "married", "separate", "hoh"] = "single",
61
+ self_employed: StrictBool = False,
62
+ rounded: StrictBool = False,
63
+ ) -> Decimal:
64
+ """Calculate withholding based on status.
65
+
66
+ Parameters:
67
+ taxable_wages_ytd -- Wages earned this year
68
+ filing_status -- Filing status (default 'single')
69
+ self_employed -- True if self-employed (default False)
70
+ rounded -- Round to nearest whole dollar amount (default False)
71
+ """
72
+
73
+ if self_employed:
74
+ tax_rate = SELF_EMPLOYED_PERCENT
75
+ taxable_wages_ytd = taxable_wages_ytd * (Decimal("92.35") / 100)
76
+ else:
77
+ tax_rate = STANDARD_PERCENT
78
+
79
+ threshold = status_threshold[filing_status]
80
+
81
+ if taxable_wages_ytd > threshold:
82
+ wages_over_threshold = taxable_wages_ytd - threshold
83
+ med_taxes = (taxable_wages_ytd - wages_over_threshold) * tax_rate
84
+ tax_rate = tax_rate + ADDITIONAL_PERCENT
85
+ med_taxes = med_taxes + (wages_over_threshold * tax_rate)
86
+ else:
87
+ med_taxes = taxable_wages_ytd * tax_rate
88
+
89
+ return med_taxes.quantize(rounding[rounded])