Add previous FY mirror selection and force fresh TDS review

This commit is contained in:
A R R R Associates
2026-09-06 22:12:56 +05:30
parent 5c19f23c2d
commit bb9d4f7f47
8 changed files with 122 additions and 23 deletions
+46 -7
View File
@@ -67,6 +67,23 @@ def _financial_year_for_date(value: date | None = None) -> str:
return f"{start_year}-{str(start_year + 1)[-2:]}"
def _financial_year_bounds(financial_year: str) -> tuple[date, date]:
match = re.fullmatch(r"(\d{4})-(\d{2})", str(financial_year or "").strip())
if not match:
raise ValueError("Invalid financial year.")
start_year = int(match.group(1))
return date(start_year, 4, 1), date(start_year + 1, 3, 31)
def _financial_year_options(reference_fy: str | None = None, years_back: int = 7) -> list[str]:
reference = str(reference_fy or _financial_year_for_date()).strip()
start, _ = _financial_year_bounds(reference)
return [
f"{year}-{str(year + 1)[-2:]}"
for year in range(start.year, start.year - max(1, int(years_back)), -1)
]
def _accounting_storage_payload(client, financial_year: str | None = None) -> dict:
"""Use the same FY + client-folder policy as existing Engagement storage."""
fy_value = str(financial_year or _financial_year_for_date()).strip()
@@ -202,6 +219,7 @@ def tally_tool(
synced: int = 0,
transactions_synced: int = 0,
export_started: int = 0,
financial_year: str = "",
error: str = "",
):
db = CommonSessionLocal()
@@ -219,6 +237,13 @@ def tally_tool(
live_result = None
analysis_history = []
command_error = error or ""
selected_financial_year = str(financial_year or _financial_year_for_date()).strip()
try:
selected_fy_start, selected_fy_end = _financial_year_bounds(selected_financial_year)
except Exception:
selected_financial_year = _financial_year_for_date()
selected_fy_start, selected_fy_end = _financial_year_bounds(selected_financial_year)
mirror_fy_options = _financial_year_options(_financial_year_for_date(), 7)
should_query_agent = bool(refresh or selected_client)
if refresh:
@@ -230,7 +255,7 @@ def tally_tool(
if should_query_agent and node and online:
payload = {}
if selected_client:
payload = _accounting_storage_payload(selected_client)
payload = _accounting_storage_payload(selected_client, selected_financial_year)
try:
response_data = request_agent_command(
node.node_code,
@@ -258,9 +283,12 @@ def tally_tool(
command_error = str(exc)
today = date.today()
fy_start_year = today.year if today.month >= 4 else today.year - 1
transaction_date_from = date(fy_start_year, 4, 1).isoformat()
transaction_date_to = today.isoformat()
transaction_date_from = selected_fy_start.isoformat()
transaction_date_to = (
min(today, selected_fy_end).isoformat()
if selected_financial_year == _financial_year_for_date(today)
else selected_fy_end.isoformat()
)
return _render(
request,
@@ -280,6 +308,8 @@ def tally_tool(
transactions_synced=bool(transactions_synced),
transaction_date_from=transaction_date_from,
transaction_date_to=transaction_date_to,
selected_financial_year=selected_financial_year,
mirror_fy_options=mirror_fy_options,
command_error=command_error,
analysis_history=analysis_history,
)
@@ -726,6 +756,7 @@ def start_full_accounting_export(
tally_guid: str = Form(...),
date_from: str = Form(...),
date_to: str = Form(...),
financial_year: str = Form(""),
csrf_token: str = Form(...),
):
validate_csrf(request, csrf_token)
@@ -742,6 +773,13 @@ def start_full_accounting_export(
end = date.fromisoformat(str(date_to or ""))
if start > end:
raise ValueError("From Date cannot be after To Date.")
target_fy = str(financial_year or _financial_year_for_date(start)).strip()
fy_start, fy_end = _financial_year_bounds(target_fy)
if start < fy_start or end > fy_end:
raise ValueError(
f"Selected dates must fall within FY {target_fy} "
f"({fy_start.isoformat()} to {fy_end.isoformat()})."
)
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)
@@ -750,7 +788,7 @@ def start_full_accounting_export(
result = request_agent_command(
node.node_code, "accounting_full_export_start",
{
**_accounting_storage_payload(client, _financial_year_for_date(start)),
**_accounting_storage_payload(client, target_fy),
"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,
@@ -758,7 +796,7 @@ def start_full_accounting_export(
)
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)
return RedirectResponse(url=f"/tools/tally?client_id={client.id}&financial_year={quote(target_fy)}&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:
@@ -779,7 +817,8 @@ def full_accounting_export_status(request: Request, client_id: int):
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
node.node_code, "accounting_full_export_status",
{"client_id": int(client.id)}, timeout_seconds=10
)
if not result.get("ok"):
return JSONResponse({"ok": False, "error": str(result.get("error") or "Progress lookup failed.")}, status_code=500)