taxforge 0.9.15__tar.gz → 0.9.17__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taxforge
3
- Version: 0.9.15
3
+ Version: 0.9.17
4
4
  Summary: AI-powered tax preparation assistant
5
5
  Author: TaxForge Team
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "taxforge"
7
- version = "0.9.15"
7
+ version = "0.9.17"
8
8
  description = "AI-powered tax preparation assistant"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -1,3 +1,3 @@
1
1
  """TaxForge - AI-powered tax preparation"""
2
2
 
3
- __version__ = "0.9.15"
3
+ __version__ = "0.9.16"
@@ -847,6 +847,69 @@ def review_page() -> rx.Component:
847
847
  background=COLORS["bg_hover"], border_radius="8px",
848
848
  ),
849
849
 
850
+ # Dependents & Child Tax Credit
851
+ rx.vstack(
852
+ rx.hstack(
853
+ rx.text("👨‍👩‍👧‍👦 Dependents", color=COLORS["text_primary"], font_weight="600"),
854
+ rx.spacer(),
855
+ rx.button("+ Add", size="sm", on_click=TaxAppState.toggle_dependent_form),
856
+ ),
857
+ rx.cond(
858
+ TaxAppState.dependents.length() > 0,
859
+ rx.foreach(
860
+ TaxAppState.dependents,
861
+ lambda d, idx: rx.hstack(
862
+ rx.text(d["name"], flex="1"),
863
+ rx.text(f"{d['relationship']}, Age {d['age']}"),
864
+ rx.badge(
865
+ rx.cond(d["is_child"], "CTC $2,000", "Credit $500"),
866
+ color_scheme=rx.cond(d["is_child"], "green", "blue"),
867
+ ),
868
+ rx.icon("x", size=14, cursor="pointer",
869
+ on_click=lambda: TaxAppState.remove_dependent(idx)),
870
+ width="100%", padding="8px",
871
+ ),
872
+ ),
873
+ rx.text("No dependents added", color=COLORS["text_muted"], font_style="italic"),
874
+ ),
875
+ # Dependent Form
876
+ rx.cond(
877
+ TaxAppState.show_dependent_form,
878
+ rx.vstack(
879
+ rx.hstack(
880
+ rx.input(placeholder="Name", value=TaxAppState.dependent_form_name, on_change=TaxAppState.set_dependent_name, flex="1"),
881
+ rx.input(placeholder="Relationship", value=TaxAppState.dependent_form_relationship, on_change=TaxAppState.set_dependent_relationship, width="120px"),
882
+ rx.input(placeholder="Age", value=TaxAppState.dependent_form_age, on_change=TaxAppState.set_dependent_age, type="number", width="80px"),
883
+ width="100%",
884
+ ),
885
+ rx.text("Under 17 = $2,000 Child Tax Credit | 17+ = $500 Other Dependent Credit",
886
+ color=COLORS["text_muted"], font_size="12px"),
887
+ rx.hstack(
888
+ rx.button("Cancel", variant="outline", on_click=TaxAppState.toggle_dependent_form),
889
+ rx.button("Add Dependent", on_click=TaxAppState.submit_dependent_form),
890
+ width="100%", justify="end",
891
+ ),
892
+ width="100%", spacing="2", padding="12px",
893
+ background="white", border_radius="8px", border=f"1px solid {COLORS['border']}",
894
+ ),
895
+ ),
896
+ # Credits Summary
897
+ rx.cond(
898
+ TaxAppState.child_tax_credit > 0,
899
+ rx.text(f"Child Tax Credit: ${TaxAppState.child_tax_credit:,.2f}",
900
+ color=COLORS["success"], font_size="13px"),
901
+ ),
902
+ rx.cond(
903
+ TaxAppState.other_dependent_credit > 0,
904
+ rx.text(f"Other Dependent Credit: ${TaxAppState.other_dependent_credit:,.2f}",
905
+ color=COLORS["success"], font_size="13px"),
906
+ ),
907
+ rx.text(f"Total Tax Credits: ${TaxAppState.total_credits:,.2f}",
908
+ color=COLORS["success"], font_size="13px", font_weight="600"),
909
+ width="100%", spacing="2", padding="12px",
910
+ background=COLORS["bg_hover"], border_radius="8px",
911
+ ),
912
+
850
913
  spacing="4",
