84 lines
2.7 KiB
Python
84 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from urllib.parse import urlencode
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TaskToolDefinition:
|
|
code: str
|
|
name: str
|
|
description: str
|
|
launch_url: str | None = None
|
|
|
|
|
|
_TASK_TOOLS: tuple[TaskToolDefinition, ...] = (
|
|
TaskToolDefinition(code="NONE", name="None", description="Normal task workflow without an attached ERP tool."),
|
|
TaskToolDefinition(
|
|
code="ACCOUNTING_OPENING_BALANCE",
|
|
name="Opening Balance Review",
|
|
description="Launch the existing Tally opening-balance comparison and verification tool.",
|
|
launch_url="/tools/accounting/opening-balances",
|
|
),
|
|
TaskToolDefinition(
|
|
code="ACCOUNTING_BANK_RECONCILIATION",
|
|
name="Bank Reconciliation",
|
|
description="Launch the existing accounting bank-reconciliation workspace.",
|
|
launch_url="/tools/accounting/bank-reconciliation",
|
|
),
|
|
TaskToolDefinition(
|
|
code="ACCOUNTING_DEPRECIATION_IT",
|
|
name="Depreciation (IT)",
|
|
description="Launch the existing Income-tax depreciation workspace connected to Tally.",
|
|
launch_url="/tools/tally/depreciation",
|
|
), TaskToolDefinition(
|
|
code="ACCOUNTING_CASH_PAYMENT_COMPLIANCE",
|
|
name="Cash Payment Tax Compliance Review",
|
|
description="Review Tally cash payments against the configurable limit, same-day aggregation and possible split-payment patterns.",
|
|
launch_url="/tools/accounting/cash-payments",
|
|
),
|
|
|
|
)
|
|
|
|
|
|
def list_task_tools() -> list[TaskToolDefinition]:
|
|
return list(_TASK_TOOLS)
|
|
|
|
|
|
def get_task_tool(code: str | None) -> TaskToolDefinition:
|
|
normalized = normalize_task_tool_code(code)
|
|
for tool in _TASK_TOOLS:
|
|
if tool.code == normalized:
|
|
return tool
|
|
return _TASK_TOOLS[0]
|
|
|
|
|
|
def normalize_task_tool_code(code: str | None) -> str:
|
|
value = (code or "NONE").strip().upper() or "NONE"
|
|
valid = {tool.code for tool in _TASK_TOOLS}
|
|
if value not in valid:
|
|
raise ValueError(f"Unsupported task tool: {value}")
|
|
return value
|
|
|
|
|
|
def build_task_tool_launch_url(
|
|
tool: TaskToolDefinition,
|
|
*,
|
|
client_id: int,
|
|
task_id: int,
|
|
tool_run_id: int,
|
|
) -> str:
|
|
if not tool.launch_url:
|
|
raise ValueError("This ERP task tool does not expose a launch URL.")
|
|
query = urlencode(
|
|
{
|
|
"client_id": int(client_id),
|
|
"task_id": int(task_id),
|
|
"task_tool_run_id": int(tool_run_id),
|
|
"task_return_url": f"/services/work-tracker/tasks/{int(task_id)}/edit",
|
|
"task_result_url": f"/services/work-tracker/tool-runs/{int(tool_run_id)}/result",
|
|
}
|
|
)
|
|
separator = "&" if "?" in tool.launch_url else "?"
|
|
return f"{tool.launch_url}{separator}{query}"
|