Add client financial year Accounting Mirror registry

This commit is contained in:
A R R R Associates
2026-09-18 20:58:41 +05:30
parent 93f2e02c35
commit 8a0d5b212d
11 changed files with 630 additions and 71 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ import io
from pathlib import Path
import zipfile
ERP_LOCAL_AGENT_VERSION = "1.26.16"
ERP_LOCAL_AGENT_VERSION = "1.26.17"
ERP_LOCAL_AGENT_NAME = "ERP Local Agent"
RUNTIME_ROOT = Path(__file__).resolve().parent / "local_agent_runtime"
_DETERMINISTIC_ZIP_TIMESTAMP = (2026, 1, 1, 0, 0, 0)
@@ -1,2 +1,2 @@
__version__ = "1.26.16"
__version__ = "1.26.17"
AGENT_NAME = "ERP Local Agent"
@@ -179,6 +179,8 @@ class AgentCommandProcessor:
result = self._post_it_depreciation(payload)
elif action == "accounting_mirror_status":
result = self._accounting_mirror_status(payload)
elif action == "accounting_mirror_list":
result = self._accounting_mirror_list(payload)
elif action == "accounting_mirror_sync":
result = self._accounting_mirror_sync(payload)
elif action == "accounting_full_export_start":
@@ -4192,6 +4194,65 @@ class AgentCommandProcessor:
"financial_year_to": fy_to.isoformat(),
}
def _accounting_mirror_list(self, payload: dict[str, Any]) -> dict[str, Any]:
"""Discover already-created FY mirrors for one client without relying on Tally names.
This scans only the canonical Storage Node hierarchy and returns file metadata
needed by the ERP mirror registry. No mirror is modified.
"""
import sqlite3 as _sqlite3
client_id = int(payload.get("client_id") or 0)
if client_id <= 0:
raise ValueError("client_id is required.")
filename = f"client_{client_id:08d}.act"
items: list[dict[str, Any]] = []
pattern = f"FY*/Clients/*/*/Accounting/{filename}"
for path in sorted(self.store.storage_root.glob(pattern)):
if not path.is_file():
continue
try:
relative = path.parent.relative_to(self.store.storage_root).as_posix()
except Exception:
continue
first = relative.split("/", 1)[0]
fy = first[2:] if first.upper().startswith("FY") else ""
if not re.fullmatch(r"\d{4}-\d{2}", fy):
continue
company: dict[str, Any] = {}
voucher_period = {"from_date": "", "to_date": ""}
ready = False
try:
db = _sqlite3.connect(path, timeout=15)
db.row_factory = _sqlite3.Row
try:
row = db.execute("SELECT * FROM company_master ORDER BY synced_at DESC LIMIT 1").fetchone()
company = dict(row) if row else {}
period = db.execute("SELECT MIN(voucher_date) AS from_date, MAX(voucher_date) AS to_date FROM voucher").fetchone()
if period:
voucher_period = dict(period)
ready = bool(company)
finally:
db.close()
except Exception:
ready = False
items.append({
"client_id": client_id,
"financial_year": fy,
"accounting_relative_dir": relative,
"accounting_db_path": str(path),
"company_name": str(company.get("company_name") or "").strip(),
"tally_guid": str(company.get("company_guid") or "").strip(),
"mirror": {
"ready": ready,
"path": str(path),
"size_bytes": path.stat().st_size,
"company": company,
"voucher_period": voucher_period,
},
})
return {"mirrors": items, "count": len(items), "agent": self._agent_info()}
def _accounting_mirror_status(self, payload: dict[str, Any]) -> dict[str, Any]:
client_id = int(payload.get("client_id") or 0)
if client_id <= 0:
@@ -4248,6 +4309,10 @@ class AgentCommandProcessor:
"job_id": job_id, "status": "queued", "percent": 1,
"stage": "Queued", "message": "Full Accounting Export queued on the Local Agent.",
"client_id": client_id, "company_name": company_name, "tally_guid": tally_guid,
"financial_year": str(payload.get("financial_year") or "").strip(),
"accounting_relative_dir": str(payload.get("accounting_relative_dir") or "").strip(),
"requested_by_user_id": requested_by,
"replacement_requested": bool(payload.get("replacement_requested")),
"date_from": date_from, "date_to": date_to, "rows": {},
"started_at_utc": now, "updated_at_utc": now, "finished_at_utc": "",
"error": "", "mirror_db_path": "", "accounting_db_path": str(self.store.db_path(client_id)),