851
914
  width="100%",
852
915
  ),
@@ -8,7 +8,7 @@ import shutil
8
8
  from pathlib import Path
9
9
 
10
10
 
11
- __version__ = "0.9.15"
11
+ __version__ = "0.9.16"
12
12
 
13
13
  RXCONFIG_CONTENT = '''"""Reflex config for TaxForge."""
14
14
  import reflex as rx
@@ -65,9 +65,29 @@ For 1099-SA (HSA distributions), extract:
65
65
  - distribution: Box 1 - Gross distribution
66
66
  - earnings: Box 2 - Earnings on excess contributions
67
67
 
68
+ For 1099-NEC (Nonemployee Compensation), extract:
69
+ - payer_name: Company/person who paid you
70
+ - payer_ein: Payer's TIN (if shown)
71
+ - nonemployee_compensation: Box 1 - Nonemployee compensation (this is self-employment income)
72
+ - federal_withheld: Box 4 - Federal income tax withheld (if any)
73
+ - state_tax_withheld: Box 5 - State tax withheld (if any)
74
+
75
+ For 1099-MISC (Miscellaneous Income), extract:
76
+ - payer_name: Company/person who paid you
77
+ - rents: Box 1 - Rents received
78
+ - royalties: Box 2 - Royalties
79
+ - other_income: Box 3 - Other income
80
+ - fishing_boat_proceeds: Box 5 - Fishing boat proceeds
81
+ - medical_payments: Box 6 - Medical and health care payments
82
+ - nonemployee_compensation: Box 7 - Nonemployee compensation (pre-2020 forms, now on 1099-NEC)
83
+ - substitute_payments: Box 8 - Substitute payments in lieu of dividends
84
+ - crop_insurance: Box 9 - Crop insurance proceeds
85
+ - attorney_fees: Box 10 - Gross proceeds paid to an attorney
86
+ - federal_withheld: Box 4 - Federal income tax withheld
87
+
68
88
  Respond ONLY with a valid JSON object containing:
69
89
  {
70
- "document_type": "W-2" | "1099-INT" | "1099-DIV" | "1099-B" | "1098" | "5498-SA" | "1099-SA" | "OTHER",
90
+ "document_type": "W-2" | "1099-INT" | "1099-DIV" | "1099-B" | "1098" | "5498-SA" | "1099-SA" | "1099-NEC" | "1099-MISC" | "OTHER",
71
91
  "confidence": 0.0-1.0,
72
92
  "extracted_data": {
73
93
  // relevant fields based on document type
@@ -296,3 +316,78 @@ def convert_to_1099(extracted_data: dict, form_type: str) -> dict:
296
316
  "amount": amount,
297
317
  "form_type": form_type,
298
318
  }
319
+
320
+
321
+ def convert_to_business_income(extracted_data: dict, source_type: str) -> dict:
322
+ """
323
+ Convert 1099-NEC or 1099-MISC to Schedule C business income.
324
+
325
+ 1099-NEC Box 1 = Self-employment income (goes to Schedule C)
326
+ 1099-MISC Box 7 (pre-2020) = Same as 1099-NEC
327
+ """
328
+ gross_income = 0.0
329
+ payer_name = extracted_data.get("payer_name", "Unknown Client")
330
+
331
+ if source_type == "1099-NEC":
332
+ gross_income = float(extracted_data.get("nonemployee_compensation", 0))
333
+ elif source_type == "1099-MISC":
334
+ # Box 7 was nonemployee comp before 2020, now rarely used
335
+ gross_income = float(extracted_data.get("nonemployee_compensation", 0))
336
+
337
+ return {
338
+ "name": f"Self-Employment ({payer_name})",
339
+ "gross_income": gross_income,
340
+ "expenses": 0.0, # User can edit to add expenses
341
+ "net_profit": gross_income,
342
+ "source_form": source_type,
343
+ "payer_name": payer_name,
344
+ "federal_withheld": float(extracted_data.get("federal_withheld", 0)),
345
+ }
346
+
347
+
348
+ def convert_1099_misc_to_other_income(extracted_data: dict) -> list:
349
+ """
350
+ Convert 1099-MISC non-self-employment boxes to other income entries.
351
+
352
+ Returns a list of income entries for: rents, royalties, other income, etc.
353
+ """
354
+ entries = []
355
+ payer = extracted_data.get("payer_name", "Unknown Payer")
356
+
357
+ # Box 1 - Rents (goes to Schedule E if rental property, otherwise other income)
358
+ rents = float(extracted_data.get("rents", 0))
359
+ if rents > 0:
360
+ entries.append({
361
+ "description": f"Rental Income - {payer} (1099-MISC Box 1)",
362
+ "amount": rents,
363
+ "category": "rental",
364
+ })
365
+
366
+ # Box 2 - Royalties (goes to Schedule E)
367
+ royalties = float(extracted_data.get("royalties", 0))
368
+ if royalties > 0:
369
+ entries.append({
370
+ "description": f"Royalties - {payer} (1099-MISC Box 2)",
371
+ "amount": royalties,
372
+ "category": "royalty",
373
+ })
374
+
375
+ # Box 3 - Other income (taxable, goes to Schedule 1 Line 8)
376
+ other = float(extracted_data.get("other_income", 0))
377
+ if other > 0:
378
+ entries.append({
379
+ "description": f"Other Income - {payer} (1099-MISC Box 3)",
380
+ "amount": other,
381
+ "category": "other",
382
+ })
383
+
384
+ # Box 10 - Attorney fees (gross proceeds)
385
+ attorney = float(extracted_data.get("attorney_fees", 0))
386
+ if attorney > 0:
387
+ entries.append({
388
+ "description": f"Attorney Fees - {payer} (1099-MISC Box 10)",
389
+ "amount": attorney,
390
+ "category": "other",
391
+ })
392
+
393
+ return entries
@@ -7,7 +7,14 @@ from pathlib import Path
7
7
  from typing import List, Dict
8
8
  from enum import Enum
9
9
 
10
- from .document_extractor import extract_with_retry, convert_to_w2, convert_to_1099, REQUEST_DELAY_SECONDS
10
+ from .document_extractor import (
11
+ extract_with_retry,
12
+ convert_to_w2,
13
+ convert_to_1099,
14
+ convert_to_business_income,
15
+ convert_1099_misc_to_other_income,
16
+ REQUEST_DELAY_SECONDS
17
+ )
11
18
  import asyncio
12
19
 
13
20
 
@@ -136,11 +143,18 @@ class TaxAppState(rx.State):
136
143
  other_deduction_form_desc: str = ""
137
144
  other_deduction_form_amount: str = ""
138
145
 
146
+ # Dependent form
147
+ dependent_form_name: str = ""
148
+ dependent_form_relationship: str = ""
149
+ dependent_form_age: str = ""
150
+ child_care_form_amount: str = ""
151
+
139
152
  # Form visibility
140
153
  show_rental_form: bool = False
141
154
  show_business_form: bool = False
142
155
  show_other_income_form: bool = False
143
156
  show_other_deduction_form: bool = False
157
+ show_dependent_form: bool = False
144
158
 
145
159
  # ===== Document State =====
146
160
  uploaded_files: List[str] = []
@@ -168,6 +182,12 @@ class TaxAppState(rx.State):
168
182
  other_income: List[Dict] = [] # {description, amount, tax_type}
169
183
  other_deductions: List[Dict] = [] # {description, amount, deduction_type}
170
184
 
185
+ # Dependents
186
+ dependents: List[Dict] = [] # {name, relationship, age, ssn_last4, is_child}
187
+
188
+ # Child and Dependent Care
189
+ child_care_expenses: float = 0.0 # Expenses for dependent care while working
190
+
171
191
  # ===== Calculated Values =====
172
192
  total_wages: float = 0.0
173
193
  total_interest: float = 0.0
@@ -186,9 +206,16 @@ class TaxAppState(rx.State):
186
206
  capital_gains_tax: float = 0.0 # Separate tax on capital gains
187
207
  additional_medicare_tax: float = 0.0 # 0.9% on wages > $250k (MFJ)
188
208
  niit: float = 0.0 # Net Investment Income Tax 3.8%
209
+
210
+ # Tax Credits
211
+ child_tax_credit: float = 0.0 # $2,000 per child under 17
212
+ other_dependent_credit: float = 0.0 # $500 per other dependent
213
+ child_care_credit: float = 0.0 # Credit for child/dependent care
214
+ total_credits: float = 0.0
189
215
  taxable_income: float = 0.0
190
216
  total_tax: float = 0.0
191
217
  total_withholding: float = 0.0
218
+ other_withholding: float = 0.0 # From 1099-NEC/MISC Box 4 (goes to Line 25c)
192
219
  refund_or_owed: float = 0.0
193
220
  is_refund: bool = True
194
221
 
@@ -416,6 +443,62 @@ class TaxAppState(rx.State):
416
443
  "source_file": filename,
417
444
  })
418
445
  parsed_count += 1
446
+
447
+ elif ai_doc_type == "1099-NEC":
448
+ # Nonemployee compensation → Schedule C (self-employment)
449
+ business_data = convert_to_business_income(extracted, "1099-NEC")
450
+ business_data["source_file"] = filename
451
+ self.business_income.append(business_data)
452
+
453
+ # Track any withholding
454
+ withheld = float(extracted.get("federal_withheld", 0))
455
+ if withheld > 0:
456
+ # Add to a special 1099 withholding tracker (goes to Line 25c)
457
+ if not hasattr(self, 'other_withholding'):
458
+ self.other_withholding = 0.0
459
+ self.other_withholding += withheld
460
+ parsed_count += 1
461
+
462
+ elif ai_doc_type == "1099-MISC":
463
+ # Check if it has nonemployee comp (Box 7, pre-2020)
464
+ nec_amount = float(extracted.get("nonemployee_compensation", 0))
465
+ if nec_amount > 0:
466
+ # Treat like 1099-NEC
467
+ business_data = convert_to_business_income(extracted, "1099-MISC")
468
+ business_data["source_file"] = filename
469
+ self.business_income.append(business_data)
470
+
471
+ # Handle other 1099-MISC income (rents, royalties, other)
472
+ other_entries = convert_1099_misc_to_other_income(extracted)
473
+ for entry in other_entries:
474
+ entry["source_file"] = filename
475
+ if entry.get("category") == "rental":
476
+ # Add as simple rental (user can expand)
477
+ self.rental_properties.append({
478
+ "address": entry["description"],
479
+ "rent_income": entry["amount"],
480
+ "mortgage_interest": 0,
481
+ "property_tax": 0,
482
+ "insurance": 0,
483
+ "repairs": 0,
484
+ "management": 0,
485
+ "utilities": 0,
486
+ "depreciation": 0,
487
+ "other_expenses": 0,
488
+ "total_expenses": 0,
489
+ "net_income": entry["amount"],
490
+ "source_file": filename,
491
+ })
492
+ else:
493
+ # Other income
494
+ self.other_income.append({
495
+ "description": entry["description"],
496
+ "amount": entry["amount"],
497
+ "source_file": filename,
498
+ })
499
+
500
+ if nec_amount > 0 or other_entries:
501
+ parsed_count += 1
419
502
 
420
503
  # Recalculate totals
421
504
  self._recalculate()
@@ -437,14 +520,22 @@ class TaxAppState(rx.State):
437
520
  lower = filename.lower()
438
521
  if "w2" in lower or "w-2" in lower:
439
522
  return "W-2"
440
- elif "1099-int" in lower:
523
+ elif "1099-nec" in lower or "1099nec" in lower:
524
+ return "1099-NEC"
525
+ elif "1099-misc" in lower or "1099misc" in lower:
526
+ return "1099-MISC"
527
+ elif "1099-int" in lower or "1099int" in lower:
441
528
  return "1099-INT"
442
- elif "1099-div" in lower:
529
+ elif "1099-div" in lower or "1099div" in lower:
443
530
  return "1099-DIV"
531
+ elif "1099-b" in lower or "1099b" in lower:
532
+ return "1099-B"
444
533
  elif "1099" in lower:
445
534
  return "1099"
446
535
  elif "1098" in lower:
447
536
  return "1098"
537
+ elif "5498" in lower:
538
+ return "5498-SA"
448
539
  return "Unknown"
449
540
 
450
541
  def add_w2(self, employer: str, wages: float, withheld: float):
@@ -555,6 +646,28 @@ class TaxAppState(rx.State):
555
646
  self.other_deductions.pop(index)
556
647
  self._recalculate()
557
648
 
649
+ # ===== Dependent Methods =====
650
+ def add_dependent(self, name: str, relationship: str, age: int, is_child: bool = True):
651
+ """Add a dependent (child or other)."""
652
+ self.dependents.append({
653
+ "name": name,
654
+ "relationship": relationship,
655
+ "age": age,
656
+ "is_child": is_child and age < 17, # Child Tax Credit requires under 17
657
+ })
658
+ self._recalculate()
659
+
660
+ def remove_dependent(self, index: int):
661
+ """Remove a dependent."""
662
+ if 0 <= index < len(self.dependents):
663
+ self.dependents.pop(index)
664
+ self._recalculate()
665
+
666
+ def set_child_care_expenses(self, amount: float):
667
+ """Set child/dependent care expenses."""
668
+ self.child_care_expenses = amount
669
+ self._recalculate()
670
+
558
671
  # ===== Form Toggle Methods =====
559
672
  def toggle_rental_form(self):
560
673
  self.show_rental_form = not self.show_rental_form
@@ -568,6 +681,9 @@ class TaxAppState(rx.State):
568
681
  def toggle_other_deduction_form(self):
569
682
  self.show_other_deduction_form = not self.show_other_deduction_form
570
683
 
684
+ def toggle_dependent_form(self):
685
+ self.show_dependent_form = not self.show_dependent_form
686
+
571
687
  # ===== Form Input Setters =====
572
688
  def set_rental_address(self, val): self.rental_form_address = val
573
689
  def set_rental_income(self, val): self.rental_form_income = val
@@ -587,6 +703,11 @@ class TaxAppState(rx.State):
587
703
  def set_other_deduction_desc(self, val): self.other_deduction_form_desc = val
588
704
  def set_other_deduction_amount(self, val): self.other_deduction_form_amount = val
589
705
 
706
+ def set_dependent_name(self, val): self.dependent_form_name = val
707
+ def set_dependent_relationship(self, val): self.dependent_form_relationship = val
708
+ def set_dependent_age(self, val): self.dependent_form_age = val
709
+ def set_child_care_amount(self, val): self.child_care_form_amount = val
710
+
590
711
  # ===== Form Submit Methods =====
591
712
  def submit_rental_form(self):
592
713
  """Submit rental property form."""
@@ -659,6 +780,34 @@ class TaxAppState(rx.State):
659
780
  except ValueError:
660
781
  self.error_message = "Invalid amount"
661
782
 
783
+ def submit_dependent_form(self):
784
+ """Submit dependent form."""
785
+ try:
786
+ age = int(self.dependent_form_age or 0)
787
+ self.add_dependent(
788
+ name=self.dependent_form_name or "Dependent",
789
+ relationship=self.dependent_form_relationship or "Child",
790
+ age=age,
791
+ is_child=(age < 17),
792
+ )
793
+ self.dependent_form_name = ""
794
+ self.dependent_form_relationship = ""
795
+ self.dependent_form_age = ""
796
+ self.show_dependent_form = False
797
+ self.success_message = "Dependent added!"
798
+ except ValueError:
799
+ self.error_message = "Invalid age"
800
+
801
+ def submit_child_care_expenses(self):
802
+ """Submit child care expenses."""
803
+ try:
804
+ self.child_care_expenses = float(self.child_care_form_amount or 0)
805
+ self.child_care_form_amount = ""
806
+ self._recalculate()
807
+ self.success_message = "Child care expenses updated!"
808
+ except ValueError:
809
+ self.error_message = "Invalid amount"
810
+
662
811
  def remove_file(self, filename: str):
663
812
  """Remove an uploaded file and its extracted data."""
664
813
  if filename in self.uploaded_files:
@@ -706,6 +855,7 @@ class TaxAppState(rx.State):
706
855
  # Withholding from all sources
707
856
  self.total_withholding = sum(w.get("federal_withheld", 0) for w in self.w2_list)
708
857
  self.total_withholding += sum(f.get("federal_withheld", 0) for f in self.form_1099_list)
858
+ self.total_withholding += self.other_withholding # From 1099-NEC/MISC
709
859
 
710
860
  # Line 2b: Taxable interest (1099-INT)
711
861
  self.total_interest = sum(
@@ -871,10 +1021,51 @@ class TaxAppState(rx.State):
871
1021
  niit_base = min(investment_income, max(0, self.adjusted_gross_income - niit_threshold))
872
1022
  self.niit = niit_base * 0.038
873
1023
 
874
- # Total tax = ordinary + capital gains + additional medicare + NIIT + SE tax
875
- self.total_tax = (ordinary_tax + self.capital_gains_tax +
876
- self.additional_medicare_tax + self.niit +
877
- self.self_employment_tax)
1024
+ # Gross tax before credits
1025
+ gross_tax = (ordinary_tax + self.capital_gains_tax +
1026
+ self.additional_medicare_tax + self.niit +
1027
+ self.self_employment_tax)
1028
+
1029
+ # ===== TAX CREDITS =====
1030
+
1031
+ # Child Tax Credit ($2,000 per qualifying child under 17)
1032
+ # Phase out: MFJ $400k, others $200k
1033
+ ctc_phaseout = 400000 if self.filing_status == "married_filing_jointly" else 200000
1034
+ qualifying_children = sum(1 for d in self.dependents if d.get("is_child", False))
1035
+ base_ctc = qualifying_children * 2000
1036
+
1037
+ # Phase out: reduce by $50 for each $1,000 over threshold
1038
+ if self.adjusted_gross_income > ctc_phaseout:
1039
+ reduction = ((self.adjusted_gross_income - ctc_phaseout) // 1000) * 50
1040
+ self.child_tax_credit = max(0, base_ctc - reduction)
1041
+ else:
1042
+ self.child_tax_credit = base_ctc
1043
+
1044
+ # Credit for Other Dependents ($500 per dependent not qualifying for CTC)
1045
+ other_dependents = sum(1 for d in self.dependents if not d.get("is_child", False))
1046
+ self.other_dependent_credit = other_dependents * 500
1047
+
1048
+ # Child and Dependent Care Credit (20-35% of expenses, max $3,000/1 or $6,000/2+)
1049
+ if self.child_care_expenses > 0 and qualifying_children > 0:
1050
+ max_expenses = 3000 if qualifying_children == 1 else 6000
1051
+ eligible_expenses = min(self.child_care_expenses, max_expenses)
1052
+ # Credit rate: 35% if AGI <= $15,000, phases down to 20% at $43,000+
1053
+ if self.adjusted_gross_income <= 15000:
1054
+ rate = 0.35
1055
+ elif self.adjusted_gross_income >= 43000:
1056
+ rate = 0.20
1057
+ else:
1058
+ rate = 0.35 - ((self.adjusted_gross_income - 15000) // 2000) * 0.01
1059
+ rate = max(0.20, rate)
1060
+ self.child_care_credit = eligible_expenses * rate
1061
+ else:
1062
+ self.child_care_credit = 0.0
1063
+
1064
+ # Total credits (nonrefundable - can't exceed tax)
1065
+ self.total_credits = self.child_tax_credit + self.other_dependent_credit + self.child_care_credit
1066
+
1067
+ # Total tax after credits
1068
+ self.total_tax = max(0, gross_tax - self.total_credits)
878
1069
 
879
1070
  # ===== REFUND OR AMOUNT OWED =====
880
1071
  self.refund_or_owed = self.total_withholding - self.total_tax
@@ -919,6 +1110,8 @@ class TaxAppState(rx.State):
919
1110
  self.business_income = []
920
1111
  self.other_income = []
921
1112
  self.other_deductions = []
1113
+ self.dependents = []
1114
+ self.child_care_expenses = 0.0
922
1115
  self.form_1099_list = []
923
1116
  self.total_wages = 0.0
924
1117
  self.total_interest = 0.0
@@ -940,6 +1133,7 @@ class TaxAppState(rx.State):
940
1133
  self.niit = 0.0
941
1134
  self.total_tax = 0.0
942
1135
  self.total_withholding = 0.0
1136
+ self.other_withholding = 0.0
943
1137
  self.refund_or_owed = 0.0
944
1138
  self.is_refund = True
945
1139
  self.return_status = "not_started"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taxforge
3
- Version: 0.9.15
3
+ Version: 0.9.17
4
4
  Summary: AI-powered tax preparation assistant
5
5
  Author: TaxForge Team
6
6
  License: MIT
File without changes
File without changes