Add full Tally ODBC export with SQLite progress
This commit is contained in:
@@ -6,7 +6,7 @@ import re
|
||||
from urllib.parse import quote
|
||||
|
||||
from fastapi import APIRouter, Form, Request
|
||||
from fastapi.responses import RedirectResponse
|
||||
from fastapi.responses import RedirectResponse, JSONResponse
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.core.db.common import CommonSessionLocal
|
||||
@@ -197,6 +197,7 @@ def tally_tool(
|
||||
unmapped: int = 0,
|
||||
synced: int = 0,
|
||||
transactions_synced: int = 0,
|
||||
export_started: int = 0,
|
||||
error: str = "",
|
||||
):
|
||||
db = CommonSessionLocal()
|
||||
@@ -547,6 +548,75 @@ def sync_tally_transactions(
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
@router.post("/full-export")
|
||||
def start_full_accounting_export(
|
||||
request: Request,
|
||||
client_id: int = Form(...),
|
||||
tally_guid: str = Form(...),
|
||||
date_from: str = Form(...),
|
||||
date_to: str = Form(...),
|
||||
csrf_token: str = Form(...),
|
||||
):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user, response = _require_partner(request, db, "accounting.tally.sync_transactions")
|
||||
if response:
|
||||
return response
|
||||
client, _clients, scope = _find_visible_client(db, request, user, client_id)
|
||||
if not client:
|
||||
return _denied()
|
||||
try:
|
||||
start = date.fromisoformat(str(date_from or ""))
|
||||
end = date.fromisoformat(str(date_to or ""))
|
||||
if start > end:
|
||||
raise ValueError("From Date cannot be after To Date.")
|
||||
except Exception as exc:
|
||||
return RedirectResponse(url=f"/tools/tally?client_id={client.id}&error={quote(str(exc))}", status_code=303)
|
||||
node = get_active_storage_node_for_branch(db, scope.tenant_id, scope.branch_id)
|
||||
if not node or not _node_online(node):
|
||||
return RedirectResponse(url=f"/tools/tally?client_id={client.id}&error={quote('ERP Local Agent is offline for the active branch.')}", status_code=303)
|
||||
result = request_agent_command(
|
||||
node.node_code, "accounting_full_export_start",
|
||||
{
|
||||
**_accounting_storage_payload(client, _financial_year_for_date(start)),
|
||||
"tally_guid": str(tally_guid or "").strip(),
|
||||
"date_from": start.isoformat(), "date_to": end.isoformat(),
|
||||
"requested_by_user_id": int(user.id), "timeout_seconds": 1800,
|
||||
}, timeout_seconds=20,
|
||||
)
|
||||
if not result.get("ok"):
|
||||
raise RuntimeError(str(result.get("error") or "Full Accounting Export could not be started."))
|
||||
return RedirectResponse(url=f"/tools/tally?client_id={client.id}&refresh=1&export_started=1", status_code=303)
|
||||
except Exception as exc:
|
||||
return RedirectResponse(url=f"/tools/tally?client_id={client_id}&error={quote(str(exc))}", status_code=303)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("/full-export/status")
|
||||
def full_accounting_export_status(request: Request, client_id: int):
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user, response = _require_partner(request, db, "accounting.tally.view")
|
||||
if response:
|
||||
return JSONResponse({"ok": False, "error": "Access denied."}, status_code=403)
|
||||
client, _clients, scope = _find_visible_client(db, request, user, client_id)
|
||||
if not client:
|
||||
return JSONResponse({"ok": False, "error": "Client is not available."}, status_code=404)
|
||||
node = get_active_storage_node_for_branch(db, scope.tenant_id, scope.branch_id)
|
||||
if not node or not _node_online(node):
|
||||
return JSONResponse({"ok": False, "error": "ERP Local Agent is offline."}, status_code=503)
|
||||
result = request_agent_command(
|
||||
node.node_code, "accounting_full_export_status", _accounting_storage_payload(client), timeout_seconds=10
|
||||
)
|
||||
if not result.get("ok"):
|
||||
return JSONResponse({"ok": False, "error": str(result.get("error") or "Progress lookup failed.")}, status_code=500)
|
||||
return JSONResponse({"ok": True, **(result.get("result") or {})})
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("/depreciation")
|
||||
def depreciation_it_tool(
|
||||
request: Request,
|
||||
|
||||
Reference in New Issue
Block a user