diff --git a/requirements.txt b/requirements.txt
index f675a57..cfe4602 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,3 +3,4 @@ uvicorn[standard]
python-multipart
python-docx
pendulum
+openpyxl
diff --git a/scripts/build-excel-maps-from-old-app.py b/scripts/build-excel-maps-from-old-app.py
new file mode 100644
index 0000000..7176736
--- /dev/null
+++ b/scripts/build-excel-maps-from-old-app.py
@@ -0,0 +1,137 @@
+import json
+import re
+from pathlib import Path
+
+OLD_APP = Path("/mnt/storage/sftp/mcelwain/repository/word-doc-generator")
+OLD_CONSTANTS_CANDIDATES = [
+ OLD_APP / "public" / "constants.js",
+ OLD_APP / "constants.js",
+]
+
+OUT_DIR = Path("tools/doc_generator/content/excel_maps")
+OUT_FILE = OUT_DIR / "legacy_excel_maps.json"
+
+CELL_RE = re.compile(r"([A-Za-z_][A-Za-z0-9_]*)\s*:\s*['\"]([A-Z]{1,3}[0-9]{1,5})['\"]")
+
+
+def find_constants_file():
+ for path in OLD_CONSTANTS_CANDIDATES:
+ if path.exists():
+ return path
+ raise SystemExit("Could not find old constants.js")
+
+
+def extract_object_blocks(text):
+ """
+ Finds JS object-ish assignment/export blocks that contain Excel cell mappings.
+ This is intentionally simple and robust for the old constants.js style.
+ """
+ blocks = []
+
+ # Match things like:
+ # const fieldToCellMap = { ... };
+ # export const fieldToCellMap = { ... };
+ # let someMap = { ... };
+ pattern = re.compile(
+ r"(?:export\s+)?(?:const|let|var)\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*\{",
+ re.MULTILINE,
+ )
+
+ for match in pattern.finditer(text):
+ name = match.group(1)
+ start = match.end() - 1
+
+ depth = 0
+ end = None
+
+ for i in range(start, len(text)):
+ char = text[i]
+ if char == "{":
+ depth += 1
+ elif char == "}":
+ depth -= 1
+ if depth == 0:
+ end = i + 1
+ break
+
+ if end:
+ block = text[start:end]
+ cells = dict(CELL_RE.findall(block))
+ if cells:
+ blocks.append((name, cells))
+
+ return blocks
+
+
+def label_from_name(name):
+ label = re.sub(r"([a-z])([A-Z])", r"\1 \2", name)
+ label = label.replace("_", " ").replace("-", " ")
+ label = re.sub(r"\s+", " ", label).strip()
+ return label.title()
+
+
+def normalize_id(name):
+ value = re.sub(r"([a-z])([A-Z])", r"\1_\2", name)
+ value = re.sub(r"[^A-Za-z0-9]+", "_", value).strip("_").lower()
+ return value or "excel_map"
+
+
+def discover_excel_templates():
+ templates = []
+
+ for path in sorted(OLD_APP.rglob("*.xlsx")):
+ if ".git" in path.parts or "node_modules" in path.parts:
+ continue
+
+ rel = path.relative_to(OLD_APP).as_posix()
+ templates.append({
+ "label": rel,
+ "legacyPath": str(path),
+ "filename": path.name
+ })
+
+ return templates
+
+
+def main():
+ constants_path = find_constants_file()
+ text = constants_path.read_text(encoding="utf-8", errors="ignore")
+
+ blocks = extract_object_blocks(text)
+ excel_templates = discover_excel_templates()
+
+ maps = []
+
+ for name, cells in blocks:
+ map_id = normalize_id(name)
+
+ maps.append({
+ "id": map_id,
+ "sourceName": name,
+ "label": label_from_name(name),
+ "description": f"Generated from {constants_path.relative_to(OLD_APP)} object {name}.",
+ "template": excel_templates[0]["filename"] if excel_templates else "",
+ "legacyTemplateCandidates": excel_templates,
+ "fields": dict(sorted(cells.items(), key=lambda item: item[1]))
+ })
+
+ OUT_DIR.mkdir(parents=True, exist_ok=True)
+ OUT_FILE.write_text(json.dumps({
+ "id": "legacy_excel_maps",
+ "source": str(constants_path),
+ "maps": maps
+ }, indent=2), encoding="utf-8")
+
+ print(f"Wrote {OUT_FILE}")
+ print(f"Source: {constants_path}")
+ print(f"Excel templates found: {len(excel_templates)}")
+ for t in excel_templates:
+ print(f"- {t['legacyPath']}")
+
+ print(f"Maps found: {len(maps)}")
+ for item in maps:
+ print(f"- {item['id']}: {len(item['fields'])} fields")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/build-legal-profile-from-old-app.py b/scripts/build-legal-profile-from-old-app.py
new file mode 100644
index 0000000..ecdbf22
--- /dev/null
+++ b/scripts/build-legal-profile-from-old-app.py
@@ -0,0 +1,192 @@
+import json
+import re
+import subprocess
+from pathlib import Path
+
+OLD_APP = Path("/mnt/storage/sftp/mcelwain/repository/word-doc-generator")
+DRAFT_PROFILE = Path("diagnostics/legacy_word_doc_generator_profile_draft.json")
+OUT_PROFILE = Path("tools/doc_generator/content/document_types/legal_profile.json")
+TEMPLATES_OUT = Path("tools/doc_generator/content/templates/legacy")
+
+OLD_PUBLIC = OLD_APP / "public"
+
+
+def run_node_list_extractor():
+ js = f"""
+import {{ pathToFileURL }} from 'url';
+
+const files = [
+ 'casePlaintiffInfo.js',
+ 'opposingCounselInfo.js',
+ 'judgeInfo.js',
+ 'caseFilingAttorneyInfo.js',
+ 'filingAttorneyInfo.js',
+ 'debtCollectorInfo.js'
+];
+
+const base = {json.dumps(str(OLD_PUBLIC))};
+const result = {{}};
+
+for (const file of files) {{
+ try {{
+ const mod = await import(pathToFileURL(`${{base}}/${{file}}`).href);
+ for (const [exportName, value] of Object.entries(mod)) {{
+ if (value && typeof value === 'object' && !Array.isArray(value)) {{
+ result[exportName] = Object.keys(value).sort();
+ }}
+ }}
+ }} catch (err) {{
+ // Some optional info files may not exist.
+ }}
+}}
+
+console.log(JSON.stringify(result));
+"""
+ try:
+ completed = subprocess.run(
+ ["node", "--input-type=module", "-e", js],
+ check=True,
+ capture_output=True,
+ text=True,
+ )
+ return json.loads(completed.stdout)
+ except Exception:
+ return {}
+
+
+def nice_label(name):
+ label = re.sub(r"([a-z])([A-Z])", r"\1 \2", name)
+ label = label.replace("_", " ").replace("-", " ")
+ label = re.sub(r"\bSsn\b", "SSN", label.title())
+ label = label.replace("Dob", "DOB")
+ return label
+
+
+def apply_legal_field_metadata(field):
+ name = field["name"]
+ lower = name.lower()
+
+ # Normalize generated labels.
+ field["label"] = nice_label(name)
+
+ # Autocomplete fields.
+ if name == "casePlaintiff":
+ field["type"] = "autocomplete"
+ field["list"] = "plaintiffs"
+ elif name == "caseOpposingCounsel":
+ field["type"] = "autocomplete"
+ field["list"] = "opposingCounsel"
+ elif name == "caseDivisionJudge":
+ field["type"] = "autocomplete"
+ field["list"] = "judges"
+ elif name == "caseFilingAttorney":
+ field["type"] = "autocomplete"
+ field["list"] = "filingAttorneys"
+ elif re.fullmatch(r"debtCollector\d+Name", name):
+ field["type"] = "autocomplete"
+ field["list"] = "debtCollectors"
+ elif lower.endswith("state") or name in {"caseState", "homeState", "client2homeState"}:
+ field["type"] = "autocomplete"
+ field["list"] = "states"
+ elif name == "caseDesignation":
+ field["type"] = "autocomplete"
+ field["list"] = "caseDesignations"
+
+ # Long text fields.
+ if name in {"notes", "caseAppearanceInfo", "paymentOptions", "paymentOptions1", "paymentOptions2", "paymentOptions3", "paymentOptions4", "paymentOptions5"}:
+ field["type"] = "textarea"
+
+ return field
+
+
+def walk_sections(sections):
+ for section in sections:
+ section["collapsible"] = section.get("heading") not in {
+ "Client Information",
+ "Case Information",
+ }
+ section["defaultOpen"] = section.get("heading") in {
+ "Client Information",
+ "Case Information",
+ }
+
+ section["fields"] = [
+ apply_legal_field_metadata(field)
+ for field in section.get("fields", [])
+ ]
+
+ for subsection in section.get("subsections", []):
+ walk_sections([subsection])
+
+
+def discover_templates():
+ templates = []
+
+ for path in sorted(TEMPLATES_OUT.rglob("*.docx")):
+ rel = path.relative_to(Path("tools/doc_generator/content/templates")).as_posix()
+ template_id = re.sub(r"[^a-zA-Z0-9]+", "_", path.stem).strip("_").lower()
+
+ label = path.relative_to(TEMPLATES_OUT).as_posix()
+ label = label.replace(".docx", "")
+ label = label.replace("/", " / ")
+ label = label.replace("_", " ")
+
+ templates.append({
+ "id": template_id,
+ "label": label,
+ "template": rel,
+ "outputFilename": f"{template_id}_{{caseNumber}}_{{timestamp_YYYY-MM-DD_HH-mm-ss}}.docx"
+ })
+
+ return templates
+
+
+def main():
+ if not DRAFT_PROFILE.exists():
+ raise SystemExit(f"Missing {DRAFT_PROFILE}. Run review-old-word-doc-generator.py first.")
+
+ draft = json.loads(DRAFT_PROFILE.read_text(encoding="utf-8"))
+
+ lists_raw = run_node_list_extractor()
+
+ lists = {
+ "plaintiffs": lists_raw.get("casePlaintiffInfo", []),
+ "opposingCounsel": lists_raw.get("caseOpposingCounselInfo", []) or lists_raw.get("opposingCounselInfo", []),
+ "judges": lists_raw.get("judgeInfo", []),
+ "filingAttorneys": lists_raw.get("caseFilingAttorneyInfo", []) or lists_raw.get("filingAttorneyInfo", []),
+ "debtCollectors": lists_raw.get("debtCollectorInfo", []),
+ "states": ["MO", "KS"],
+ "caseDesignations": [
+ "Associate Circuit",
+ "Circuit",
+ "Limited Actions",
+ "Small Claims"
+ ]
+ }
+
+ sections = draft["sections"]
+ walk_sections(sections)
+
+ templates = discover_templates()
+
+ profile = {
+ "id": "legal_profile",
+ "name": "Legal Profile",
+ "description": "Consumer debt defense legal profile generated from the legacy word-doc-generator app.",
+ "template": templates[0]["template"] if templates else "legacy/Canned-Emails.docx",
+ "outputFilename": "legal_{caseNumber}_{timestamp_YYYY-MM-DD_HH-mm-ss}.docx",
+ "lists": lists,
+ "templates": templates,
+ "sections": sections
+ }
+
+ OUT_PROFILE.parent.mkdir(parents=True, exist_ok=True)
+ OUT_PROFILE.write_text(json.dumps(profile, indent=2), encoding="utf-8")
+
+ print(f"Wrote {OUT_PROFILE}")
+ print(f"Lists: {', '.join(f'{k}={len(v)}' for k, v in lists.items())}")
+ print(f"Templates: {len(templates)}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/build-legal-profile-from-old-html.py b/scripts/build-legal-profile-from-old-html.py
new file mode 100644
index 0000000..5c8a2fd
--- /dev/null
+++ b/scripts/build-legal-profile-from-old-html.py
@@ -0,0 +1,337 @@
+import json
+import re
+import subprocess
+from pathlib import Path
+
+OLD_APP = Path("/mnt/storage/sftp/mcelwain/repository/word-doc-generator")
+OLD_PUBLIC = OLD_APP / "public"
+OLD_HTML = OLD_PUBLIC / "index.html"
+
+OUT_PROFILE = Path("tools/doc_generator/content/document_types/legal_profile.json")
+TEMPLATES_OUT = Path("tools/doc_generator/content/templates/legacy")
+
+TAG_RE = re.compile(r'<(input|select|textarea)\b[^>]*>', re.IGNORECASE | re.DOTALL)
+ATTR_RE = re.compile(r'([a-zA-Z_:][-a-zA-Z0-9_:.]*)=["\']([^"\']*)["\']')
+LABEL_RE = re.compile(
+ r'',
+ re.IGNORECASE | re.DOTALL
+)
+
+EXCLUDE_FIELD_NAMES = {
+ "letterTemplateFile",
+ "discoTemplateFile",
+ "excelFile",
+ "csvFile",
+ "templateFile",
+ "file",
+ "SSNLastFour",
+ "SSN2LastFour",
+ "caseAccLastFour",
+ "casePlaintiffFileName",
+ "caseAnswerDateString",
+ "caseAnswerDateYYYY-MM-DD",
+ "caseAnswerDateYyyyMmDd",
+ "caseAnswerFiledDateString",
+ "caseFilingDateString",
+ "caseDispositionDateString",
+ "discoCosDateString",
+ "discoResponseCosDateString",
+}
+
+EXCLUDE_PATTERNS = [
+ r"^settlementPaymentDate\d{2}$",
+ r"^settlementPaymentAmount\d{2}$",
+ r"^settlementRemaingBalance\d{2}$",
+ r"^settlementRemainingBalance\d{2}$",
+ r"^debtCollector\d+AccLastFour$",
+]
+
+
+def attrs_from_tag(tag):
+ return dict(ATTR_RE.findall(tag))
+
+
+def clean_html_label(value):
+ value = re.sub(r"<[^>]+>", "", value)
+ value = value.replace(":", "")
+ value = re.sub(r"\s+", " ", value).strip()
+ return value
+
+
+def nice_label(name):
+ label = re.sub(r"([a-z])([A-Z])", r"\1 \2", name)
+ label = label.replace("_", " ").replace("-", " ")
+ label = label.title()
+ label = label.replace("Ssn", "SSN")
+ label = label.replace("Dob", "DOB")
+ label = label.replace("Mm Dd Yyyy", "MM DD YYYY")
+ return label
+
+
+def should_exclude(name):
+ if not name:
+ return True
+ if name in EXCLUDE_FIELD_NAMES:
+ return True
+ if name.endswith("TemplateFile"):
+ return True
+ return any(re.match(pattern, name) for pattern in EXCLUDE_PATTERNS)
+
+
+def run_node_list_extractor():
+ js = f"""
+import {{ pathToFileURL }} from 'url';
+
+const files = [
+ 'casePlaintiffInfo.js',
+ 'opposingCounselInfo.js',
+ 'judgeInfo.js',
+ 'caseFilingAttorneyInfo.js',
+ 'filingAttorneyInfo.js',
+ 'debtCollectorInfo.js'
+];
+
+const base = {json.dumps(str(OLD_PUBLIC))};
+const result = {{}};
+
+for (const file of files) {{
+ try {{
+ const mod = await import(pathToFileURL(`${{base}}/${{file}}`).href);
+ for (const [exportName, value] of Object.entries(mod)) {{
+ if (value && typeof value === 'object' && !Array.isArray(value)) {{
+ result[exportName] = Object.keys(value).sort();
+ }}
+ }}
+ }} catch (err) {{}}
+}}
+
+console.log(JSON.stringify(result));
+"""
+ try:
+ completed = subprocess.run(
+ ["node", "--input-type=module", "-e", js],
+ check=True,
+ capture_output=True,
+ text=True,
+ )
+ return json.loads(completed.stdout)
+ except Exception:
+ return {}
+
+
+def field_type(name, tag_name, attrs):
+ lower = name.lower()
+
+ if tag_name.lower() == "textarea":
+ return "textarea"
+
+ html_type = attrs.get("type", "").lower()
+ if html_type in {"date", "email", "tel", "number"}:
+ return html_type
+
+ if "date" in lower or lower == "dob":
+ return "date"
+ if "email" in lower:
+ return "email"
+ if "phone" in lower or "fax" in lower:
+ return "tel"
+ if list_name_for_field(name):
+ return "autocomplete"
+
+ return "text"
+
+
+def list_name_for_field(name):
+ if name == "casePlaintiff":
+ return "plaintiffs"
+ if name == "caseOpposingCounsel":
+ return "opposingCounsel"
+ if name == "caseDivisionJudge":
+ return "judges"
+ if name == "caseFilingAttorney":
+ return "filingAttorneys"
+ if name in {"caseState", "homeState", "client2homeState"}:
+ return "states"
+ if name == "caseDesignation":
+ return "caseDesignations"
+ if re.fullmatch(r"debtCollector\d+Name", name):
+ return "debtCollectors"
+ return None
+
+
+def section_for(name):
+ lower = name.lower()
+
+ if lower.startswith("client2"):
+ return "Client 2 Information"
+ if lower.startswith("client") or lower in {
+ "ssn", "dob", "alias", "email",
+ "homeaddress", "homecity", "homestate", "homezip", "homecounty",
+ "homephone", "cellphone"
+ }:
+ return "Client Information"
+ if lower.startswith("case"):
+ return "Case Information"
+ if lower.startswith("disco"):
+ return "Discovery Information"
+ if lower.startswith("settlement"):
+ return "Settlement Information"
+ if lower.startswith("installment") or lower.startswith("fee") or lower in {
+ "nameoncard", "cardnumber", "securitycode", "expiration",
+ "billingaddress", "billingzip"
+ }:
+ return "Fee / Payment Information"
+ if lower.startswith("debtcollector") or name == "numCollectors":
+ return "Debt Collector Information"
+ if lower == "notes":
+ return "Notes"
+
+ return "Other Fields"
+
+
+def discover_templates():
+ templates = []
+
+ for path in sorted(TEMPLATES_OUT.rglob("*.docx")):
+ rel = path.relative_to(Path("tools/doc_generator/content/templates")).as_posix()
+ template_id = re.sub(r"[^a-zA-Z0-9]+", "_", path.stem).strip("_").lower()
+
+ label = path.relative_to(TEMPLATES_OUT).as_posix()
+ label = label.replace(".docx", "")
+ label = label.replace("/", " / ")
+ label = label.replace("_", " ")
+
+ templates.append({
+ "id": template_id,
+ "label": label,
+ "template": rel,
+ "outputFilename": f"{template_id}_{{caseNumber}}_{{timestamp_YYYY-MM-DD_HH-mm-ss}}.docx"
+ })
+
+ return templates
+
+
+html = OLD_HTML.read_text(encoding="utf-8", errors="ignore")
+
+labels = {
+ field_id: clean_html_label(label)
+ for field_id, label in LABEL_RE.findall(html)
+}
+
+fields_seen = []
+field_meta = {}
+
+for match in TAG_RE.finditer(html):
+ tag_name = match.group(1)
+ tag = match.group(0)
+ attrs = attrs_from_tag(tag)
+
+ name = attrs.get("name") or attrs.get("id")
+ if should_exclude(name):
+ continue
+
+ if name not in fields_seen:
+ fields_seen.append(name)
+ field_meta[name] = (tag_name, attrs)
+
+grouped = {}
+
+for name in fields_seen:
+ tag_name, attrs = field_meta[name]
+ ftype = field_type(name, tag_name, attrs)
+
+ field = {
+ "name": name,
+ "label": labels.get(name) or nice_label(name),
+ "type": ftype,
+ "required": False
+ }
+
+ list_name = list_name_for_field(name)
+ if list_name:
+ field["list"] = list_name
+
+ grouped.setdefault(section_for(name), []).append(field)
+
+preferred_order = [
+ "Client Information",
+ "Client 2 Information",
+ "Case Information",
+ "Discovery Information",
+ "Settlement Information",
+ "Fee / Payment Information",
+ "Debt Collector Information",
+ "Notes",
+ "Other Fields",
+]
+
+sections = []
+
+for heading in preferred_order:
+ fields = grouped.get(heading)
+ if not fields:
+ continue
+
+ sections.append({
+ "heading": heading,
+ "collapsible": heading not in {"Client Information", "Case Information"},
+ "defaultOpen": heading in {"Client Information", "Case Information"},
+ "fields": fields
+ })
+
+lists_raw = run_node_list_extractor()
+
+lists = {
+ "plaintiffs": lists_raw.get("casePlaintiffInfo", []),
+ "opposingCounsel": lists_raw.get("caseOpposingCounselInfo", []) or lists_raw.get("opposingCounselInfo", []),
+ "judges": lists_raw.get("judgeInfo", []),
+ "filingAttorneys": lists_raw.get("caseFilingAttorneyInfo", []) or lists_raw.get("filingAttorneyInfo", []),
+ "debtCollectors": lists_raw.get("debtCollectorInfo", []),
+ "states": ["MO", "KS"],
+ "caseDesignations": [
+ "Associate Circuit",
+ "Circuit",
+ "Limited Actions",
+ "Small Claims"
+ ]
+}
+
+templates = discover_templates()
+
+profile = {
+ "id": "legal_profile",
+ "name": "Legal Profile",
+ "description": "Consumer debt defense legal profile based on the legacy app form fields. Additional template fields are calculated at generation time.",
+ "template": templates[0]["template"] if templates else "legacy/Canned-Emails.docx",
+ "outputFilename": "legal_{caseNumber}_{timestamp_YYYY-MM-DD_HH-mm-ss}.docx",
+ "lists": lists,
+ "templates": templates,
+ "calculations": [
+ {
+ "script": "legacy_legal",
+ "runOn": "generate",
+ "description": "Generate old-template compatible calculated fields.",
+ "outputsDynamic": {
+ "settlementSchedule": {
+ "countField": "settlementInstallmentNo",
+ "indexFormat": "decimal2",
+ "maxCount": 120,
+ "fields": [
+ "settlementPaymentDate",
+ "settlementPaymentAmount",
+ "settlementRemaingBalance",
+ "settlementRemainingBalance"
+ ]
+ }
+ }
+ }
+ ],
+ "sections": sections
+}
+
+OUT_PROFILE.write_text(json.dumps(profile, indent=2), encoding="utf-8")
+
+print(f"Wrote {OUT_PROFILE}")
+print(f"Visible HTML fields: {len(fields_seen)}")
+for section in sections:
+ print(f"- {section['heading']}: {len(section['fields'])}")
diff --git a/scripts/legacy-excel-datafile.py b/scripts/legacy-excel-datafile.py
new file mode 100644
index 0000000..1a18533
--- /dev/null
+++ b/scripts/legacy-excel-datafile.py
@@ -0,0 +1,106 @@
+import argparse
+import csv
+import json
+import zipfile
+import xml.etree.ElementTree as ET
+from pathlib import Path
+
+MAP_FILE = Path("tools/doc_generator/content/excel_maps/legacy_excel_maps.json")
+
+NS = {
+ "main": "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ "rel": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+}
+
+
+def load_map(map_id):
+ data = json.loads(MAP_FILE.read_text(encoding="utf-8"))
+ for item in data["maps"]:
+ if item["id"] == map_id:
+ return item
+ raise SystemExit(f"Map not found: {map_id}")
+
+
+def col_row(cell):
+ col = "".join(ch for ch in cell if ch.isalpha())
+ row = "".join(ch for ch in cell if ch.isdigit())
+ return col, int(row)
+
+
+def shared_strings(z):
+ try:
+ xml = z.read("xl/sharedStrings.xml")
+ except KeyError:
+ return []
+
+ root = ET.fromstring(xml)
+ values = []
+
+ for si in root.findall("main:si", NS):
+ parts = []
+ for t in si.findall(".//main:t", NS):
+ parts.append(t.text or "")
+ values.append("".join(parts))
+
+ return values
+
+
+def read_xlsx_cells(path):
+ values = {}
+
+ with zipfile.ZipFile(path) as z:
+ strings = shared_strings(z)
+
+ # MVP: first worksheet only.
+ sheet_xml = z.read("xl/worksheets/sheet1.xml")
+ root = ET.fromstring(sheet_xml)
+
+ for cell in root.findall(".//main:c", NS):
+ ref = cell.attrib.get("r")
+ cell_type = cell.attrib.get("t")
+ v = cell.find("main:v", NS)
+
+ if not ref or v is None:
+ continue
+
+ raw = v.text or ""
+
+ if cell_type == "s":
+ try:
+ values[ref] = strings[int(raw)]
+ except Exception:
+ values[ref] = raw
+ else:
+ values[ref] = raw
+
+ return values
+
+
+def export_csv(map_id, xlsx_path, csv_path):
+ mapping = load_map(map_id)
+ cells = read_xlsx_cells(xlsx_path)
+
+ row = {}
+ for field, cell in mapping["fields"].items():
+ row[field] = cells.get(cell, "")
+
+ with open(csv_path, "w", newline="", encoding="utf-8") as f:
+ writer = csv.DictWriter(f, fieldnames=list(mapping["fields"].keys()))
+ writer.writeheader()
+ writer.writerow(row)
+
+ print(f"Exported {csv_path}")
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Export legacy Excel workbook cells to new app CSV datafile.")
+ parser.add_argument("map_id", help="Map id from legacy_excel_maps.json")
+ parser.add_argument("xlsx", help="Legacy Excel workbook to read")
+ parser.add_argument("csv", help="CSV datafile to write")
+ args = parser.parse_args()
+
+ export_csv(args.map_id, Path(args.xlsx), Path(args.csv))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/rebuild-template-labels.py b/scripts/rebuild-template-labels.py
new file mode 100644
index 0000000..f11b9cc
--- /dev/null
+++ b/scripts/rebuild-template-labels.py
@@ -0,0 +1,112 @@
+import json
+import re
+from pathlib import Path
+
+PROFILE = Path("tools/doc_generator/content/document_types/legal_profile.json")
+TEMPLATES_ROOT = Path("tools/doc_generator/content/templates")
+LEGACY_ROOT = TEMPLATES_ROOT / "legacy"
+
+CATEGORY_RULES = [
+ ("discovery", ["disco", "discovery", "interrog", "request-for-production", "rfp", "admission"]),
+ ("answers", ["answer", "entry-of-appearance"]),
+ ("settlement", ["settlement", "stip", "payment"]),
+ ("client", ["client", "engagement", "fee", "contract"]),
+ ("motions", ["motion", "dismiss", "compel", "summary"]),
+ ("letters", ["letter", "email", "canned"]),
+ ("pleadings", ["petition", "complaint", "counterclaim"]),
+]
+
+
+def title_case(value):
+ value = value.replace("_", " ").replace("-", " ")
+ value = re.sub(r"\s+", " ", value).strip()
+
+ replacements = {
+ "disco": "discovery",
+ "rfp": "request for production",
+ "cos": "certificate of service",
+ "oc": "opposing counsel",
+ "atty": "attorney",
+ "mo": "Missouri",
+ "ks": "Kansas",
+ }
+
+ words = []
+ for word in value.split():
+ lower = word.lower()
+ words.append(replacements.get(lower, lower))
+
+ return " ".join(words)
+
+
+def slug(value):
+ value = title_case(value).lower()
+ value = re.sub(r"[^a-z0-9]+", "_", value)
+ return value.strip("_") or "template"
+
+
+def category_for(relative_path):
+ text = relative_path.as_posix().lower()
+ for category, needles in CATEGORY_RULES:
+ if any(needle in text for needle in needles):
+ return category
+ return "general"
+
+
+def label_for(path):
+ rel = path.relative_to(LEGACY_ROOT)
+ parts = list(rel.parts)
+ parts[-1] = Path(parts[-1]).stem
+
+ clean_parts = [title_case(part) for part in parts]
+ return " / ".join(clean_parts)
+
+
+def main():
+ data = json.loads(PROFILE.read_text(encoding="utf-8"))
+
+ templates = []
+ used_ids = set()
+
+ for path in sorted(LEGACY_ROOT.rglob("*.docx")):
+ rel_from_templates = path.relative_to(TEMPLATES_ROOT).as_posix()
+ rel_from_legacy = path.relative_to(LEGACY_ROOT)
+
+ category = category_for(rel_from_legacy)
+ base_id = f"{category}_{slug(rel_from_legacy.with_suffix('').as_posix())}"
+ template_id = base_id
+
+ n = 2
+ while template_id in used_ids:
+ template_id = f"{base_id}_{n}"
+ n += 1
+
+ used_ids.add(template_id)
+
+ templates.append({
+ "id": template_id,
+ "category": category,
+ "label": label_for(path),
+ "template": rel_from_templates,
+ "outputFilename": f"{template_id}_{{caseNumber}}_{{timestamp_YYYY-MM-DD_HH-mm-ss}}.docx"
+ })
+
+ templates.sort(key=lambda item: (item["category"], item["label"]))
+
+ data["templates"] = templates
+
+ if templates:
+ data["defaultTemplateId"] = templates[0]["id"]
+ data["template"] = templates[0]["template"]
+
+ PROFILE.write_text(json.dumps(data, indent=2), encoding="utf-8")
+
+ print(f"Updated {PROFILE}")
+ print(f"Templates: {len(templates)}")
+ for category in sorted({item["category"] for item in templates}):
+ count = sum(1 for item in templates if item["category"] == category)
+ print(f"- {category}: {count}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/review-old-word-doc-generator.py b/scripts/review-old-word-doc-generator.py
new file mode 100644
index 0000000..2412d08
--- /dev/null
+++ b/scripts/review-old-word-doc-generator.py
@@ -0,0 +1,251 @@
+import json
+import re
+from pathlib import Path
+
+try:
+ from docx import Document
+except Exception:
+ Document = None
+
+OLD_APP = Path("/mnt/storage/sftp/mcelwain/repository/word-doc-generator")
+OUT_DIR = Path("diagnostics")
+OUT_DIR.mkdir(parents=True, exist_ok=True)
+
+PLACEHOLDER_RE = re.compile(r"\{([A-Za-z0-9_:\-]+)\}")
+
+
+def read_text(path):
+ try:
+ return path.read_text(encoding="utf-8", errors="ignore")
+ except Exception:
+ return ""
+
+
+def find_placeholders_in_text(text):
+ return sorted(set(PLACEHOLDER_RE.findall(text)))
+
+
+def find_placeholders_in_docx(path):
+ if Document is None:
+ return []
+
+ found = set()
+ try:
+ doc = Document(path)
+ except Exception:
+ return []
+
+ def scan_paragraphs(paragraphs):
+ for p in paragraphs:
+ found.update(find_placeholders_in_text(p.text))
+
+ def scan_table(table):
+ for row in table.rows:
+ for cell in row.cells:
+ scan_paragraphs(cell.paragraphs)
+ for nested in cell.tables:
+ scan_table(nested)
+
+ scan_paragraphs(doc.paragraphs)
+ for table in doc.tables:
+ scan_table(table)
+
+ return sorted(found)
+
+
+def categorize_field(name):
+ lower = name.lower()
+
+ if lower.startswith("client2"):
+ return "Client 2 Information"
+ if lower.startswith("client") or lower in {"dob", "ssn", "ssnlastfour", "alias", "email"}:
+ return "Client Information"
+ if lower.startswith("case"):
+ return "Case Information"
+ if lower.startswith("settlement"):
+ return "Settlement Information"
+ if lower.startswith("installment") or lower.startswith("fee") or lower in {"nameoncard", "cardnumber", "securitycode", "expiration", "billingaddress", "billingzip"}:
+ return "Fee / Payment Information"
+ if lower.startswith("debtcollector"):
+ return "Debt Collector Information"
+ if lower.startswith("disco"):
+ return "Discovery Information"
+ if lower in {"today", "currentdate", "currentdatemm-dd-yyyy"}:
+ return "Date Fields"
+ if lower == "notes":
+ return "Notes"
+
+ return "Other Fields"
+
+
+def field_type(name):
+ lower = name.lower()
+ if "notes" in lower or "appearanceinfo" in lower or "paymentoptions" in lower:
+ return "textarea"
+ if "date" in lower or lower in {"dob"}:
+ return "date"
+ if "email" in lower:
+ return "email"
+ if "phone" in lower or "fax" in lower:
+ return "tel"
+ return "text"
+
+
+def make_sections(fields):
+ grouped = {}
+ for name in fields:
+ grouped.setdefault(categorize_field(name), []).append(name)
+
+ preferred_order = [
+ "Date Fields",
+ "Client Information",
+ "Client 2 Information",
+ "Case Information",
+ "Discovery Information",
+ "Settlement Information",
+ "Fee / Payment Information",
+ "Debt Collector Information",
+ "Notes",
+ "Other Fields",
+ ]
+
+ sections = []
+ for heading in preferred_order:
+ names = grouped.get(heading)
+ if not names:
+ continue
+
+ sections.append({
+ "heading": heading,
+ "collapsible": heading not in {"Client Information", "Case Information"},
+ "defaultOpen": heading in {"Client Information", "Case Information"},
+ "fields": [
+ {
+ "name": name,
+ "label": re.sub(r"([a-z])([A-Z])", r"\1 \2", name).replace("_", " ").strip().title(),
+ "type": field_type(name),
+ "required": False
+ }
+ for name in sorted(names)
+ ]
+ })
+
+ return sections
+
+
+js_files = sorted(OLD_APP.rglob("*.js"))
+html_files = sorted(OLD_APP.rglob("*.html"))
+css_files = sorted(OLD_APP.rglob("*.css"))
+docx_files = sorted(OLD_APP.rglob("*.docx"))
+xlsx_files = sorted(OLD_APP.rglob("*.xlsx"))
+
+all_text_placeholders = set()
+function_hits = []
+
+function_terms = {
+ "DOCX generation": ["docx", "Docxtemplater", "generateDocument", "generateDoc"],
+ "Excel generation": ["xlsx", "generateExcel", "template.xlsx"],
+ "vCard generation": ["vcard", "vCard", "BEGIN:VCARD"],
+ "Calendar / ICS generation": ["ics", "BEGIN:VCALENDAR", "VEVENT"],
+ "Client folder generation": ["generateClientFolder", "client folder"],
+ "Settlement calculations": ["settlementPayment", "settlementInstallment", "remainingBalance"],
+}
+
+for path in js_files + html_files:
+ text = read_text(path)
+ all_text_placeholders.update(find_placeholders_in_text(text))
+
+ for label, terms in function_terms.items():
+ if any(term in text for term in terms):
+ function_hits.append((label, str(path.relative_to(OLD_APP))))
+
+template_rows = []
+all_template_placeholders = set()
+
+for path in docx_files:
+ placeholders = find_placeholders_in_docx(path)
+ all_template_placeholders.update(placeholders)
+ template_rows.append({
+ "template": str(path.relative_to(OLD_APP)),
+ "placeholder_count": len(placeholders),
+ "placeholders": placeholders,
+ })
+
+all_fields = sorted(all_text_placeholders | all_template_placeholders)
+
+profile = {
+ "id": "legacy_word_doc_generator",
+ "name": "Legacy Word Doc Generator Profile",
+ "description": "Draft profile generated from the legacy word-doc-generator app.",
+ "template": "REPLACE_WITH_SELECTED_TEMPLATE.docx",
+ "outputFilename": "legacy_document_{timestamp_YYYY-MM-DD_HH-mm-ss}.docx",
+ "sourceApp": str(OLD_APP),
+ "sections": make_sections(all_fields),
+ "legacyFeatures": sorted(set(label for label, _ in function_hits)),
+ "templatesFound": template_rows,
+}
+
+profile_path = OUT_DIR / "legacy_word_doc_generator_profile_draft.json"
+profile_path.write_text(json.dumps(profile, indent=2), encoding="utf-8")
+
+report = []
+report.append("# Legacy Word Doc Generator Review")
+report.append("")
+report.append(f"Source app: `{OLD_APP}`")
+report.append("")
+report.append("## Files Found")
+report.append("")
+report.append(f"- JS files: {len(js_files)}")
+report.append(f"- HTML files: {len(html_files)}")
+report.append(f"- CSS files: {len(css_files)}")
+report.append(f"- DOCX templates: {len(docx_files)}")
+report.append(f"- XLSX files: {len(xlsx_files)}")
+report.append("")
+report.append("## Legacy Features Detected")
+report.append("")
+
+if function_hits:
+ seen = set()
+ for label, rel in function_hits:
+ key = (label, rel)
+ if key in seen:
+ continue
+ seen.add(key)
+ report.append(f"- {label}: `{rel}`")
+else:
+ report.append("- No major legacy feature signatures detected.")
+
+report.append("")
+report.append("## Templates Found")
+report.append("")
+
+if template_rows:
+ for row in template_rows:
+ report.append(f"### `{row['template']}`")
+ report.append(f"- Placeholder count: {row['placeholder_count']}")
+ if row["placeholders"]:
+ report.append("- Placeholders:")
+ for name in row["placeholders"]:
+ report.append(f" - `{{{name}}}`")
+ report.append("")
+else:
+ report.append("- No DOCX templates found.")
+
+report.append("")
+report.append("## All Fields Detected")
+report.append("")
+for name in all_fields:
+ report.append(f"- `{{{name}}}`")
+
+report.append("")
+report.append("## Draft Profile")
+report.append("")
+report.append(f"Generated: `{profile_path}`")
+report.append("")
+
+report_path = OUT_DIR / "legacy_word_doc_generator_review.md"
+report_path.write_text("\n".join(report), encoding="utf-8")
+
+print(f"Wrote {report_path}")
+print(f"Wrote {profile_path}")
+print(f"Detected {len(all_fields)} unique fields/placeholders")
diff --git a/tools/doc_generator/content/templates/legacy/Canned-Emails.docx b/tools/doc_generator/content/templates/legacy/Canned-Emails.docx
new file mode 100755
index 0000000..2530e0d
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Canned-Emails.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Abbot-Osborn-Jacobs_MO-DB-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Abbot-Osborn-Jacobs_MO-DB-disco.docx
new file mode 100755
index 0000000..7faf11f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Abbot-Osborn-Jacobs_MO-DB-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Allen-Withrow_MO-OC-disco-RFAs.docx b/tools/doc_generator/content/templates/legacy/Discovery/Allen-Withrow_MO-OC-disco-RFAs.docx
new file mode 100755
index 0000000..65af23e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Allen-Withrow_MO-OC-disco-RFAs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Allen-Withrow_MO-OC-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Allen-Withrow_MO-OC-disco.docx
new file mode 100755
index 0000000..95e3df3
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Allen-Withrow_MO-OC-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-CC.docx
new file mode 100755
index 0000000..e424209
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-CC_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-CC_Ryan.docx
new file mode 100755
index 0000000..dbcffe6
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-CC_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-Loan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-Loan.docx
new file mode 100755
index 0000000..0980e2e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-Loan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-Loan_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-Loan_Ryan.docx
new file mode 100755
index 0000000..c9469ae
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-DB-Loan_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-CC.docx
new file mode 100755
index 0000000..acc4a59
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-CC_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-CC_Ryan.docx
new file mode 100755
index 0000000..8fca278
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-CC_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-Deficiency.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-Deficiency.docx
new file mode 100755
index 0000000..5703658
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-Deficiency.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-Deficiency_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-Deficiency_Ryan.docx
new file mode 100755
index 0000000..f620a93
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-KS-disco-OC-Deficiency_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-MO-disco-DB-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-MO-disco-DB-CC.docx
new file mode 100755
index 0000000..69e5dba
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-MO-disco-DB-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BQ-MO-disco-OC-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/BQ-MO-disco-OC-CC.docx
new file mode 100755
index 0000000..3abdc71
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BQ-MO-disco-OC-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Berman-Rabin_MO-OC-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/Berman-Rabin_MO-OC-CC.docx
new file mode 100755
index 0000000..e605872
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Berman-Rabin_MO-OC-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Berman-Rabin_MO-OC-Loan-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Berman-Rabin_MO-OC-Loan-disco.docx
new file mode 100755
index 0000000..2cac803
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Berman-Rabin_MO-OC-Loan-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco-RFAs.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco-RFAs.docx
new file mode 100755
index 0000000..07c6ff7
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco-RFAs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco-RFAs_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco-RFAs_Ryan.docx
new file mode 100755
index 0000000..af739d6
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco-RFAs_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco.docx
new file mode 100755
index 0000000..f22ad22
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco_Ryan.docx
new file mode 100755
index 0000000..e83eb63
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-DB-CC-disco_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-OC-CC-disco-RFAs.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-OC-CC-disco-RFAs.docx
new file mode 100755
index 0000000..e4c1c96
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-OC-CC-disco-RFAs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-OC-CC-disco-RFAs_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-OC-CC-disco-RFAs_Ryan.docx
new file mode 100755
index 0000000..3b691b5
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-OC-CC-disco-RFAs_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco - Copy.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco - Copy.docx
new file mode 100755
index 0000000..e7a1dd3
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco - Copy.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco.docx
new file mode 100755
index 0000000..04046b6
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco_Ryan.docx
new file mode 100755
index 0000000..660d6dd
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittKS-disco_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-CC-disco-RFAs.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-CC-disco-RFAs.docx
new file mode 100755
index 0000000..d67da6d
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-CC-disco-RFAs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-CC-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-CC-disco.docx
new file mode 100755
index 0000000..a541eea
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-CC-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-disco.docx
new file mode 100755
index 0000000..1f0e30a
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-DB-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-OC-CC-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-OC-CC-disco.docx
new file mode 100755
index 0000000..ea69c48
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-OC-CC-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco-DB-Loan-DRAFT.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco-DB-Loan-DRAFT.docx
new file mode 100755
index 0000000..3c74fb8
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco-DB-Loan-DRAFT.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco-DB-Loan-RFAs.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco-DB-Loan-RFAs.docx
new file mode 100755
index 0000000..b437421
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco-DB-Loan-RFAs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco.docx
new file mode 100755
index 0000000..1b72561
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/BlittMO-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Burns-Walsh-KS-DB-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/Burns-Walsh-KS-DB-CC.docx
new file mode 100755
index 0000000..c2d8c87
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Burns-Walsh-KS-DB-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Burns-Walsh-KS-DB-CC_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/Burns-Walsh-KS-DB-CC_Ryan.docx
new file mode 100755
index 0000000..bc0716f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Burns-Walsh-KS-DB-CC_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_KS-OC-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_KS-OC-CC.docx
new file mode 100755
index 0000000..fbca9cb
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_KS-OC-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_KS-OC-CC_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_KS-OC-CC_Ryan.docx
new file mode 100755
index 0000000..34418d1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_KS-OC-CC_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_MO-OC-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_MO-OC-CC.docx
new file mode 100755
index 0000000..cfd5c2b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Couch-Lambert_MO-OC-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Disco-Example-Responses.docx b/tools/doc_generator/content/templates/legacy/Discovery/Disco-Example-Responses.docx
new file mode 100755
index 0000000..e585466
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Disco-Example-Responses.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff.docx b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff.docx
new file mode 100755
index 0000000..8a7ef82
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_Balance-Inquiry.docx b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_Balance-Inquiry.docx
new file mode 100755
index 0000000..306d42f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_Balance-Inquiry.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_Debt-buyer-Balance-Inquiry_ROGs_RPDs.pdf.docx b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_Debt-buyer-Balance-Inquiry_ROGs_RPDs.pdf.docx
new file mode 100755
index 0000000..1f717e9
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_Debt-buyer-Balance-Inquiry_ROGs_RPDs.pdf.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_ROGs-RPDs.docx b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_ROGs-RPDs.docx
new file mode 100755
index 0000000..543c41c
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_ROGs-RPDs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_ROGs-RPDs_Westlake_MO.docx b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_ROGs-RPDs_Westlake_MO.docx
new file mode 100755
index 0000000..759cb1d
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Discovery-to-Plaintiff_ROGs-RPDs_Westlake_MO.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Auto-Deficiency-RFAs.docx b/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Auto-Deficiency-RFAs.docx
new file mode 100755
index 0000000..2a373b9
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Auto-Deficiency-RFAs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Loan-RFAs.docx b/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Loan-RFAs.docx
new file mode 100755
index 0000000..e1afcd6
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Loan-RFAs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Loan.docx b/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Loan.docx
new file mode 100755
index 0000000..f9eea4e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Faber-Brand-MO-DB-Loan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/KF-KS-OC-CC.docx b/tools/doc_generator/content/templates/legacy/Discovery/KF-KS-OC-CC.docx
new file mode 100755
index 0000000..0584c59
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/KF-KS-OC-CC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/KF-KS-OC-CC_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/KF-KS-OC-CC_Ryan.docx
new file mode 100755
index 0000000..41a16b7
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/KF-KS-OC-CC_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-DB.docx b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-DB.docx
new file mode 100755
index 0000000..028f6e5
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-DB.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-DB_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-DB_Ryan.docx
new file mode 100755
index 0000000..c6a2607
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-DB_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-OC.docx b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-OC.docx
new file mode 100755
index 0000000..2e1af78
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-OC_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-OC_Ryan.docx
new file mode 100755
index 0000000..5072bff
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-KS-disco-OC_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-MO-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-MO-disco.docx
new file mode 100755
index 0000000..e330964
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Mandarich-MO-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco.docx
new file mode 100755
index 0000000..0b7a2a1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_Ryan.docx
new file mode 100755
index 0000000..9a6e8c8
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_w-o-Signature.docx b/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_w-o-Signature.docx
new file mode 100755
index 0000000..7637750
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_w-o-Signature.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_w-o-Signature_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_w-o-Signature_Ryan.docx
new file mode 100755
index 0000000..9580a0e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/PRA-KS-disco_w-o-Signature_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/PRA-MO-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/PRA-MO-disco.docx
new file mode 100755
index 0000000..f430de1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/PRA-MO-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/PRA-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/PRA-disco.docx
new file mode 100755
index 0000000..0678baa
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/PRA-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-DB-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-DB-disco.docx
new file mode 100755
index 0000000..d72702e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-DB-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-DB-disco_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-DB-disco_Ryan.docx
new file mode 100755
index 0000000..bf3660b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-DB-disco_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-Loan-OC.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-Loan-OC.docx
new file mode 100755
index 0000000..89f0e95
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-Loan-OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-Loan-OC_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-Loan-OC_Ryan.docx
new file mode 100755
index 0000000..a67fe62
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-Loan-OC_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-OC-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-OC-disco.docx
new file mode 100755
index 0000000..03fef75
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-OC-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-OC-disco_Ryan.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-OC-disco_Ryan.docx
new file mode 100755
index 0000000..bf9c79c
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-KS-OC-disco_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-DB-Consumer-Installment-Loan-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-DB-Consumer-Installment-Loan-disco.docx
new file mode 100755
index 0000000..3c8423b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-DB-Consumer-Installment-Loan-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-DB-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-DB-disco.docx
new file mode 100755
index 0000000..04ebbd8
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-DB-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-OC-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-OC-disco.docx
new file mode 100755
index 0000000..9b2fecd
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Pappas-MO-OC-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Discovery/Southlaw-MO-OC-disco.docx b/tools/doc_generator/content/templates/legacy/Discovery/Southlaw-MO-OC-disco.docx
new file mode 100755
index 0000000..8f9edd1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Discovery/Southlaw-MO-OC-disco.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Annual-Credit-Report-Request-Envelope.docx b/tools/doc_generator/content/templates/legacy/Letters/Annual-Credit-Report-Request-Envelope.docx
new file mode 100644
index 0000000..95292ab
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Annual-Credit-Report-Request-Envelope.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Annual-Credit-Report-Request-Form.docx b/tools/doc_generator/content/templates/legacy/Letters/Annual-Credit-Report-Request-Form.docx
new file mode 100644
index 0000000..83a4202
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Annual-Credit-Report-Request-Form.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Envelope_Client.docx b/tools/doc_generator/content/templates/legacy/Letters/Envelope_Client.docx
new file mode 100755
index 0000000..6d1fc65
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Envelope_Client.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Envelope_Client_without_Sender.docx b/tools/doc_generator/content/templates/legacy/Letters/Envelope_Client_without_Sender.docx
new file mode 100644
index 0000000..7852f84
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Envelope_Client_without_Sender.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Envelope_OC.docx b/tools/doc_generator/content/templates/legacy/Letters/Envelope_OC.docx
new file mode 100644
index 0000000..5a9a508
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Envelope_OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Intake-Cover-Letter_James.docx b/tools/doc_generator/content/templates/legacy/Letters/Intake-Cover-Letter_James.docx
new file mode 100755
index 0000000..2fb8fe2
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Intake-Cover-Letter_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Intake-Cover-Letter_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/Intake-Cover-Letter_Ryan.docx
new file mode 100755
index 0000000..96f38f1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Intake-Cover-Letter_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Intake_case-expectations-long.docx b/tools/doc_generator/content/templates/legacy/Letters/Intake_case-expectations-long.docx
new file mode 100644
index 0000000..878201b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Intake_case-expectations-long.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Intake_case-expectations.docx b/tools/doc_generator/content/templates/legacy/Letters/Intake_case-expectations.docx
new file mode 100644
index 0000000..dcc0f79
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Intake_case-expectations.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Intake_general-information.docx b/tools/doc_generator/content/templates/legacy/Letters/Intake_general-information.docx
new file mode 100644
index 0000000..5df41a5
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Intake_general-information.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Intake_welcome-letter.docx b/tools/doc_generator/content/templates/legacy/Letters/Intake_welcome-letter.docx
new file mode 100644
index 0000000..51262bc
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Intake_welcome-letter.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Garnishment-Notice_James.docx b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Garnishment-Notice_James.docx
new file mode 100755
index 0000000..0cef1af
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Garnishment-Notice_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Garnishment-Notice_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Garnishment-Notice_Ryan.docx
new file mode 100755
index 0000000..6343c0b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Garnishment-Notice_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Missed-Payment_James.docx b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Missed-Payment_James.docx
new file mode 100755
index 0000000..ae11b6e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Missed-Payment_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Missed-Payment_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Missed-Payment_Ryan.docx
new file mode 100755
index 0000000..27d2c96
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Missed-Payment_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Returned-Check_James.docx b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Returned-Check_James.docx
new file mode 100755
index 0000000..e9ac6c7
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Returned-Check_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Returned-Check_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Returned-Check_Ryan.docx
new file mode 100755
index 0000000..ff1d6b4
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/Post-Judgment_Returned-Check_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/authorization-disclosure-no-payment.docx b/tools/doc_generator/content/templates/legacy/Letters/authorization-disclosure-no-payment.docx
new file mode 100644
index 0000000..7f5a22b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/authorization-disclosure-no-payment.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/authorization-disclosure.docx b/tools/doc_generator/content/templates/legacy/Letters/authorization-disclosure.docx
new file mode 100644
index 0000000..19aaa53
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/authorization-disclosure.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_Information-Sheet.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_Information-Sheet.docx
new file mode 100644
index 0000000..c1ec0a1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_Information-Sheet.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_Ryan.docx
new file mode 100755
index 0000000..ff7837e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_with-interest-costs.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_with-interest-costs.docx
new file mode 100755
index 0000000..24d8693
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_CJ_with-interest-costs.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_James.docx
new file mode 100755
index 0000000..1e5b13c
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_Ryan.docx
new file mode 100644
index 0000000..8e8fbfb
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_without-enclosures_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_without-enclosures_James.docx
new file mode 100755
index 0000000..6e5c354
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_without-enclosures_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_without-enclosures_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_without-enclosures_Ryan.docx
new file mode 100644
index 0000000..502fb8b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB-by-Court_without-enclosures_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB_James.docx
new file mode 100755
index 0000000..90086e7
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB_Ryan.docx
new file mode 100644
index 0000000..5989d5f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-DB_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Hardship_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Hardship_James.docx
new file mode 100755
index 0000000..944bfe8
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Hardship_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Hardship_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Hardship_Ryan.docx
new file mode 100644
index 0000000..05aa96e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Hardship_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_James.docx
new file mode 100755
index 0000000..3e3784b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_Ryan.docx
new file mode 100755
index 0000000..198d8df
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_without-enclosures_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_without-enclosures_James.docx
new file mode 100755
index 0000000..744791f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_without-enclosures_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_without-enclosures_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_without-enclosures_Ryan.docx
new file mode 100755
index 0000000..0a83546
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-OC-by-Court_without-enclosures_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Trial_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Trial_James.docx
new file mode 100755
index 0000000..b3fa8c8
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Trial_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Trial_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Trial_Ryan.docx
new file mode 100755
index 0000000..0ec5757
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-Trial_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-generic_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-generic_James.docx
new file mode 100755
index 0000000..391a31a
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-generic_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-generic_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-generic_Ryan.docx
new file mode 100644
index 0000000..92dc4dc
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP-generic_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP_James.docx
new file mode 100755
index 0000000..08fbdd3
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP_Ryan.docx
new file mode 100755
index 0000000..6416eb6
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWOP_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWP_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWP_James.docx
new file mode 100755
index 0000000..eaf2f1e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWP_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_DWP_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWP_Ryan.docx
new file mode 100755
index 0000000..2c20b1f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_DWP_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_FCRA-Notice-CJ.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_FCRA-Notice-CJ.docx
new file mode 100644
index 0000000..2d8696c
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_FCRA-Notice-CJ.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_FCRA-Notice-Rule-17.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_FCRA-Notice-Rule-17.docx
new file mode 100644
index 0000000..f216d5e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_FCRA-Notice-Rule-17.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_MO-Traffic-Ticket_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_MO-Traffic-Ticket_James.docx
new file mode 100755
index 0000000..d8f4573
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_MO-Traffic-Ticket_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_MO-Traffic-Ticket_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_MO-Traffic-Ticket_Ryan.docx
new file mode 100755
index 0000000..9e95bb3
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_MO-Traffic-Ticket_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_PRA-Mutual-Release_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_PRA-Mutual-Release_James.docx
new file mode 100755
index 0000000..77b1ab1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_PRA-Mutual-Release_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_PRA-Mutual-Release_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_PRA-Mutual-Release_Ryan.docx
new file mode 100755
index 0000000..7cd5c2d
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_PRA-Mutual-Release_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_Rule-17_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_Rule-17_James.docx
new file mode 100755
index 0000000..995e7a2
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_Rule-17_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_Rule-17_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_Rule-17_Ryan.docx
new file mode 100755
index 0000000..abfb612
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_Rule-17_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP-no-due-date_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP-no-due-date_James.docx
new file mode 100755
index 0000000..e8f15c3
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP-no-due-date_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP-no-due-date_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP-no-due-date_Ryan.docx
new file mode 100755
index 0000000..787d64f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP-no-due-date_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP_James.docx
new file mode 100755
index 0000000..ca536f5
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP_Ryan.docx
new file mode 100755
index 0000000..80a44b1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-DWP_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-Mutual-Release-DWP_James.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-Mutual-Release-DWP_James.docx
new file mode 100755
index 0000000..89dc727
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-Mutual-Release-DWP_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-Mutual-Release-DWP_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-Mutual-Release-DWP_Ryan.docx
new file mode 100755
index 0000000..5005521
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/closeout_Settlement-Payment-Mutual-Release-DWP_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/payment-receipt_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/payment-receipt_Ryan.docx
new file mode 100644
index 0000000..57b6271
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/payment-receipt_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/representation-termination_James.docx b/tools/doc_generator/content/templates/legacy/Letters/representation-termination_James.docx
new file mode 100755
index 0000000..099ef0e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/representation-termination_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/representation-termination_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/representation-termination_Ryan.docx
new file mode 100755
index 0000000..2b147f2
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/representation-termination_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/unable-to-contact_James.docx b/tools/doc_generator/content/templates/legacy/Letters/unable-to-contact_James.docx
new file mode 100755
index 0000000..39692c1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/unable-to-contact_James.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Letters/unable-to-contact_Ryan.docx b/tools/doc_generator/content/templates/legacy/Letters/unable-to-contact_Ryan.docx
new file mode 100755
index 0000000..aaee339
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Letters/unable-to-contact_Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer-Account-Stated-DB.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer-Account-Stated-DB.docx
new file mode 100755
index 0000000..09acaa5
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer-Account-Stated-DB.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer.docx
new file mode 100755
index 0000000..d3c8a2e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer_Account-Stated-OC.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer_Account-Stated-OC.docx
new file mode 100755
index 0000000..ef47c24
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Answer_Account-Stated-OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_EoA-Ryan.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_EoA-Ryan.docx
new file mode 100755
index 0000000..d88fcb5
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_EoA-Ryan.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_JOCO_Motion-to-Withdraw.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_JOCO_Motion-to-Withdraw.docx
new file mode 100755
index 0000000..30c9ae7
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_JOCO_Motion-to-Withdraw.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Journal-Entry-DWOP.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Journal-Entry-DWOP.docx
new file mode 100755
index 0000000..4b52eaf
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Journal-Entry-DWOP.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_MSAJ.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_MSAJ.docx
new file mode 100755
index 0000000..341d500
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_MSAJ.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Motion-to-File-Out-of-Time.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Motion-to-File-Out-of-Time.docx
new file mode 100755
index 0000000..6b51754
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Motion-to-File-Out-of-Time.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Motion-to-Withdraw.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Motion-to-Withdraw.docx
new file mode 100755
index 0000000..1db0609
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Motion-to-Withdraw.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_NoH.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_NoH.docx
new file mode 100755
index 0000000..bd67b63
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_NoH.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Response-to-MSJ_Late-Response_Auto-Deficiency-Blitt.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Response-to-MSJ_Late-Response_Auto-Deficiency-Blitt.docx
new file mode 100755
index 0000000..e7635e8
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Response-to-MSJ_Late-Response_Auto-Deficiency-Blitt.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Response-to-MSJ_Late-Responses-Blitt.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Response-to-MSJ_Late-Responses-Blitt.docx
new file mode 100755
index 0000000..3b17f7e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Response-to-MSJ_Late-Responses-Blitt.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/KS_Service_Waiver.docx b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Service_Waiver.docx
new file mode 100755
index 0000000..75ef975
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/KS_Service_Waiver.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Credit-Card_DB.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Credit-Card_DB.docx
new file mode 100755
index 0000000..e45d3a3
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Credit-Card_DB.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Credit-Card_OC.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Credit-Card_OC.docx
new file mode 100755
index 0000000..e709c61
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Credit-Card_OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Medical_OC.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Medical_OC.docx
new file mode 100755
index 0000000..2426f26
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Account-Stated_Medical_OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Auto-Deficiency_OC.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Auto-Deficiency_OC.docx
new file mode 100755
index 0000000..e9033e5
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Auto-Deficiency_OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Credit-Card_OC.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Credit-Card_OC.docx
new file mode 100755
index 0000000..d136381
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Credit-Card_OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Payday.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Payday.docx
new file mode 100755
index 0000000..182aedd
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Payday.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Promissory-Note_DB.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Promissory-Note_DB.docx
new file mode 100755
index 0000000..5f1995c
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Promissory-Note_DB.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Promissory-Note_OC.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Promissory-Note_OC.docx
new file mode 100755
index 0000000..687030f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_ADs_Breach-of-Contract_Promissory-Note_OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Answer-ADs_Account-Stated_Credit-Card_OC.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Answer-ADs_Account-Stated_Credit-Card_OC.docx
new file mode 100755
index 0000000..e5212e9
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Answer-ADs_Account-Stated_Credit-Card_OC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-MSAJ.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-MSAJ.docx
new file mode 100755
index 0000000..119cf60
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-MSAJ.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-Order-to-Continue-Hearing.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-Order-to-Continue-Hearing.docx
new file mode 100755
index 0000000..5cbfd94
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-Order-to-Continue-Hearing.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-Order-to-Continue-Trial.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-Order-to-Continue-Trial.docx
new file mode 100755
index 0000000..5a573b2
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-Order-to-Continue-Trial.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-to-Continue-Hearing.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-to-Continue-Hearing.docx
new file mode 100755
index 0000000..68ffc4a
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-to-Continue-Hearing.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-to-Continue-Trial.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-to-Continue-Trial.docx
new file mode 100755
index 0000000..f5991f7
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Joint-Motion-to-Continue-Trial.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_MSAJ.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_MSAJ.docx
new file mode 100755
index 0000000..7790170
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_MSAJ.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-File-Out-of-Time.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-File-Out-of-Time.docx
new file mode 100755
index 0000000..a0c8011
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-File-Out-of-Time.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Quash-Garnishment-Exempt-Income.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Quash-Garnishment-Exempt-Income.docx
new file mode 100755
index 0000000..1d47fd4
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Quash-Garnishment-Exempt-Income.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Quash-Garnishment.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Quash-Garnishment.docx
new file mode 100755
index 0000000..b48384e
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Quash-Garnishment.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Transfer-Venue.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Transfer-Venue.docx
new file mode 100755
index 0000000..26a3e28
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Transfer-Venue.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Withdraw_Services-Terminated.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Withdraw_Services-Terminated.docx
new file mode 100755
index 0000000..89bba36
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Withdraw_Services-Terminated.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Withdraw_Unable-to-Contact.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Withdraw_Unable-to-Contact.docx
new file mode 100755
index 0000000..a019012
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Motion-to-Withdraw_Unable-to-Contact.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Mutual-DWP.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Mutual-DWP.docx
new file mode 100755
index 0000000..d39f0be
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Mutual-DWP.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_NoH-to-Plaintiff.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_NoH-to-Plaintiff.docx
new file mode 100755
index 0000000..a94b254
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_NoH-to-Plaintiff.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment.docx
new file mode 100755
index 0000000..18f2a74
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment_Blitt.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment_Blitt.docx
new file mode 100755
index 0000000..4dd18fb
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment_Blitt.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment_Pappas.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment_Pappas.docx
new file mode 100755
index 0000000..6e72a40
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Proposed-Consent-Judgment_Pappas.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Rule-17-Structured-Settlement-Memo.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Rule-17-Structured-Settlement-Memo.docx
new file mode 100755
index 0000000..4be4303
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Rule-17-Structured-Settlement-Memo.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_SoC.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_SoC.docx
new file mode 100755
index 0000000..5a0c0a5
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_SoC.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Traffic_Amended Plea-Agreement.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Traffic_Amended Plea-Agreement.docx
new file mode 100755
index 0000000..d3b1b44
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Traffic_Amended Plea-Agreement.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/Pleadings/MO_Traffic_Request-for-Plea.docx b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Traffic_Request-for-Plea.docx
new file mode 100755
index 0000000..0d072cc
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/Pleadings/MO_Traffic_Request-for-Plea.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/authorization-disclosure-no-payment.docx b/tools/doc_generator/content/templates/legacy/authorization-disclosure-no-payment.docx
new file mode 100755
index 0000000..7f5a22b
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/authorization-disclosure-no-payment.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/authorization-disclosure.docx b/tools/doc_generator/content/templates/legacy/authorization-disclosure.docx
new file mode 100755
index 0000000..19aaa53
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/authorization-disclosure.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/cert-mailing.docx b/tools/doc_generator/content/templates/legacy/cert-mailing.docx
new file mode 100644
index 0000000..8932b1f
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/cert-mailing.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/closeout.docx b/tools/doc_generator/content/templates/legacy/closeout.docx
new file mode 100755
index 0000000..8fa5d06
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/closeout.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/defenses.docx b/tools/doc_generator/content/templates/legacy/defenses.docx
new file mode 100755
index 0000000..18d4b59
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/defenses.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/dispute-envelopes.docx b/tools/doc_generator/content/templates/legacy/dispute-envelopes.docx
new file mode 100644
index 0000000..17e4ec9
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/dispute-envelopes.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/entry.docx b/tools/doc_generator/content/templates/legacy/entry.docx
new file mode 100755
index 0000000..3691bfc
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/entry.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/isc-body.docx b/tools/doc_generator/content/templates/legacy/isc-body.docx
new file mode 100644
index 0000000..9a94195
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/isc-body.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/letter.docx b/tools/doc_generator/content/templates/legacy/letter.docx
new file mode 100644
index 0000000..4df592a
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/letter.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/notes.docx b/tools/doc_generator/content/templates/legacy/notes.docx
new file mode 100644
index 0000000..529bbf8
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/notes.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/retainer.docx b/tools/doc_generator/content/templates/legacy/retainer.docx
new file mode 100644
index 0000000..34562fa
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/retainer.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/spreadsheets.docx b/tools/doc_generator/content/templates/legacy/spreadsheets.docx
new file mode 100644
index 0000000..9fac1bf
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/spreadsheets.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/waiver.docx b/tools/doc_generator/content/templates/legacy/waiver.docx
new file mode 100755
index 0000000..a140f96
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/waiver.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/~$entry.docx b/tools/doc_generator/content/templates/legacy/~$entry.docx
new file mode 100644
index 0000000..365acc8
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/~$entry.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/~$nned-Emails.docx b/tools/doc_generator/content/templates/legacy/~$nned-Emails.docx
new file mode 100644
index 0000000..18ce7e2
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/~$nned-Emails.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/~$notes.docx b/tools/doc_generator/content/templates/legacy/~$notes.docx
new file mode 100644
index 0000000..6da20a1
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/~$notes.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/~$oseout.docx b/tools/doc_generator/content/templates/legacy/~$oseout.docx
new file mode 100644
index 0000000..9483271
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/~$oseout.docx differ
diff --git a/tools/doc_generator/content/templates/legacy/~$readsheets.docx b/tools/doc_generator/content/templates/legacy/~$readsheets.docx
new file mode 100644
index 0000000..f4bc9f6
Binary files /dev/null and b/tools/doc_generator/content/templates/legacy/~$readsheets.docx differ
diff --git a/tools/doc_generator/logic/calculations/__init__.py b/tools/doc_generator/logic/calculations/__init__.py
new file mode 100644
index 0000000..3532156
--- /dev/null
+++ b/tools/doc_generator/logic/calculations/__init__.py
@@ -0,0 +1,18 @@
+from tools.doc_generator.logic.calculations.legacy_legal import apply_legacy_legal_calculations
+
+CALCULATION_HANDLERS = {
+ "legacy_legal": apply_legacy_legal_calculations,
+}
+
+
+def apply_calculations(document_type: dict, data: dict) -> dict:
+ calculated = dict(data)
+
+ for calculation in document_type.get("calculations", []):
+ script = calculation.get("script")
+ handler = CALCULATION_HANDLERS.get(script)
+
+ if handler:
+ calculated = handler(calculated, calculation)
+
+ return calculated
diff --git a/tools/doc_generator/logic/calculations/legacy_legal.py b/tools/doc_generator/logic/calculations/legacy_legal.py
new file mode 100644
index 0000000..3fd89ba
--- /dev/null
+++ b/tools/doc_generator/logic/calculations/legacy_legal.py
@@ -0,0 +1,135 @@
+from __future__ import annotations
+
+from datetime import datetime
+from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
+
+import pendulum
+
+
+def clean_money(value) -> Decimal:
+ text = str(value or "").replace("$", "").replace(",", "").strip()
+ if not text:
+ return Decimal("0")
+ try:
+ return Decimal(text)
+ except InvalidOperation:
+ return Decimal("0")
+
+
+def clean_int(value) -> int:
+ try:
+ return max(0, int(str(value or "0").strip()))
+ except ValueError:
+ return 0
+
+
+def money(value: Decimal) -> str:
+ value = value.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
+ return f"${value:,.2f}"
+
+
+def parse_date(value):
+ text = str(value or "").strip()
+ if not text:
+ return None
+
+ for fmt in ("YYYY-MM-DD", "MM/DD/YYYY", "MM-DD-YYYY"):
+ try:
+ return pendulum.from_format(text, fmt)
+ except Exception:
+ pass
+
+ try:
+ return pendulum.parse(text)
+ except Exception:
+ return None
+
+
+def format_date(value) -> str:
+ if not value:
+ return ""
+ return value.format("MMMM Do, YYYY")
+
+
+def add_months(date_value, months: int):
+ if not date_value:
+ return None
+ return date_value.add(months=months)
+
+
+def add_last_four_fields(data: dict) -> dict:
+ # Existing old-template compatibility.
+ for key, value in list(data.items()):
+ if not key.endswith("Account"):
+ continue
+
+ base = key[:-len("Account")]
+ digits = "".join(ch for ch in str(value or "") if ch.isdigit())
+ data[f"{base}AccLastFour"] = digits[-4:] if len(digits) >= 4 else digits
+
+ ssn = "".join(ch for ch in str(data.get("SSN", "")) if ch.isdigit())
+ if ssn:
+ data["SSNLastFour"] = ssn[-4:]
+
+ ssn2 = "".join(ch for ch in str(data.get("client2SSN", "")) if ch.isdigit())
+ if ssn2:
+ data["SSN2LastFour"] = ssn2[-4:]
+
+ return data
+
+
+def add_case_filename_fields(data: dict) -> dict:
+ plaintiff = str(data.get("casePlaintiff", "") or "")
+ data["casePlaintiffFileName"] = plaintiff.replace(" ", "-").replace(",", "").replace(".", "")
+ return data
+
+
+def add_settlement_schedule(data: dict, calculation: dict) -> dict:
+ config = (calculation.get("outputsDynamic") or {}).get("settlementSchedule", {})
+
+ count_field = config.get("countField", "settlementInstallmentNo")
+ count = clean_int(data.get(count_field))
+
+ # Safety cap. Old app used many fixed fields; 120 is plenty for MVP.
+ count = min(count, int(config.get("maxCount", 120)))
+
+ settlement_amount = clean_money(data.get("settlementAmount"))
+ installment_amount = clean_money(data.get("settlementInstallmentAmount"))
+ first_payment_date = parse_date(data.get("settlementFirstPaymentDate"))
+
+ if count <= 0:
+ return data
+
+ if installment_amount == 0 and settlement_amount > 0:
+ installment_amount = (settlement_amount / Decimal(count)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
+
+ remaining = settlement_amount
+
+ for i in range(count):
+ suffix = f"{i:02d}"
+ payment_date = add_months(first_payment_date, i)
+
+ payment = installment_amount
+ if settlement_amount > 0:
+ if i == count - 1:
+ payment = remaining
+ remaining = max(Decimal("0"), remaining - payment)
+
+ data[f"settlementPaymentDate{suffix}"] = format_date(payment_date)
+ data[f"settlementPaymentAmount{suffix}"] = money(payment)
+ data[f"settlementRemaingBalance{suffix}"] = money(remaining)
+
+ # Correct spelling alias for future templates.
+ data[f"settlementRemainingBalance{suffix}"] = money(remaining)
+
+ return data
+
+
+def apply_legacy_legal_calculations(data: dict, calculation: dict) -> dict:
+ data = dict(data)
+
+ data = add_last_four_fields(data)
+ data = add_case_filename_fields(data)
+ data = add_settlement_schedule(data, calculation)
+
+ return data
diff --git a/tools/doc_generator/logic/renderer.py b/tools/doc_generator/logic/renderer.py
index 13bdddc..639140a 100644
--- a/tools/doc_generator/logic/renderer.py
+++ b/tools/doc_generator/logic/renderer.py
@@ -4,6 +4,7 @@ from pathlib import Path
from docx import Document
from tools.doc_generator.logic.core_fields import merge_core_fields
+from tools.doc_generator.logic.calculations import apply_calculations
from tools.doc_generator.logic.document_types import get_document_type
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -11,6 +12,7 @@ CONTENT_DIR = BASE_DIR / "content"
TEMPLATES_DIR = CONTENT_DIR / "templates"
PROJECT_ROOT = BASE_DIR.parent.parent
EXPORTS_DIR = PROJECT_ROOT / "exports"
+UPLOADED_TEMPLATES_DIR = PROJECT_ROOT / "inputs" / "uploads" / "templates"
def safe_filename(value: str) -> str:
@@ -22,17 +24,51 @@ def safe_filename(value: str) -> str:
def render_filename(pattern: str, data: dict) -> str:
filename = pattern
-
for key, value in data.items():
filename = filename.replace("{" + key + "}", safe_filename(value))
-
return safe_filename(filename)
+def choose_template(document_type_id: str, document_type: dict, template_id: str | None):
+ templates = document_type.get("templates") or []
+
+ # Uploaded template ids are formatted as uploaded:
+ if template_id and template_id.startswith("uploaded:"):
+ filename = safe_filename(template_id.removeprefix("uploaded:"))
+ path = UPLOADED_TEMPLATES_DIR / document_type_id / filename
+ return {
+ "templatePath": path,
+ "outputFilename": f"{Path(filename).stem}_{{caseNumber}}_{{timestamp_YYYY-MM-DD_HH-mm-ss}}.docx",
+ }
+
+ selected = None
+
+ if template_id:
+ selected = next((item for item in templates if item.get("id") == template_id), None)
+
+ if selected is None:
+ default_id = document_type.get("defaultTemplateId")
+ selected = next((item for item in templates if item.get("id") == default_id), None)
+
+ if selected is None and templates:
+ selected = templates[0]
+
+ if selected:
+ return {
+ "templatePath": TEMPLATES_DIR / selected["template"],
+ "outputFilename": selected.get("outputFilename") or document_type.get("outputFilename", f"{document_type_id}.docx"),
+ }
+
+ return {
+ "templatePath": TEMPLATES_DIR / document_type["template"],
+ "outputFilename": document_type.get("outputFilename", f"{document_type_id}.docx"),
+ }
+
+
def replace_placeholders_in_paragraph(paragraph, data: dict):
full_text = "".join(run.text for run in paragraph.runs)
-
new_text = full_text
+
for key, value in data.items():
new_text = new_text.replace("{" + key + "}", "" if value is None else str(value))
@@ -58,18 +94,20 @@ def replace_placeholders_in_table(table, data: dict):
replace_placeholders_in_table(nested_table, data)
-def generate_docx(document_type_id: str, data: dict) -> Path:
+def generate_docx(document_type_id: str, data: dict, template_id: str | None = None) -> Path:
data = merge_core_fields(data)
document_type = get_document_type(document_type_id)
+ data = apply_calculations(document_type, data)
- template_path = TEMPLATES_DIR / document_type["template"]
+ selected_template = choose_template(document_type_id, document_type, template_id)
+ template_path = selected_template["templatePath"]
if not template_path.exists():
raise FileNotFoundError(f"Template not found: {template_path}")
EXPORTS_DIR.mkdir(parents=True, exist_ok=True)
- output_pattern = document_type.get("outputFilename", f"{document_type_id}.docx")
+ output_pattern = selected_template.get("outputFilename") or document_type.get("outputFilename", f"{document_type_id}.docx")
output_filename = render_filename(output_pattern, data)
if not output_filename.lower().endswith(".docx"):
@@ -86,5 +124,4 @@ def generate_docx(document_type_id: str, data: dict) -> Path:
replace_placeholders_in_table(table, data)
document.save(output_path)
-
return output_path