Add Phase 22 master integrity engine
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user