Add financial year selector to Cash Payment Review

This commit is contained in:
A R R R Associates
2026-09-09 14:54:16 +05:30
parent e3f012d302
commit 7f372330a5
2 changed files with 93 additions and 12 deletions
+60 -8
View File
@@ -4,6 +4,7 @@ from datetime import date, datetime
from decimal import Decimal, InvalidOperation
from urllib.parse import quote
import uuid
import re
from fastapi import APIRouter, Request
from fastapi.responses import RedirectResponse, JSONResponse
@@ -148,6 +149,30 @@ def _review_financial_year(date_from: str, date_to: str, fallback_today: date) -
return fy, parsed_from, parsed_to
def _financial_year_bounds(financial_year: str) -> tuple[date, date]:
text = str(financial_year or "").strip()
match = re.fullmatch(r"(\d{4})-(\d{2})", text)
if not match:
raise ValueError("Invalid financial year.")
start_year = int(match.group(1))
expected_suffix = str((start_year + 1) % 100).zfill(2)
if match.group(2) != expected_suffix:
raise ValueError("Invalid financial year.")
return date(start_year, 4, 1), date(start_year + 1, 3, 31)
def _financial_year_options(selected_fy: str, today: date) -> list[str]:
current = _financial_year_for_date(today)
current_start = int(current.split("-", 1)[0])
selected_start = int(str(selected_fy).split("-", 1)[0]) if selected_fy else current_start
newest = max(current_start, selected_start)
oldest = min(current_start - 7, selected_start)
return [
f"{year}-{str((year + 1) % 100).zfill(2)}"
for year in range(newest, oldest - 1, -1)
]
def _render(request: Request, db, user, **context):
base = {
"request": request,
@@ -170,6 +195,7 @@ def cash_payment_review(
tally_guid: str = "",
date_from: str = "",
date_to: str = "",
financial_year: str = "",
job_id: str = "",
cash_ledger_name: str = "",
analyze: int = 0,
@@ -196,16 +222,35 @@ def cash_payment_review(
today = date.today()
# Default period still follows the current date when the user first opens
# the page, but once a date range is supplied the mirror is resolved
# strictly from that review period rather than from the workspace FY.
# Financial Year is now an explicit review selector. This avoids any
# ambiguity between the ERP workspace FY and the local mirror FY.
default_fy = _financial_year_for_date(today)
default_start_year = int(default_fy.split("-", 1)[0])
start_text = date_from or date(default_start_year, 4, 1).isoformat()
end_text = date_to or today.isoformat()
review_fy, parsed_from, parsed_to = _review_financial_year(start_text, end_text, today)
requested_fy = str(financial_year or "").strip()
try:
review_fy = requested_fy if requested_fy else (
_financial_year_for_date(_parse_review_date(date_from, today))
if date_from else default_fy
)
fy_start, fy_end = _financial_year_bounds(review_fy)
except Exception:
review_fy = default_fy
fy_start, fy_end = _financial_year_bounds(review_fy)
parsed_from = _parse_review_date(date_from, fy_start) if date_from else fy_start
parsed_to = _parse_review_date(date_to, fy_end) if date_to else fy_end
# Keep manual sub-period review possible, but never allow a reversed
# range such as 01/04/2025 -> 31/03/2025.
if parsed_from < fy_start or parsed_from > fy_end:
parsed_from = fy_start
if parsed_to < fy_start or parsed_to > fy_end:
parsed_to = fy_end
if parsed_to < parsed_from:
parsed_from, parsed_to = fy_start, fy_end
start_text = parsed_from.isoformat()
end_text = parsed_to.isoformat()
financial_year_options = _financial_year_options(review_fy, today)
review = None
mirror_status = None
@@ -294,6 +339,7 @@ def cash_payment_review(
allocation_input={"total_amount": "", "party_name": "", "expense_ledger": "", "source_payments": ""},
page_mode="compliance",
review_financial_year=review_fy,
financial_year_options=financial_year_options,
)
finally:
db.close()
@@ -737,7 +783,13 @@ async def save_cash_payment_settings(request: Request):
except Exception:
db.rollback()
client_id = str(form.get("client_id") or "").strip()
suffix = f"&client_id={client_id}" if client_id else ""
financial_year = str(form.get("financial_year") or "").strip()
parts = []
if client_id:
parts.append("client_id=" + quote(client_id))
if financial_year:
parts.append("financial_year=" + quote(financial_year))
suffix = ("&" + "&".join(parts)) if parts else ""
return RedirectResponse(url=f"/tools/accounting/cash-payments?saved=1{suffix}", status_code=303)
finally:
db.close()