from datetime import datetime, timezone from pathlib import Path from sqlalchemy.orm import Session from .kyc_constants import KYC_DOCUMENT_TYPES from .models import KycApplication, KycDocument, UserAccount def ensure_kyc_application(db: Session, user: UserAccount) -> KycApplication: if user.kyc_application: return user.kyc_application application = KycApplication(user_id=user.id, status="not_started") db.add(application) db.flush() for document_type in KYC_DOCUMENT_TYPES: db.add(KycDocument(application_id=application.id, document_type=document_type, status="missing")) db.commit() db.refresh(application) return application def serialize_kyc(application: KycApplication) -> dict: documents = sorted(application.documents, key=lambda doc: doc.document_type) all_approved = bool(documents) and all(doc.status == "approved" for doc in documents) return { "id": str(application.id), "pan_number": application.pan_number, "gst_number": application.gst_number, "status": "approved" if all_approved and application.status != "not_started" else application.status, "completed": all_approved and application.pan_number and application.gst_number, "submitted_at": application.submitted_at, "approved_at": application.approved_at, "documents": [ { "id": str(doc.id), "document_type": doc.document_type, "original_filename": doc.original_filename, "status": doc.status, "review_note": doc.review_note, "uploaded_at": doc.uploaded_at, "reviewed_at": doc.reviewed_at, } for doc in documents ], } def refresh_application_status(application: KycApplication) -> None: documents = application.documents if not documents: return if all(doc.status == "approved" for doc in documents) and application.pan_number and application.gst_number: application.status = "approved" application.approved_at = datetime.now(timezone.utc) elif any(doc.status == "rejected" for doc in documents): application.status = "rejected" elif application.submitted_at: application.status = "submitted" def upload_root(base_dir: str) -> Path: path = Path(base_dir) path.mkdir(parents=True, exist_ok=True) return path