80 lines
3.3 KiB
Python
80 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from us_cpa.cases import CaseManager
|
|
from us_cpa.renderers import render_case_forms
|
|
from us_cpa.returns import normalize_case_facts
|
|
from us_cpa.sources import TaxYearCorpus
|
|
|
|
|
|
def _load_case_facts(case_dir: Path) -> dict[str, Any]:
|
|
facts_path = case_dir / "extracted" / "facts.json"
|
|
payload = json.loads(facts_path.read_text())
|
|
facts = {key: value["value"] for key, value in payload["facts"].items()}
|
|
facts["_factMetadata"] = {
|
|
key: {"sources": value.get("sources", [])} for key, value in payload["facts"].items()
|
|
}
|
|
return facts
|
|
|
|
|
|
|
|
class PrepareEngine:
|
|
def __init__(self, *, corpus: TaxYearCorpus | None = None) -> None:
|
|
self.corpus = corpus or TaxYearCorpus()
|
|
|
|
def prepare_case(self, case_dir: Path) -> dict[str, Any]:
|
|
manager = CaseManager(case_dir)
|
|
manifest = manager.load_manifest()
|
|
facts = _load_case_facts(manager.case_dir)
|
|
normalized = normalize_case_facts(facts, manifest["taxYear"])
|
|
normalized_path = manager.case_dir / "return" / "normalized-return.json"
|
|
normalized_path.write_text(json.dumps(normalized, indent=2))
|
|
|
|
artifacts = render_case_forms(manager.case_dir, self.corpus, normalized)
|
|
unresolved_issues = json.loads(manager.issues_path.read_text())["issues"]
|
|
|
|
summary = {
|
|
"requiredForms": normalized["requiredForms"],
|
|
"reviewRequiredArtifacts": [
|
|
artifact["formCode"] for artifact in artifacts["artifacts"] if artifact["reviewRequired"]
|
|
],
|
|
"refund": normalized["totals"]["refund"],
|
|
"balanceDue": normalized["totals"]["balanceDue"],
|
|
"unresolvedIssueCount": len(unresolved_issues),
|
|
}
|
|
result = {
|
|
"status": "prepared",
|
|
"caseDir": str(manager.case_dir),
|
|
"taxYear": manifest["taxYear"],
|
|
"normalizedReturnPath": str(normalized_path),
|
|
"artifactManifestPath": str(manager.case_dir / "output" / "artifacts.json"),
|
|
"summary": summary,
|
|
}
|
|
(manager.case_dir / "reports" / "prepare-summary.json").write_text(json.dumps(result, indent=2))
|
|
return result
|
|
|
|
|
|
class EfileExporter:
|
|
def export_case(self, case_dir: Path) -> dict[str, Any]:
|
|
case_dir = Path(case_dir).expanduser().resolve()
|
|
normalized = json.loads((case_dir / "return" / "normalized-return.json").read_text())
|
|
artifacts = json.loads((case_dir / "output" / "artifacts.json").read_text())
|
|
issues = json.loads((case_dir / "issues" / "open-issues.json").read_text())["issues"]
|
|
payload = {
|
|
"status": "draft" if issues or any(a["reviewRequired"] for a in artifacts["artifacts"]) else "ready",
|
|
"taxYear": normalized["taxYear"],
|
|
"returnSummary": {
|
|
"requiredForms": normalized["requiredForms"],
|
|
"refund": normalized["totals"]["refund"],
|
|
"balanceDue": normalized["totals"]["balanceDue"],
|
|
},
|
|
"attachments": artifacts["artifacts"],
|
|
"unresolvedIssues": issues,
|
|
}
|
|
output_path = case_dir / "output" / "efile-ready.json"
|
|
output_path.write_text(json.dumps(payload, indent=2))
|
|
return payload
|