Add previous FY mirror selection and force fresh TDS review
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user