Add Phase 19 bank accounting and reconciliation workflow

This commit is contained in:
A R R R Associates
2026-08-24 15:23:49 +05:30
parent 67ebd587e9
commit 769add8cb8
17 changed files with 1363 additions and 10 deletions
+32 -2
View File
@@ -86,6 +86,7 @@ def _ctx(request, db, user, **extra):
"selected_bank": "auto",
"financial_year": "",
"classification_enabled": True,
"purpose": "analyze_only",
"analyzer_clients": [],
"analyzer_engagements": [],
"selected_client_id": None,
@@ -137,7 +138,7 @@ def index(request: Request, job: str | None = None):
@router.post("/analyze")
async def analyze(request: Request, csrf_token: str = Form(...), bank_selection: str = Form("auto"), financial_year: str = Form(""), customer_name: str = Form(""), account_number: str = Form(""), client_id: str = Form(""), engagement_id: str = Form(""), confirm_same_client: str | None = Form(None), enable_classification: str | None = Form(None), statements: list[UploadFile] = File(...)):
async def analyze(request: Request, csrf_token: str = Form(...), bank_selection: str = Form("auto"), financial_year: str = Form(""), customer_name: str = Form(""), account_number: str = Form(""), client_id: str = Form(""), engagement_id: str = Form(""), confirm_same_client: str | None = Form(None), enable_classification: str | None = Form(None), purpose: str = Form("analyze_only"), statements: list[UploadFile] = File(...)):
db = CommonSessionLocal()
selected_bank = bank_selection if bank_selection in dict(BANK_OPTIONS) else "auto"
classification_enabled = enable_classification == "1"
@@ -147,8 +148,16 @@ async def analyze(request: Request, csrf_token: str = Form(...), bank_selection:
if denied:
return denied
validate_csrf(request, csrf_token)
purpose = purpose if purpose in {"analyze_only", "accounting_entries", "bank_reconciliation"} else "analyze_only"
resolved_client_id = int(client_id) if client_id.strip() else None
resolved_engagement_id = int(engagement_id) if engagement_id.strip() else None
if purpose in {"accounting_entries", "bank_reconciliation"} and not resolved_client_id:
raise ValueError(
"Prepare Accounting Entries and Bank Reconciliation require an ERP client. "
"Use Analyze Only for standalone analysis."
)
validate_selected_client_and_engagement(
db,
request=request,
@@ -175,6 +184,7 @@ async def analyze(request: Request, csrf_token: str = Form(...), bank_selection:
client_id=resolved_client_id,
engagement_id=resolved_engagement_id,
ownership_confirmation=(confirm_same_client == "1"),
purpose=purpose,
)
return RedirectResponse(f"/tools/bank-statement-analyzer?job={job_id}#analysis-status", status_code=303)
except Exception as exc:
@@ -187,7 +197,27 @@ async def analyze(request: Request, csrf_token: str = Form(...), bank_selection:
timezone_name = _display_timezone_name(request, db, user)
recent = [_localised_job_view(item, timezone_name) for item in list_user_jobs(user.id, limit=8)]
client_context = analyzer_client_context(db, request=request, user=user, roles=get_user_roles(db, user.id))
return templates.TemplateResponse("modules/bank_statement_analyzer/templates/bank_statement_analyzer/index.html", _ctx(request, db, user, error=str(exc), active_job=None, recent_jobs=recent, selected_bank=selected_bank, financial_year=financial_year, classification_enabled=classification_enabled, display_timezone=timezone_name), status_code=400)
return templates.TemplateResponse(
"modules/bank_statement_analyzer/templates/bank_statement_analyzer/index.html",
_ctx(
request,
db,
user,
error=str(exc),
active_job=None,
recent_jobs=recent,
selected_bank=selected_bank,
financial_year=financial_year,
classification_enabled=classification_enabled,
purpose=purpose if purpose in {"analyze_only", "accounting_entries", "bank_reconciliation"} else "analyze_only",
display_timezone=timezone_name,
analyzer_clients=client_context["clients"],
analyzer_engagements=client_context["engagements"],
selected_client_id=(int(client_id) if str(client_id).strip().isdigit() else None),
selected_engagement_id=(int(engagement_id) if str(engagement_id).strip().isdigit() else None),
),
status_code=400,
)
finally:
db.close()