Add task role eligibility and safe open engagement sync

This commit is contained in:
A R R R Associates
2026-08-08 15:38:05 +05:30
parent 1a02af213d
commit 01a1c1abc1
7 changed files with 452 additions and 13 deletions
@@ -59,8 +59,19 @@
<input name="task_name" required class="w-full rounded-xl border border-slate-300 px-3 py-2 text-sm" placeholder="e.g. Verify books with GSTR-2B">
</div>
<div class="lg:col-span-3">
<label class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-500">Default Role</label>
<input name="default_role_name" class="w-full rounded-xl border border-slate-300 px-3 py-2 text-sm" placeholder="Staff / Manager / Partner">
<label class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-500">Default Assignee Role</label>
<select name="default_role_name" class="w-full rounded-xl border border-slate-300 px-3 py-2 text-sm">
<option value="">Automatic</option>
{% for role in task_execution_roles %}<option value="{{ role }}">{{ role }}</option>{% endfor %}
</select>
</div>
<div class="lg:col-span-12 rounded-xl border border-blue-200 bg-blue-50 p-3">
<div class="text-xs font-semibold uppercase tracking-wide text-blue-800">Eligible Roles</div>
<div class="mt-2 flex flex-wrap gap-4 text-xs text-slate-700">
{% for role in task_execution_roles %}
<label class="inline-flex items-center gap-1"><input type="checkbox" name="eligible_roles" value="{{ role }}"> {{ role }}</label>
{% endfor %}
</div>
</div>
<div class="lg:col-span-2">
<label class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-500">Sequence</label>
@@ -99,6 +110,32 @@
</section>
{% endif %}
{% if request.query_params.get('synced') %}
<div class="rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-800">
Open engagement sync completed:
{{ request.query_params.get('created', '0') }} missing task(s) added,
{{ request.query_params.get('updated_pending', '0') }} pending task(s) refreshed,
{{ request.query_params.get('updated_started', '0') }} started task assignee(s) refreshed,
{{ request.query_params.get('preserved', '0') }} historical/unsafe task(s) preserved.
</div>
{% endif %}
{% if can_manage_tasks %}
<section class="rounded-2xl border border-violet-200 bg-violet-50 p-4">
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<h3 class="text-sm font-semibold text-violet-950">Sync Firm Tasks to Open Engagements</h3>
<p class="mt-1 text-xs text-violet-800">Adds missing active tasks and refreshes pending/not-started role and assignee. Completed tasks, evidence, comments, review history and locked engagements are preserved.</p>
</div>
<form method="post" action="/services/templates/{{ service.id }}/sync-open-engagements" class="flex flex-wrap items-center gap-3" onsubmit="return confirm('Sync current firm task templates to open engagements?');">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<label class="inline-flex items-center gap-2 text-xs text-violet-900"><input type="checkbox" name="include_started_open_tasks"> Also reassign In Progress / Blocked</label>
<button type="submit" class="rounded-xl bg-violet-600 px-4 py-2 text-sm font-semibold text-white hover:bg-violet-700">Sync Open Engagements</button>
</form>
</div>
</section>
{% endif %}
<section class="overflow-hidden rounded-2xl bg-white shadow-soft">
<div class="border-b border-slate-100 px-5 py-4">
<h3 class="text-sm font-semibold text-slate-900">Firm Task List</h3>
@@ -124,7 +161,7 @@
<div class="font-medium text-slate-900">{{ task.task_name }}</div>
{% if task.description %}<div class="mt-1 text-xs text-slate-500">{{ task.description }}</div>{% endif %}
</td>
<td class="px-4 py-3 text-sm text-slate-700">{{ task.default_role_name or '-' }}</td>
<td class="px-4 py-3 text-sm text-slate-700"><div>{{ task.default_role_name or '-' }}</div><div class="mt-1 text-xs text-slate-500">Eligible: {{ task.eligible_role_names or task.default_role_name or '-' }}</div></td>
<td class="px-4 py-3 text-xs text-slate-600">
<div class="flex flex-wrap gap-1">
{% if task.is_mandatory %}<span class="rounded-full bg-slate-100 px-2 py-1">Mandatory</span>{% endif %}