Add versioned Client FY Accounting Mirrors

This commit is contained in:
A R R R Associates
2026-09-19 12:19:33 +05:30
parent f20b79ff70
commit f6776cc96a
11 changed files with 457 additions and 198 deletions
+34 -9
View File
@@ -22,9 +22,12 @@ from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
from app.modules.core.rbac.permission_guard import require_permission
from app.modules.documents.services import build_document_scope, get_active_storage_node_for_branch, client_folder_parts, sanitize_segment
from app.modules.accounting.agent_bridge import request_agent_command
from app.modules.accounting.accounting_mirror_registry import (
from app.modules.accounting.accounting_mirror_service import (
get_registered_mirror,
list_registered_mirrors,
list_accounting_mirror_versions,
next_accounting_mirror_version,
register_accounting_mirror_version,
sync_discovered_mirrors,
upsert_registered_mirror,
)
@@ -342,6 +345,10 @@ def tally_tool(
get_registered_mirror(db, scope.tenant_id, int(selected_client.id), selected_financial_year)
if selected_client else None
)
selected_mirror_versions = (
list_accounting_mirror_versions(db, scope.tenant_id, int(selected_client.id), selected_financial_year)
if selected_client else []
)
return _render(
request,
@@ -366,6 +373,7 @@ def tally_tool(
mirror_fy_options=mirror_fy_options,
registered_mirrors=registered_mirrors,
selected_mirror_registration=selected_mirror_registration,
selected_mirror_versions=selected_mirror_versions,
command_error=command_error,
analysis_history=analysis_history,
)
@@ -850,6 +858,8 @@ def mirror_registration_status(request: Request, client_id: int, financial_year:
"client_name": client.client_name,
"company_name": (row.company_name if row else str((mirror.get("company") or {}).get("company_name") or "")),
"last_synced_at": (row.last_synced_at_utc.isoformat() if row and row.last_synced_at_utc else ""),
"version_no": (int(row.version_no) if row else 0),
"version_count": (len(list_accounting_mirror_versions(db, scope.tenant_id, int(client.id), financial_year)) if row else 0),
})
finally:
db.close()
@@ -913,15 +923,19 @@ def start_full_accounting_export(
replace_confirmed = str(replace_existing or "").strip().lower() in {"1", "true", "yes", "on"}
if (existing_registration or existing_file) and not replace_confirmed:
current_version = int(existing_registration.version_no) if existing_registration else 1
message = (
f"An Accounting Mirror already exists for {client.client_name} - FY {target_fy}. "
"Use Replace Existing Mirror to refresh it; the current mirror will remain active if the new export fails."
f"An Accounting Mirror already exists for {client.client_name} - FY {target_fy} as version {current_version}. "
"Use Create New Version to refresh it; the existing version remains available if the new export fails."
)
return RedirectResponse(
url=f"/tools/tally?client_id={client.id}&financial_year={quote(target_fy)}&error={quote(message)}",
status_code=303,
)
current_version_no = int(existing_registration.version_no) if existing_registration else (1 if existing_file else 0)
mirror_version_no = (current_version_no + 1) if (existing_registration or existing_file) else 1
result = request_agent_command(
node.node_code, "accounting_full_export_start",
{
@@ -930,6 +944,8 @@ def start_full_accounting_export(
"date_from": start.isoformat(), "date_to": end.isoformat(),
"requested_by_user_id": int(user.id), "timeout_seconds": 1800,
"replacement_requested": bool(existing_registration or existing_file),
"previous_version_no": current_version_no,
"mirror_version_no": mirror_version_no,
}, timeout_seconds=20,
)
if not result.get("ok"):
@@ -967,12 +983,21 @@ def full_accounting_export_status(request: Request, client_id: int, financial_ye
if re.fullmatch(r"\d{4}-\d{2}", fy):
storage_payload = _accounting_storage_payload(client, fy)
try:
upsert_registered_mirror(
db, tenant_id=scope.tenant_id, client_id=int(client.id), financial_year=fy,
accounting_relative_dir=storage_payload["accounting_relative_dir"], storage_node_id=int(node.id),
mirror=job.get("mirror") or {}, job=job, requested_by_user_id=int(user.id),
replacement=bool(job.get("replacement_requested")),
)
if bool(job.get("replacement_requested")):
register_accounting_mirror_version(
db, tenant_id=scope.tenant_id, client_id=int(client.id), financial_year=fy,
accounting_relative_dir=storage_payload["accounting_relative_dir"], storage_node_id=int(node.id),
mirror=job.get("mirror") or {}, job=job, requested_by_user_id=int(user.id),
version_no=int(job.get("mirror_version_no") or 0) or None,
archived_previous_file_name=str(job.get("archived_previous_file_name") or ""),
)
else:
upsert_registered_mirror(
db, tenant_id=scope.tenant_id, client_id=int(client.id), financial_year=fy,
accounting_relative_dir=storage_payload["accounting_relative_dir"], storage_node_id=int(node.id),
mirror=job.get("mirror") or {}, job=job, requested_by_user_id=int(user.id),
replacement=False,
)
db.commit()
except Exception:
db.rollback()