103 lines
3.8 KiB
Python
103 lines
3.8 KiB
Python
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()
|