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