Add Phase 6 controlled Tally writeback

This commit is contained in:
A R R R Associates
2026-08-19 22:33:15 +05:30
parent 66d286fd55
commit 193fd4b71c
11 changed files with 464 additions and 21 deletions
+76 -2
View File
@@ -478,6 +478,8 @@ def depreciation_it_tool(
fy_start: str = "",
fy_end: str = "",
calculated: int = 0,
approved: int = 0,
posted: int = 0,
run_id: int | None = None,
error: str = "",
):
@@ -494,7 +496,7 @@ 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,"phase5_status",{"client_id":int(selected_client.id)},timeout_seconds=20)
status_response = request_agent_command(node.node_code,"phase6_status",{"client_id":int(selected_client.id)},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()
@@ -507,7 +509,7 @@ def depreciation_it_tool(
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)}
base.update({"title":"Income-tax Depreciation","clients":clients,"selected_client":selected_client,"storage_node":node,"agent_online":online,"live_result":live_result,"preview":preview,"selected_tally_guid":str(tally_guid or ""),"fy_start":start_text,"fy_end":end_text,"calculated":bool(calculated),"depreciation_run":depreciation_run,"command_error":command_error})
base.update({"title":"Income-tax Depreciation","clients":clients,"selected_client":selected_client,"storage_node":node,"agent_online":online,"live_result":live_result,"preview":preview,"selected_tally_guid":str(tally_guid or ""),"fy_start":start_text,"fy_end":end_text,"calculated":bool(calculated),"approved":bool(approved),"posted":bool(posted),"depreciation_run":depreciation_run,"command_error":command_error})
return templates.TemplateResponse("modules/accounting/templates/accounting/depreciation_it.html",base)
finally: db.close()
@@ -543,3 +545,75 @@ async def calculate_it_depreciation(request: Request):
return RedirectResponse(url=f"/tools/tally/depreciation?client_id={client.id}&tally_guid={quote(tally_guid)}&fy_start={start.isoformat()}&fy_end={end.isoformat()}&calculated=1&run_id={rid}",status_code=303)
finally: db.close()
@router.post("/depreciation/approve")
async def approve_it_depreciation(request: Request):
form = await request.form()
validate_csrf(request, str(form.get("csrf_token") or ""))
db = CommonSessionLocal()
try:
user, response = _require_partner(request, db, "accounting.tally.writeback")
if response: return response
try:
client_id = int(form.get("client_id")); run_id = int(form.get("run_id"))
except Exception:
return RedirectResponse(url="/tools/tally/depreciation?error=" + quote("Invalid depreciation draft."), status_code=303)
client, _clients, scope = _find_visible_client(db, request, user, client_id)
if not client: return _denied()
if str(form.get("confirm_approval") or "") != "yes":
return RedirectResponse(url=f"/tools/tally/depreciation?client_id={client_id}&run_id={run_id}&error={quote('Confirm that you reviewed the depreciation draft before approval.')}", status_code=303)
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}&run_id={run_id}&error={quote('ERP Local Agent is offline for the active branch.')}", status_code=303)
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 "")},
timeout_seconds=30,
)
if not result.get("ok"): raise RuntimeError(str(result.get("error") or "Approval failed."))
dep = (result.get("result") or {}).get("depreciation") or {}
guid = quote(str(dep.get("tally_guid") or ""))
return RedirectResponse(url=f"/tools/tally/depreciation?client_id={client_id}&tally_guid={guid}&fy_start={dep.get('fy_start','')}&fy_end={dep.get('fy_end','')}&run_id={run_id}&approved=1", status_code=303)
except Exception as exc:
return RedirectResponse(url=f"/tools/tally/depreciation?client_id={client_id}&run_id={run_id}&error={quote(str(exc))}", status_code=303)
finally:
db.close()
@router.post("/depreciation/post-to-tally")
async def post_it_depreciation_to_tally(request: Request):
form = await request.form()
validate_csrf(request, str(form.get("csrf_token") or ""))
db = CommonSessionLocal()
try:
user, response = _require_partner(request, db, "accounting.tally.writeback")
if response: return response
try:
client_id = int(form.get("client_id")); run_id = int(form.get("run_id"))
except Exception:
return RedirectResponse(url="/tools/tally/depreciation?error=" + quote("Invalid depreciation draft."), status_code=303)
client, _clients, scope = _find_visible_client(db, request, user, client_id)
if not client: return _denied()
if str(form.get("post_confirmation") or "").strip().upper() != "POST":
return RedirectResponse(url=f"/tools/tally/depreciation?client_id={client_id}&run_id={run_id}&error={quote('Type POST exactly to confirm Tally write-back.')}", status_code=303)
if str(form.get("confirm_posting") or "") != "yes":
return RedirectResponse(url=f"/tools/tally/depreciation?client_id={client_id}&run_id={run_id}&error={quote('Confirm that you want to create the Journal voucher in TallyPrime.')}", status_code=303)
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}&run_id={run_id}&error={quote('ERP Local Agent is offline for the active branch.')}", status_code=303)
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)},
timeout_seconds=120,
)
if not result.get("ok"): raise RuntimeError(str(result.get("error") or "Tally write-back failed."))
dep = (result.get("result") or {}).get("depreciation") or {}
guid = quote(str(dep.get("tally_guid") or ""))
return RedirectResponse(url=f"/tools/tally/depreciation?client_id={client_id}&tally_guid={guid}&fy_start={dep.get('fy_start','')}&fy_end={dep.get('fy_end','')}&run_id={run_id}&posted=1", status_code=303)
except Exception as exc:
return RedirectResponse(url=f"/tools/tally/depreciation?client_id={client_id}&run_id={run_id}&error={quote(str(exc))}", status_code=303)
finally:
db.close()