from __future__ import annotations from fastapi import APIRouter, Request from fastapi.responses import RedirectResponse from app.core.db.common import CommonSessionLocal from app.core.templating import templates from app.modules.accounting.master_integrity_service import build_master_integrity_report, filter_integrity_issues from app.modules.accounting.ui import _require_partner, _visible_clients from app.modules.core.rbac.deps import get_user_permissions, get_user_roles router = APIRouter( prefix="/tools/accounting/master-integrity", tags=["accounting-master-integrity-ui"], ) @router.get("") def page( request: Request, client_id: int | None = None, tally_guid: str = "", q: str = "", severity: str = "", master_type: str = "", issue_type: str = "", page: int = 1, per_page: int = 50, ): db = CommonSessionLocal() try: user, denied = _require_partner(request, db, "accounting.tally.view") if denied: return denied clients, scope = _visible_clients(db, request, user) selected = next((c for c in clients if client_id and int(c.id) == int(client_id)), None) # This phase intentionally analyzes the already-synced ERP master snapshots. # Tally writes are not performed from this report. report = { "summary": {"groups": 0, "ledgers": 0, "stock_groups": 0, "stock_items": 0, "units": 0, "issues": 0, "high": 0, "medium": 0, "low": 0}, "issues": [], "issue_types": [], "master_types": [], } filtered = {"rows": [], "total": 0, "page": 1, "pages": 1, "per_page": per_page} available_guids = [] if selected: from sqlalchemy import select from app.modules.accounting.chart_models import AccountingChartLedger available_guids = [ row[0] for row in db.execute( select(AccountingChartLedger.tally_guid) .where( AccountingChartLedger.tenant_id == scope.tenant_id, AccountingChartLedger.client_id == selected.id, ) .distinct() .order_by(AccountingChartLedger.tally_guid) ).all() if str(row[0] or "").strip() ] if tally_guid and tally_guid not in available_guids: tally_guid = "" if not tally_guid and len(available_guids) == 1: tally_guid = available_guids[0] if tally_guid: report = build_master_integrity_report( db, tenant_id=scope.tenant_id, client_id=selected.id, tally_guid=tally_guid, ) filtered = filter_integrity_issues( report, q=q, severity=severity, master_type=master_type, issue_type=issue_type, page=page, per_page=per_page, ) return templates.TemplateResponse( "modules/accounting/templates/accounting/master_integrity.html", { "request": request, "current_user": user, "current_user_roles": get_user_roles(db, user.id), "current_user_permissions": get_user_permissions(db, user.id), "title": "Master Integrity Engine", "clients": clients, "selected_client": selected, "available_guids": available_guids, "selected_tally_guid": tally_guid, "report": report, "filtered": filtered, "q": q, "severity_filter": severity, "master_type_filter": master_type, "issue_type_filter": issue_type, }, ) finally: db.close()