Add FY-wise Tally data paths to engagement workspace

This commit is contained in:
A R R R Associates
2026-09-02 13:06:34 +05:30
parent ec00a76ace
commit a0db6cebfc
4 changed files with 175 additions and 9 deletions
+36 -2
View File
@@ -435,6 +435,32 @@ def build_year_wise_relative_path(db: Session, engagement: ClientServiceSubscrip
return Path(fy) / "Clients" / letter / client_folder / service_category / period / doc_type / stored_filename
def build_tally_data_relative_path(
db: Session,
engagement: ClientServiceSubscription,
document: EngagementDocument,
version_no: int,
original_filename: str,
financial_year: str,
) -> Path:
"""Build the local-storage target for an uploaded Tally dataset.
Tally data is engagement-level reference data, but it is deliberately stored
under the selected financial year so current-year and prior-year datasets can
coexist and be compared without changing the engagement/task workflow.
"""
client = getattr(engagement, "client", None) or db.get(Client, engagement.client_id)
fy = sanitize_segment(f"FY{financial_year}", "FY")
letter, client_folder = client_folder_parts(client, engagement.client_id)
stored_filename = build_versioned_filename(
original_filename,
document_id=document.id,
version_no=version_no,
engagement_code=sanitize_segment(f"ENG-{engagement.id}-TALLY", "ENGAGEMENT"),
)
return Path(fy) / "Clients" / letter / client_folder / "Accounting" / "Tally Data" / stored_filename
def build_permanent_relative_path(db: Session, client: Client, document: PermanentClientDocument, version_no: int, original_filename: str) -> Path:
letter, client_folder = client_folder_parts(client, document.client_id)
category = sanitize_segment(document.category, "Other Permanent Documents")
@@ -1150,6 +1176,7 @@ def save_uploaded_revision(
user,
existing_document_id: int | None = None,
udin_required: bool | str | None = None,
tally_financial_year: str | None = None,
) -> EngagementDocument:
original_filename = Path(upload_file.filename or "document.bin").name
document_type = document_type if document_type in DOCUMENT_TYPES else "GENERAL"
@@ -1164,6 +1191,8 @@ def save_uploaded_revision(
if description is not None:
document.description = description.strip() or None
document.document_type = document_type
if tally_financial_year:
document.financial_year = tally_financial_year
document.udin_required = resolved_udin_required
if resolved_udin_required and (document.udin_status or "not_required") == "not_required":
document.udin_status = "pending"
@@ -1175,7 +1204,7 @@ def save_uploaded_revision(
branch_id=engagement.branch_id,
client_id=engagement.client_id,
engagement_id=engagement.id,
financial_year=engagement.financial_year,
financial_year=tally_financial_year or engagement.financial_year,
assessment_year=engagement.assessment_year,
document_code="PENDING",
document_type=document_type,
@@ -1192,7 +1221,12 @@ def save_uploaded_revision(
document.document_code = create_document_code(db, engagement.tenant_id, engagement.id, document.id)
next_version_no = int(document.current_version_no or 0) + 1
rel_path = build_year_wise_relative_path(db, engagement, document, next_version_no, original_filename)
if tally_financial_year:
rel_path = build_tally_data_relative_path(
db, engagement, document, next_version_no, original_filename, tally_financial_year
)
else:
rel_path = build_year_wise_relative_path(db, engagement, document, next_version_no, original_filename)
abs_path = DEFAULT_STORAGE_ROOT / rel_path
try:
abs_path.parent.mkdir(parents=True, exist_ok=True)
+35
View File
@@ -101,6 +101,20 @@ from app.modules.services.execution import recalculate_task_aqmm_status
router = APIRouter(prefix="/documents", tags=["documents-ui"])
logger = logging.getLogger("audit_storage_agent.documents_ui")
_TALLY_MARKER_PREFIX = "ERP_TALLY_DATA_FY:"
def _previous_financial_year(financial_year: str) -> str:
match = re.match(r"^(\d{4})-(\d{2}|\d{4})$", (financial_year or "").strip())
if not match:
return ""
start = int(match.group(1))
return f"{start - 1:04d}-{start % 100:02d}"
def _allowed_tally_financial_years(engagement) -> set[str]:
current = str(getattr(engagement, "financial_year", "") or "").strip()
previous = _previous_financial_year(current)
return {year for year in (current, previous) if year}
def _normalise_document_text(value) -> str:
return re.sub(r"[^a-z0-9]+", " ", str(value or "").lower()).strip()
@@ -359,6 +373,8 @@ def upload_engagement_document(
remarks: str | None = Form(None),
existing_document_id: str | None = Form(None),
udin_required: str | None = Form(None),
upload_target: str | None = Form(None),
tally_financial_year: str | None = Form(None),
file: UploadFile = File(...),
return_to: str = Form(""),
csrf_token: str = Form(...),
@@ -381,6 +397,24 @@ def upload_engagement_document(
return RedirectResponse(url=return_target if return_to else f"/documents/engagements/{engagement.id}?year_locked=1", status_code=303)
if not file or not file.filename:
return RedirectResponse(url=return_target if return_to else f"/documents/engagements/{engagement_id}?error=missing_file", status_code=303)
is_tally_upload = (upload_target or "").strip().lower() == "tally"
selected_tally_fy = (tally_financial_year or "").strip() if is_tally_upload else ""
if is_tally_upload:
if selected_tally_fy not in _allowed_tally_financial_years(engagement):
return RedirectResponse(url=return_target if return_to else f"/documents/engagements/{engagement_id}?error=invalid_tally_year", status_code=303)
title = f"Tally Data - FY {selected_tally_fy}"
description = f"{_TALLY_MARKER_PREFIX}{selected_tally_fy}"
document_type = "GENERAL"
if existing_document_id:
existing_doc = get_document(db, int(existing_document_id))
existing_marker = str(getattr(existing_doc, "description", "") or "") if existing_doc else ""
if (
not existing_doc
or int(getattr(existing_doc, "engagement_id", 0) or 0) != int(engagement.id)
or existing_marker.strip() != f"{_TALLY_MARKER_PREFIX}{selected_tally_fy}"
):
return RedirectResponse(url=return_target if return_to else f"/documents/engagements/{engagement_id}?error=invalid_tally_document", status_code=303)
try:
doc = save_uploaded_revision(
db,
@@ -393,6 +427,7 @@ def upload_engagement_document(
user=user,
existing_document_id=int(existing_document_id) if existing_document_id else None,
udin_required=_bool_from_form(udin_required),
tally_financial_year=selected_tally_fy or None,
)
log_document_access(db, action="upload", result="success", user=user, request=request, document=doc)
db.commit()