Align Tally accounting storage with client storage policy
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date, datetime, timezone
|
||||
from pathlib import Path
|
||||
from urllib.parse import quote
|
||||
|
||||
from fastapi import APIRouter, Form, Request
|
||||
@@ -14,7 +15,7 @@ from app.core.templating import templates
|
||||
from app.modules.clients.models import Client
|
||||
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
|
||||
from app.modules.core.rbac.permission_guard import require_permission
|
||||
from app.modules.documents.services import build_document_scope, get_active_storage_node_for_branch
|
||||
from app.modules.documents.services import build_document_scope, get_active_storage_node_for_branch, client_folder_parts
|
||||
from app.modules.accounting.agent_bridge import request_agent_command
|
||||
from app.modules.registrations.models import ClientRegistration, RegistrationType
|
||||
|
||||
@@ -55,6 +56,18 @@ def _find_visible_client(db, request: Request, user, client_id: int):
|
||||
return client, clients, scope
|
||||
|
||||
|
||||
def _accounting_storage_payload(client) -> dict:
|
||||
"""Use the exact client folder naming policy already used by Permanent/Engagement storage."""
|
||||
letter, client_folder = client_folder_parts(client, int(client.id))
|
||||
relative_dir = Path("Accounting") / "Clients" / letter / client_folder
|
||||
return {
|
||||
"client_id": int(client.id),
|
||||
"client_name": str(client.client_name or "").strip(),
|
||||
"client_code": str(getattr(client, "client_code", "") or "").strip(),
|
||||
"accounting_relative_dir": relative_dir.as_posix(),
|
||||
}
|
||||
|
||||
|
||||
def _client_registrations(db, client, tenant_id: int):
|
||||
rows = db.execute(
|
||||
select(ClientRegistration, RegistrationType)
|
||||
@@ -143,10 +156,7 @@ def tally_tool(
|
||||
if should_query_agent and node and online:
|
||||
payload = {}
|
||||
if selected_client:
|
||||
payload = {
|
||||
"client_id": int(selected_client.id),
|
||||
"client_name": selected_client.client_name,
|
||||
}
|
||||
payload = _accounting_storage_payload(selected_client)
|
||||
try:
|
||||
response_data = request_agent_command(
|
||||
node.node_code,
|
||||
@@ -216,8 +226,7 @@ def initialize_accounting_storage(
|
||||
node.node_code,
|
||||
"accounting_initialize",
|
||||
{
|
||||
"client_id": int(client.id),
|
||||
"client_name": client.client_name,
|
||||
**_accounting_storage_payload(client),
|
||||
"tenant_id": int(scope.tenant_id),
|
||||
"requested_by_user_id": int(user.id),
|
||||
},
|
||||
@@ -293,8 +302,7 @@ def map_tally_company(
|
||||
node.node_code,
|
||||
"accounting_map_company",
|
||||
{
|
||||
"client_id": int(client.id),
|
||||
"client_name": client.client_name,
|
||||
**_accounting_storage_payload(client),
|
||||
"tenant_id": int(scope.tenant_id),
|
||||
"registration": registration_payload,
|
||||
"tally_guid": str(tally_guid or "").strip(),
|
||||
@@ -349,7 +357,7 @@ def unmap_tally_company(
|
||||
node.node_code,
|
||||
"accounting_unmap_company",
|
||||
{
|
||||
"client_id": int(client.id),
|
||||
**_accounting_storage_payload(client),
|
||||
"mapping_id": int(mapping_id),
|
||||
"unmapped_by_user_id": int(user.id),
|
||||
},
|
||||
@@ -398,7 +406,7 @@ def sync_tally_masters(
|
||||
node.node_code,
|
||||
"accounting_sync_masters",
|
||||
{
|
||||
"client_id": int(client.id),
|
||||
**_accounting_storage_payload(client),
|
||||
"tally_guid": str(tally_guid or "").strip(),
|
||||
"requested_by_user_id": int(user.id),
|
||||
},
|
||||
@@ -454,7 +462,7 @@ def sync_tally_transactions(
|
||||
node.node_code,
|
||||
"accounting_sync_transactions",
|
||||
{
|
||||
"client_id": int(client.id),
|
||||
**_accounting_storage_payload(client),
|
||||
"tally_guid": str(tally_guid or "").strip(),
|
||||
"date_from": start.isoformat(),
|
||||
"date_to": end.isoformat(),
|
||||
@@ -496,16 +504,16 @@ def depreciation_it_tool(
|
||||
live_result = None; preview = None; depreciation_run = None; command_error = error or ""
|
||||
if selected_client and node and online:
|
||||
try:
|
||||
status_response = request_agent_command(node.node_code,"phase6_status",{"client_id":int(selected_client.id)},timeout_seconds=20)
|
||||
status_response = request_agent_command(node.node_code,"phase6_status",_accounting_storage_payload(selected_client),timeout_seconds=20)
|
||||
if status_response.get("ok"): live_result=status_response.get("result") or {}
|
||||
else: command_error=str(status_response.get("error") or "Local Agent status failed.")
|
||||
chosen_guid=str(tally_guid or "").strip()
|
||||
if chosen_guid:
|
||||
preview_response=request_agent_command(node.node_code,"accounting_depreciation_preview",{"client_id":int(selected_client.id),"tally_guid":chosen_guid,"fy_start":start_text,"fy_end":end_text},timeout_seconds=60)
|
||||
preview_response=request_agent_command(node.node_code,"accounting_depreciation_preview",{**_accounting_storage_payload(selected_client),"tally_guid":chosen_guid,"fy_start":start_text,"fy_end":end_text},timeout_seconds=60)
|
||||
if preview_response.get("ok"): preview=(preview_response.get("result") or {}).get("preview")
|
||||
else: command_error=str(preview_response.get("error") or "Depreciation preview failed.")
|
||||
if run_id:
|
||||
run_response=request_agent_command(node.node_code,"accounting_get_it_depreciation_run",{"client_id":int(selected_client.id),"run_id":int(run_id)},timeout_seconds=30)
|
||||
run_response=request_agent_command(node.node_code,"accounting_get_it_depreciation_run",{**_accounting_storage_payload(selected_client),"run_id":int(run_id)},timeout_seconds=30)
|
||||
if run_response.get("ok"): depreciation_run=(run_response.get("result") or {}).get("depreciation")
|
||||
except Exception as exc: command_error=str(exc)
|
||||
base={"request":request,"current_user":user,"current_user_roles":get_user_roles(db,user.id),"current_user_permissions":get_user_permissions(db,user.id),"csrf_token":get_or_create_csrf_token(request)}
|
||||
@@ -537,7 +545,7 @@ async def calculate_it_depreciation(request: Request):
|
||||
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/depreciation?client_id={client.id}&tally_guid={quote(tally_guid)}&fy_start={start.isoformat()}&fy_end={end.isoformat()}&error={quote('ERP Local Agent is offline for the active branch.')}",status_code=303)
|
||||
try:
|
||||
result=request_agent_command(node.node_code,"accounting_calculate_it_depreciation",{"client_id":int(client.id),"tally_guid":tally_guid,"fy_start":start.isoformat(),"fy_end":end.isoformat(),"assignments":assignments,"depreciation_expense_ledger":str(form.get("depreciation_expense_ledger") or ""),"depreciation_reserve_ledger":str(form.get("depreciation_reserve_ledger") or ""),"requested_by_user_id":int(user.id)},timeout_seconds=120)
|
||||
result=request_agent_command(node.node_code,"accounting_calculate_it_depreciation",{**_accounting_storage_payload(client),"tally_guid":tally_guid,"fy_start":start.isoformat(),"fy_end":end.isoformat(),"assignments":assignments,"depreciation_expense_ledger":str(form.get("depreciation_expense_ledger") or ""),"depreciation_reserve_ledger":str(form.get("depreciation_reserve_ledger") or ""),"requested_by_user_id":int(user.id)},timeout_seconds=120)
|
||||
if not result.get("ok"): raise RuntimeError(str(result.get("error") or "Income-tax depreciation calculation failed."))
|
||||
dep=(result.get("result") or {}).get("depreciation") or {}; rid=int(dep.get("run_id"))
|
||||
except Exception as exc:
|
||||
@@ -569,7 +577,7 @@ async def approve_it_depreciation(request: Request):
|
||||
try:
|
||||
result = request_agent_command(
|
||||
node.node_code, "accounting_approve_it_depreciation",
|
||||
{"client_id": client_id, "run_id": run_id, "approved_by_user_id": int(user.id), "approval_note": str(form.get("approval_note") or "")},
|
||||
{**_accounting_storage_payload(client), "run_id": run_id, "approved_by_user_id": int(user.id), "approval_note": str(form.get("approval_note") or "")},
|
||||
timeout_seconds=30,
|
||||
)
|
||||
if not result.get("ok"): raise RuntimeError(str(result.get("error") or "Approval failed."))
|
||||
@@ -606,7 +614,7 @@ async def post_it_depreciation_to_tally(request: Request):
|
||||
try:
|
||||
result = request_agent_command(
|
||||
node.node_code, "accounting_post_it_depreciation",
|
||||
{"client_id": client_id, "run_id": run_id, "posted_by_user_id": int(user.id)},
|
||||
{**_accounting_storage_payload(client), "run_id": run_id, "posted_by_user_id": int(user.id)},
|
||||
timeout_seconds=120,
|
||||
)
|
||||
if not result.get("ok"): raise RuntimeError(str(result.get("error") or "Tally write-back failed."))
|
||||
|
||||
Reference in New Issue
Block a user