Unify accounting analysis on Client FY mirror registry
This commit is contained in:
@@ -21,7 +21,7 @@ from app.core.security.csrf import get_or_create_csrf_token, validate_csrf
|
||||
from app.core.settings import get_settings
|
||||
from app.core.templating import templates
|
||||
from app.modules.accounting.agent_bridge import request_agent_command
|
||||
from app.modules.accounting.ui import _accounting_storage_payload, _find_visible_client, _require_partner, _visible_clients, _node_online
|
||||
from app.modules.accounting.ui import _accounting_storage_payload, _analysis_accounting_storage_payload, _find_visible_client, _require_partner, _visible_clients, _node_online
|
||||
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
|
||||
from app.modules.credential_vault.crypto import decrypt_value
|
||||
from app.modules.credential_vault.models import CredentialVaultEntry
|
||||
@@ -256,13 +256,18 @@ def _vault_entries(db, user, request, tenant_id: int, client_id: int, registrati
|
||||
return sorted(eligible, key=rank)
|
||||
|
||||
|
||||
def _storage_payload(client, fy: str, gstin: str) -> tuple[str, str]:
|
||||
def _storage_payload(client, fy: str, gstin: str, *, db=None, tenant_id: int | None = None, require_registered: bool = False) -> tuple[dict, str]:
|
||||
fy_folder = sanitize_segment(f"FY{fy}", "FY")
|
||||
letter, client_folder = client_folder_parts(client, int(client.id))
|
||||
root = Path(fy_folder) / "Clients" / letter / client_folder
|
||||
accounting = _accounting_storage_payload(client, fy)
|
||||
accounting_dir = str(accounting.get("accounting_relative_dir") or (root / "Accounting").as_posix()).strip()
|
||||
return accounting_dir, (root / "GST" / sanitize_segment(f"GSTIN_{gstin}", "GSTIN")).as_posix()
|
||||
if require_registered:
|
||||
accounting = _analysis_accounting_storage_payload(
|
||||
client, fy, db=db, tenant_id=tenant_id
|
||||
)
|
||||
else:
|
||||
accounting = _accounting_storage_payload(client, fy, db=db, tenant_id=tenant_id)
|
||||
accounting.setdefault("accounting_relative_dir", (root / "Accounting").as_posix())
|
||||
return accounting, (root / "GST" / sanitize_segment(f"GSTIN_{gstin}", "GSTIN")).as_posix()
|
||||
|
||||
|
||||
def _redirect(client_id: int, **params):
|
||||
@@ -490,7 +495,8 @@ def start_download(
|
||||
# Ensure FY is consistent in single-month mode.
|
||||
if download_mode == "single":
|
||||
financial_year=_fy_for_period(periods[0])
|
||||
accounting_dir,gst_dir=_storage_payload(client,financial_year,gstin)
|
||||
accounting_payload,gst_dir=_storage_payload(client,financial_year,gstin,db=db,tenant_id=scope.tenant_id)
|
||||
accounting_dir=str(accounting_payload.get("accounting_relative_dir") or "")
|
||||
jti=uuid.uuid4().hex
|
||||
token=_encode_operator_token({
|
||||
"jti":jti,"user_id":int(user.id),"tenant_id":int(scope.tenant_id),"branch_id":int(scope.branch_id),
|
||||
@@ -610,7 +616,8 @@ async def import_downloaded_returns(
|
||||
allowed_periods = set(_selected_periods(download_mode, financial_year, period))
|
||||
if download_mode == "single":
|
||||
financial_year = _fy_for_period(next(iter(allowed_periods)))
|
||||
accounting_dir, gst_dir = _storage_payload(client, financial_year, gstin)
|
||||
accounting_payload, gst_dir = _storage_payload(client, financial_year, gstin, db=db, tenant_id=scope.tenant_id)
|
||||
accounting_dir = str(accounting_payload.get("accounting_relative_dir") or "")
|
||||
groups = {
|
||||
"GSTR1": gstr1_files or [], "GSTR2B": gstr2b_files or [],
|
||||
"GSTR3B": gstr3b_files or [], "GSTR2A": gstr2a_files or [],
|
||||
@@ -719,13 +726,14 @@ def analyze(request: Request, client_id: int=Form(...), registration_id: int=For
|
||||
reg,_=pair; gstin=_norm_gstin(reg.registration_number)
|
||||
periods=_periods_for_fy(financial_year) if analyze_mode=="full_fy" else [re.sub(r"\D","",period or "")]
|
||||
if any(len(p)!=6 for p in periods): raise ValueError("Enter a valid MMYYYY period.")
|
||||
accounting_dir,gst_dir=_storage_payload(client,financial_year,gstin)
|
||||
accounting_payload,gst_dir=_storage_payload(client,financial_year,gstin,db=db,tenant_id=scope.tenant_id,require_registered=True)
|
||||
accounting_dir=str(accounting_payload.get("accounting_relative_dir") or "")
|
||||
node=get_active_storage_node_for_branch(db,scope.tenant_id,scope.branch_id)
|
||||
if not node or not _node_online(node): return _redirect(client_id,registration_id=registration_id,period=period,financial_year=financial_year,error="Local Storage Agent is offline.")
|
||||
results=[]
|
||||
for p in periods:
|
||||
date_from,date_to=_period_bounds(p)
|
||||
res=request_agent_command(node.node_code,"gst_reconciliation_analyze",{"client_id":client.id,"gstin":gstin,"financial_year":financial_year,"period":p,"gst_relative_dir":gst_dir,"accounting_relative_dir":accounting_dir,"date_from":date_from,"date_to":date_to},timeout_seconds=30)
|
||||
res=request_agent_command(node.node_code,"gst_reconciliation_analyze",{**accounting_payload,"client_id":client.id,"gstin":gstin,"financial_year":financial_year,"period":p,"gst_relative_dir":gst_dir,"accounting_relative_dir":accounting_dir,"date_from":date_from,"date_to":date_to},timeout_seconds=30)
|
||||
if res.get("ok"):
|
||||
results.append((res.get("result") or {}).get("analysis") or {})
|
||||
if not results: raise RuntimeError("No stored GST periods could be reconciled.")
|
||||
|
||||
Reference in New Issue
Block a user