Boka73's picture
Deploy Gradio app
dd6303a verified
"""Local missing-document checklist for a tender folder."""
from __future__ import annotations
import json
import pathlib
from dataclasses import dataclass, asdict
REQUIRED_DOCS = [
{"key": "notice", "label": "Tender Notice PDF", "critical": True, "patterns": ["notice", "ift", "1."]},
{"key": "tds_1", "label": "TDS Part 1 PDF", "critical": True, "patterns": ["tds_1", "tds1", "tds", "2."]},
{"key": "tds_2", "label": "TDS Part 2 PDF", "critical": False, "patterns": ["tds_2", "tds2", "3."]},
{"key": "boq", "label": "BOQ PDF", "critical": True, "patterns": ["boq", "4."]},
{"key": "context", "label": "Editable context.json", "critical": True, "patterns": ["context.json"]},
]
@dataclass
class ChecklistItem:
key: str
label: str
critical: bool
found: bool
matched_file: str = ""
def scan_required_documents(input_folder: str) -> dict:
folder = pathlib.Path(input_folder)
files = [p.name for p in folder.iterdir() if p.is_file()] if folder.exists() else []
lowered = {name.lower(): name for name in files}
items = []
for spec in REQUIRED_DOCS:
matched = ""
for low, real in lowered.items():
if any(pattern.lower() in low for pattern in spec["patterns"]):
matched = real
break
items.append(ChecklistItem(spec["key"], spec["label"], spec["critical"], bool(matched), matched))
missing_critical = [i.label for i in items if i.critical and not i.found]
missing_optional = [i.label for i in items if not i.critical and not i.found]
return {
"input_folder": str(folder),
"ready_to_generate": len(missing_critical) == 0,
"missing_critical": missing_critical,
"missing_optional": missing_optional,
"items": [asdict(i) for i in items],
}
def save_checklist_report(input_folder: str, output_folder: str) -> str:
report = scan_required_documents(input_folder)
out = pathlib.Path(output_folder) / "missing_document_checklist.json"
out.parent.mkdir(parents=True, exist_ok=True)
out.write_text(json.dumps(report, indent=2), encoding="utf-8")
return str(out)