181 lines
24 KiB
HTML
181 lines
24 KiB
HTML
{% extends "ui/templates/base/layout.html" %}
|
|
{% block content %}
|
|
<div class="space-y-6">
|
|
<div class="flex items-center justify-between">
|
|
<div><h2 class="text-xl font-semibold text-slate-900">Engagement</h2><p class="text-sm text-slate-500">{{ row.client.client_name if row.client else '-' }} · {{ row.catalogue.service_name if row.catalogue else '-' }} · FY {{ row.financial_year }}</p></div>
|
|
<div class="flex gap-2">
|
|
<a href="/services/engagements?financial_year={{ row.financial_year }}" class="rounded-xl border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Back</a>
|
|
{% if can_manage and not row.is_locked %}<a href="/services/engagements/{{ row.id }}/edit" class="rounded-xl bg-brand-600 px-4 py-2 text-sm font-medium text-white hover:bg-brand-700">Edit</a>{% endif %}
|
|
</div>
|
|
</div>
|
|
{% if row.is_locked %}<div class="rounded-2xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-800">This engagement is locked as historical record. It cannot be edited.</div>{% endif %}
|
|
<div class="grid gap-6 lg:grid-cols-2">
|
|
<section class="rounded-2xl bg-white p-5 shadow-soft"><h3 class="text-sm font-semibold text-slate-900">Client & Service</h3><dl class="mt-4 space-y-3 text-sm"><div><dt class="text-slate-500">Client</dt><dd class="font-medium text-slate-900">{{ row.client.client_name if row.client else '-' }}</dd></div><div><dt class="text-slate-500">Service</dt><dd class="font-medium text-slate-900">{{ row.catalogue.service_name if row.catalogue else '-' }}</dd></div><div><dt class="text-slate-500">Financial Year</dt><dd>{{ row.financial_year or '-' }}</dd></div><div><dt class="text-slate-500">Assessment Year</dt><dd>{{ row.assessment_year or '-' }}</dd></div><div><dt class="text-slate-500">Engagement Type</dt><dd>{{ 'Assurance' if row.engagement_type == 'assurance' else 'Non-Assurance' }}</dd></div><div><dt class="text-slate-500">Original Due Date</dt><dd>{{ row.original_due_date or '-' }}</dd></div><div><dt class="text-slate-500">Expiry Date</dt><dd>{{ row.expiry_date or '-' }}</dd></div><div><dt class="text-slate-500">Current Due Date</dt><dd class="font-medium text-slate-900">{{ row.current_due_date or '-' }}{% if row.due_date_source %}<span class="ml-2 rounded-full bg-slate-100 px-2 py-1 text-xs font-medium text-slate-600">{{ row.due_date_source|replace('_',' ')|title }}</span>{% endif %}</dd></div><div><dt class="text-slate-500">Status</dt><dd>{{ 'Locked' if row.is_locked else row.status|replace('_',' ')|title }}{% if not row.is_active %} / Inactive{% endif %}</dd></div><div><dt class="text-slate-500">Period</dt><dd>{{ row.start_date or '-' }} to {{ row.end_date or '-' }}</dd></div></dl></section>
|
|
<section class="rounded-2xl bg-white p-5 shadow-soft"><h3 class="text-sm font-semibold text-slate-900">Assignment</h3><dl class="mt-4 space-y-3 text-sm"><div><dt class="text-slate-500">Partner</dt><dd>{{ row.assigned_partner.full_name if row.assigned_partner and row.assigned_partner.full_name else (row.assigned_partner.email if row.assigned_partner else '-') }}</dd></div><div><dt class="text-slate-500">Manager</dt><dd>{{ row.assigned_manager.full_name if row.assigned_manager and row.assigned_manager.full_name else (row.assigned_manager.email if row.assigned_manager else '-') }}</dd></div><div><dt class="text-slate-500">Staff</dt><dd>{{ row.assigned_staff.full_name if row.assigned_staff and row.assigned_staff.full_name else (row.assigned_staff.email if row.assigned_staff else '-') }}</dd></div><div><dt class="text-slate-500">Review Partner</dt><dd>{{ row.review_partner.full_name if row.review_partner and row.review_partner.full_name else (row.review_partner.email if row.review_partner else '-') }}</dd></div></dl></section>
|
|
</div>
|
|
|
|
{% if row.quality_workflow_required %}
|
|
<section class="rounded-2xl border border-indigo-200 bg-indigo-50 p-5 shadow-soft">
|
|
<div class="flex flex-wrap items-start justify-between gap-4">
|
|
<div>
|
|
<h3 class="text-sm font-semibold text-indigo-950">AQMM Engagement Quality Workflow</h3>
|
|
<p class="mt-1 text-sm text-indigo-800">Mandatory because this is an assurance engagement. Client master creation and CSV import do not trigger AQMM; this workflow is engagement-specific.</p>
|
|
</div>
|
|
<span class="rounded-full px-3 py-1 text-xs font-semibold {% if row.quality_acceptance_status == 'approved' %}bg-emerald-100 text-emerald-700{% elif row.quality_workflow_status == 'ready_for_approval' %}bg-sky-100 text-sky-700{% else %}bg-amber-100 text-amber-800{% endif %}">{{ row.quality_workflow_status|replace('_',' ')|title }}</span>
|
|
</div>
|
|
|
|
{% if row.quality_block_reason %}<div class="mt-3 rounded-xl border border-amber-200 bg-white/80 px-4 py-3 text-sm text-amber-800">Blocked reason: {{ row.quality_block_reason }}</div>{% endif %}
|
|
|
|
<div class="mt-4 grid gap-3 md:grid-cols-4">
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-indigo-100"><div class="text-xs font-semibold uppercase text-slate-500">Independence</div><div class="mt-1 text-sm font-medium text-slate-900">{{ row.quality_independence_status|replace('_',' ')|title }}</div></div>
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-indigo-100"><div class="text-xs font-semibold uppercase text-slate-500">Conflict</div><div class="mt-1 text-sm font-medium text-slate-900">{{ row.quality_conflict_status|replace('_',' ')|title }}</div></div>
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-indigo-100"><div class="text-xs font-semibold uppercase text-slate-500">KYC</div><div class="mt-1 text-sm font-medium text-slate-900">{{ row.quality_kyc_status|replace('_',' ')|title }}</div></div>
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-indigo-100"><div class="text-xs font-semibold uppercase text-slate-500">Engagement Letter</div><div class="mt-1 text-sm font-medium text-slate-900">{{ row.quality_engagement_letter_status|replace('_',' ')|title }}</div></div>
|
|
</div>
|
|
|
|
{% if can_manage and not row.is_locked %}
|
|
<div class="mt-5 flex flex-wrap gap-2">
|
|
<form method="post" action="/services/engagements/{{ row.id }}/aqmm/initiate"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><button class="rounded-xl bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700">Initiate / Sync AQMM</button></form>
|
|
<form method="post" action="/services/engagements/{{ row.id }}/aqmm/request-declarations"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><button class="rounded-xl border border-indigo-300 bg-white px-4 py-2 text-sm font-medium text-indigo-700 hover:bg-indigo-50">Request Declarations</button></form>
|
|
<form method="post" action="/services/engagements/{{ row.id }}/aqmm/kyc/verify" class="flex gap-2"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><input name="notes" placeholder="KYC notes" class="rounded-xl border border-indigo-200 px-3 py-2 text-sm"><button class="rounded-xl border border-indigo-300 bg-white px-4 py-2 text-sm font-medium text-indigo-700 hover:bg-indigo-50">Verify KYC</button></form>
|
|
</div>
|
|
<div class="mt-3 flex flex-wrap gap-2">
|
|
<form method="post" action="/services/engagements/{{ row.id }}/aqmm/engagement-letter/complete" class="flex gap-2"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><select name="acceptance_mode" class="rounded-xl border border-indigo-200 px-3 py-2 text-sm"><option value="digital_otp">Digital OTP accepted</option><option value="manual_signed_upload">Manual signed copy verified</option></select><input name="notes" placeholder="Letter evidence note" class="rounded-xl border border-indigo-200 px-3 py-2 text-sm"><button class="rounded-xl border border-indigo-300 bg-white px-4 py-2 text-sm font-medium text-indigo-700 hover:bg-indigo-50">Complete Engagement Letter</button></form>
|
|
<form method="post" action="/services/engagements/{{ row.id }}/aqmm/approve"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><button class="rounded-xl bg-emerald-600 px-4 py-2 text-sm font-medium text-white hover:bg-emerald-700">Approve AQMM & Activate</button></form>
|
|
</div>
|
|
{% endif %}
|
|
|
|
|
|
<div class="mt-5 rounded-2xl border border-white bg-white p-4">
|
|
<div class="flex flex-wrap items-start justify-between gap-3">
|
|
<div>
|
|
<h4 class="text-sm font-semibold text-slate-900">AQMM Quality Checklist Tasks</h4>
|
|
<p class="mt-1 text-xs text-slate-500">These are your existing service tasks tagged as part of AQMM. No separate checklist is created.</p>
|
|
</div>
|
|
<div class="grid grid-cols-2 gap-2 text-xs md:grid-cols-4">
|
|
<span class="rounded-xl bg-slate-100 px-3 py-2">Total: <strong>{{ aqmm_task_summary.total if aqmm_task_summary else 0 }}</strong></span>
|
|
<span class="rounded-xl bg-emerald-100 px-3 py-2 text-emerald-800">Completed: <strong>{{ aqmm_task_summary.completed if aqmm_task_summary else 0 }}</strong></span>
|
|
<span class="rounded-xl bg-amber-100 px-3 py-2 text-amber-800">Evidence Missing: <strong>{{ aqmm_task_summary.evidence_missing if aqmm_task_summary else 0 }}</strong></span>
|
|
<span class="rounded-xl bg-purple-100 px-3 py-2 text-purple-800">Final Blockers: <strong>{{ aqmm_task_summary.blockers|length if aqmm_task_summary else 0 }}</strong></span>
|
|
</div>
|
|
</div>
|
|
<div class="mt-4 overflow-hidden rounded-xl border border-slate-200">
|
|
<table class="min-w-full divide-y divide-slate-200 text-sm">
|
|
<thead class="bg-slate-50"><tr><th class="px-3 py-2 text-left">Task</th><th class="px-3 py-2 text-left">AQMM Flags</th><th class="px-3 py-2 text-left">Evidence</th><th class="px-3 py-2 text-left">Status</th><th class="px-3 py-2 text-right">Action</th></tr></thead>
|
|
<tbody class="divide-y divide-slate-100">
|
|
{% for item in aqmm_task_summary.rows if aqmm_task_summary %}
|
|
{% set task = item.task %}
|
|
<tr>
|
|
<td class="px-3 py-2"><div class="font-medium text-slate-900">{{ task.sequence_no }}. {{ task.task_name }}</div>{% if task.aqmm_reference %}<div class="text-xs text-slate-500">{{ task.aqmm_reference }}</div>{% endif %}</td>
|
|
<td class="px-3 py-2 text-xs"><div class="flex flex-wrap gap-1">{% if task.aqmm_mandatory %}<span class="rounded-full bg-rose-100 px-2 py-1 text-rose-800">Mandatory</span>{% endif %}{% if task.aqmm_evidence_required %}<span class="rounded-full bg-sky-100 px-2 py-1 text-sky-800">Evidence</span>{% endif %}{% if task.aqmm_manager_review_required %}<span class="rounded-full bg-amber-100 px-2 py-1 text-amber-800">Manager</span>{% endif %}{% if task.aqmm_partner_review_required %}<span class="rounded-full bg-indigo-100 px-2 py-1 text-indigo-800">Partner</span>{% endif %}{% if task.aqmm_review_partner_required %}<span class="rounded-full bg-purple-100 px-2 py-1 text-purple-800">Review Partner</span>{% endif %}{% if task.aqmm_blocks_final_release %}<span class="rounded-full bg-slate-900 px-2 py-1 text-white">Final Gate</span>{% endif %}</div></td>
|
|
<td class="px-3 py-2">{{ 'Uploaded' if item.has_evidence else ('Required' if task.aqmm_evidence_required else '-') }}</td>
|
|
<td class="px-3 py-2"><span class="rounded-full px-2 py-1 text-xs font-medium {{ 'bg-emerald-100 text-emerald-800' if item.passes else 'bg-amber-100 text-amber-800' }}">{{ 'OK' if item.passes else item.issue }}</span><div class="mt-1 text-xs text-slate-500">Task: {{ task.status|replace('_',' ')|title }}</div></td>
|
|
<td class="px-3 py-2 text-right"><a href="/documents/tasks/{{ task.id }}" class="text-xs font-medium text-brand-700 hover:underline">Open Evidence</a></td>
|
|
</tr>
|
|
{% else %}
|
|
<tr><td colspan="5" class="px-3 py-6 text-center text-sm text-slate-500">No AQMM-tagged task generated yet. Mark selected service tasks as AQMM and generate work tracker tasks.</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{% if my_pending_declarations %}
|
|
<div class="mt-5 rounded-2xl border border-white bg-white p-4">
|
|
<h4 class="text-sm font-semibold text-slate-900">My Pending Declarations</h4>
|
|
<div class="mt-3 space-y-3">
|
|
{% for declaration in my_pending_declarations %}
|
|
<form method="post" action="/services/engagements/{{ row.id }}/aqmm/declarations/{{ declaration.id }}/respond" class="rounded-xl border border-slate-200 p-3">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<div class="text-sm font-medium text-slate-900">{{ declaration.declaration_type|title }} Declaration</div>
|
|
<textarea name="notes" rows="2" placeholder="Declaration remarks / safeguards if any" class="mt-2 w-full rounded-xl border border-slate-300 px-3 py-2 text-sm"></textarea>
|
|
<div class="mt-2 flex flex-wrap gap-2"><button name="status" value="declared_clear" class="rounded-xl bg-emerald-600 px-3 py-2 text-xs font-medium text-white">Declare Clear</button><button name="status" value="conflict_declared" class="rounded-xl bg-rose-600 px-3 py-2 text-xs font-medium text-white">Report Issue / Conflict</button><button name="status" value="not_applicable" class="rounded-xl border border-slate-300 px-3 py-2 text-xs font-medium text-slate-700">Not Applicable</button></div>
|
|
</form>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if declarations %}
|
|
<div class="mt-5 overflow-hidden rounded-2xl bg-white border border-indigo-100">
|
|
<div class="border-b border-slate-100 px-4 py-3 text-sm font-semibold text-slate-900">Declarations</div>
|
|
<table class="min-w-full divide-y divide-slate-200 text-sm"><thead class="bg-slate-50"><tr><th class="px-3 py-2 text-left">Type</th><th class="px-3 py-2 text-left">User</th><th class="px-3 py-2 text-left">Role</th><th class="px-3 py-2 text-left">Status</th><th class="px-3 py-2 text-left">Responded</th></tr></thead><tbody class="divide-y divide-slate-100">{% for d in declarations %}<tr><td class="px-3 py-2">{{ d.declaration_type|title }}</td><td class="px-3 py-2">{{ d.requested_user.full_name if d.requested_user and d.requested_user.full_name else (d.requested_user.email if d.requested_user else '-') }}</td><td class="px-3 py-2">{{ d.requested_role or '-' }}</td><td class="px-3 py-2">{{ d.status|replace('_',' ')|title }}</td><td class="px-3 py-2">{{ d.responded_at_utc or '-' }}</td></tr>{% endfor %}</tbody></table>
|
|
</div>
|
|
{% endif %}
|
|
</section>
|
|
{% endif %}
|
|
|
|
{% if closure_checklist %}
|
|
<section class="rounded-2xl border border-emerald-200 bg-emerald-50 p-5 shadow-soft">
|
|
<div class="flex flex-wrap items-start justify-between gap-4">
|
|
<div>
|
|
<h3 class="text-sm font-semibold text-emerald-950">Engagement Closure Checklist</h3>
|
|
<p class="mt-1 text-sm text-emerald-800">Closure uses existing AQMM acceptance, AQMM-tagged tasks, task evidence/review notes, final document release and UDIN controls. Only final delivery confirmations are manual.</p>
|
|
</div>
|
|
<span class="rounded-full px-3 py-1 text-xs font-semibold {% if closure_checklist.closure_status == 'closed' %}bg-emerald-600 text-white{% elif closure_checklist.closure_status == 'ready_for_partner_closure' %}bg-sky-100 text-sky-800{% elif closure_checklist.closure_status == 'reopened' %}bg-amber-100 text-amber-800{% else %}bg-white text-slate-700{% endif %}">{{ closure_checklist.closure_status|replace('_',' ')|title }}</span>
|
|
</div>
|
|
|
|
{% if closure_checklist.closure_block_reason %}<div class="mt-3 rounded-xl border border-amber-200 bg-white px-4 py-3 text-sm text-amber-800">Closure pending: {{ closure_checklist.closure_block_reason }}</div>{% endif %}
|
|
|
|
<div class="mt-4 grid gap-3 md:grid-cols-3 lg:grid-cols-6">
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-emerald-100"><div class="text-xs font-semibold uppercase text-slate-500">Tasks</div><div class="mt-1 text-sm font-medium {{ 'text-emerald-700' if closure_checklist.normal_tasks_completed else 'text-amber-700' }}">{{ 'Completed' if closure_checklist.normal_tasks_completed else 'Pending' }}</div></div>
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-emerald-100"><div class="text-xs font-semibold uppercase text-slate-500">AQMM Acceptance</div><div class="mt-1 text-sm font-medium {{ 'text-emerald-700' if closure_checklist.aqmm_acceptance_completed else 'text-amber-700' }}">{{ 'Completed' if closure_checklist.aqmm_acceptance_completed else 'Pending' }}</div></div>
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-emerald-100"><div class="text-xs font-semibold uppercase text-slate-500">AQMM Tasks</div><div class="mt-1 text-sm font-medium {{ 'text-emerald-700' if closure_checklist.aqmm_tasks_completed else 'text-amber-700' }}">{{ 'Completed' if closure_checklist.aqmm_tasks_completed else 'Pending' }}</div></div>
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-emerald-100"><div class="text-xs font-semibold uppercase text-slate-500">Evidence / Reviews</div><div class="mt-1 text-sm font-medium {{ 'text-emerald-700' if closure_checklist.evidence_review_completed else 'text-amber-700' }}">{{ 'Completed' if closure_checklist.evidence_review_completed else 'Pending' }}</div></div>
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-emerald-100"><div class="text-xs font-semibold uppercase text-slate-500">Final Release</div><div class="mt-1 text-sm font-medium {{ 'text-emerald-700' if closure_checklist.final_documents_released else 'text-amber-700' }}">{{ 'Completed' if closure_checklist.final_documents_released else 'Pending' }}</div></div>
|
|
<div class="rounded-xl bg-white px-4 py-3 border border-emerald-100"><div class="text-xs font-semibold uppercase text-slate-500">UDIN</div><div class="mt-1 text-sm font-medium {{ 'text-emerald-700' if closure_checklist.udin_completed else 'text-amber-700' }}">{{ 'Completed' if closure_checklist.udin_completed else 'Pending' }}</div></div>
|
|
</div>
|
|
|
|
<form method="post" action="/services/engagements/{{ row.id }}/closure/update" class="mt-5 rounded-2xl bg-white p-4 border border-emerald-100">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<h4 class="text-sm font-semibold text-slate-900">Manual Closure Confirmations</h4>
|
|
<div class="mt-3 grid gap-3 md:grid-cols-2">
|
|
<label class="flex items-center gap-2 rounded-xl border border-slate-200 px-3 py-2 text-sm"><input type="checkbox" name="deliverables_sent_to_client" {% if closure_checklist.deliverables_sent_to_client %}checked{% endif %} {% if row.is_locked and closure_checklist.closure_status == 'closed' %}disabled{% endif %}> Deliverables sent to client</label>
|
|
<label class="flex items-center gap-2 rounded-xl border border-slate-200 px-3 py-2 text-sm"><input type="checkbox" name="billing_reviewed" {% if closure_checklist.billing_reviewed %}checked{% endif %} {% if row.is_locked and closure_checklist.closure_status == 'closed' %}disabled{% endif %}> Billing / fee status reviewed</label>
|
|
<label class="flex items-center gap-2 rounded-xl border border-slate-200 px-3 py-2 text-sm"><input type="checkbox" name="open_points_closed" {% if closure_checklist.open_points_closed %}checked{% endif %} {% if row.is_locked and closure_checklist.closure_status == 'closed' %}disabled{% endif %}> Open points / rework items closed</label>
|
|
<label class="flex items-center gap-2 rounded-xl border border-slate-200 px-3 py-2 text-sm"><input type="checkbox" name="client_communication_completed" {% if closure_checklist.client_communication_completed %}checked{% endif %} {% if row.is_locked and closure_checklist.closure_status == 'closed' %}disabled{% endif %}> Client communication completed</label>
|
|
</div>
|
|
<textarea name="closure_note" rows="3" placeholder="Partner closure note / file completion remarks" class="mt-3 w-full rounded-xl border border-slate-300 px-3 py-2 text-sm" {% if row.is_locked and closure_checklist.closure_status == 'closed' %}disabled{% endif %}>{{ closure_checklist.closure_note or '' }}</textarea>
|
|
{% if can_manage and closure_checklist.closure_status != 'closed' %}<div class="mt-3 flex flex-wrap gap-2"><button class="rounded-xl border border-emerald-300 bg-white px-4 py-2 text-sm font-medium text-emerald-700 hover:bg-emerald-50">Save Closure Confirmations</button></div>{% endif %}
|
|
</form>
|
|
|
|
{% if can_manage %}
|
|
<div class="mt-4 flex flex-wrap gap-2">
|
|
{% if closure_checklist.closure_status != 'closed' %}
|
|
<form method="post" action="/services/engagements/{{ row.id }}/closure/sync"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><button class="rounded-xl border border-emerald-300 bg-white px-4 py-2 text-sm font-medium text-emerald-700 hover:bg-emerald-50">Recalculate Closure Readiness</button></form>
|
|
<form method="post" action="/services/engagements/{{ row.id }}/closure/approve"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><button class="rounded-xl bg-emerald-600 px-4 py-2 text-sm font-medium text-white hover:bg-emerald-700">Approve Closure & Lock</button></form>
|
|
{% else %}
|
|
<form method="post" action="/services/engagements/{{ row.id }}/closure/reopen" class="flex flex-wrap gap-2"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><input name="reason" required placeholder="Reason to reopen" class="rounded-xl border border-slate-300 px-3 py-2 text-sm"><button class="rounded-xl bg-amber-600 px-4 py-2 text-sm font-medium text-white hover:bg-amber-700">Reopen Engagement</button></form>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</section>
|
|
{% endif %}
|
|
|
|
{% if can_manage and not row.is_locked %}<form method="post" action="/services/engagements/{{ row.id }}/lock" class="rounded-2xl border border-amber-200 bg-white p-5 shadow-soft"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><h3 class="text-sm font-semibold text-slate-900">Year-end Lock</h3><p class="mt-2 text-sm text-slate-600">Lock this engagement when the year is complete. After locking, it becomes read-only history.</p><button class="mt-4 rounded-xl bg-amber-600 px-4 py-2 text-sm font-medium text-white hover:bg-amber-700">Lock Engagement</button></form>{% 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">Engagement Tasks & Task Documents</h3>
|
|
<p class="text-sm text-slate-500">Open each task to upload documents against its configured document requirements.</p>
|
|
</div>
|
|
<table class="min-w-full divide-y divide-slate-200">
|
|
<thead class="bg-slate-50"><tr><th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Seq</th><th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Task</th><th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Status</th><th class="px-4 py-3 text-right text-xs font-semibold uppercase tracking-wide text-slate-500">Documents</th></tr></thead>
|
|
<tbody class="divide-y divide-slate-100">
|
|
{% for task in tasks or [] %}
|
|
<tr>
|
|
<td class="px-4 py-3 text-sm font-medium text-slate-900">{{ task.sequence_no }}</td>
|
|
<td class="px-4 py-3 text-sm"><div class="font-medium text-slate-900">{{ task.task_name }}</div>{% if task.description %}<div class="text-xs text-slate-500">{{ task.description }}</div>{% endif %}{% if task.is_aqmm_task %}<div class="mt-1 flex flex-wrap gap-1 text-[11px]"><span class="rounded-full bg-indigo-100 px-2 py-1 text-indigo-800">AQMM</span>{% if task.aqmm_mandatory %}<span class="rounded-full bg-rose-100 px-2 py-1 text-rose-800">Mandatory</span>{% endif %}{% if task.aqmm_evidence_required %}<span class="rounded-full bg-sky-100 px-2 py-1 text-sky-800">Evidence</span>{% endif %}</div>{% endif %}</td>
|
|
<td class="px-4 py-3 text-sm text-slate-700">{{ task.status.replace('_',' ').title() }}</td>
|
|
<td class="px-4 py-3 text-right"><a href="/documents/tasks/{{ task.id }}" class="text-sm font-medium text-brand-700 hover:underline">Open Task Documents</a></td>
|
|
</tr>
|
|
{% else %}
|
|
<tr><td colspan="4" class="px-4 py-8 text-center text-sm text-slate-500">No execution tasks generated yet. Generate work tracker tasks first.</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
{% if row.remarks %}<section class="rounded-2xl bg-white p-5 shadow-soft"><h3 class="text-sm font-semibold text-slate-900">Remarks</h3><p class="mt-3 text-sm leading-6 text-slate-700">{{ row.remarks }}</p></section>{% endif %}
|
|
</div>
|
|
{% endblock %}
|