Prepare ERP source for Gitea deployment

This commit is contained in:
A R R R Associates
2026-06-20 15:01:44 +05:30
commit 5c75eb6bd9
450 changed files with 67698 additions and 0 deletions
@@ -0,0 +1,32 @@
{% extends "ui/templates/base/layout.html" %}
{% block content %}
<div class="space-y-6">
<div class="flex items-start justify-between gap-4">
<div><h1 class="text-2xl font-bold text-slate-900">{{ case.case_code }} - {{ case.title }}</h1><p class="mt-1 text-sm text-slate-500">{{ case.client.client_name if case.client else '' }} · {{ case.department }} · {{ case.case_type }}</p></div>
<div class="flex gap-2"><a href="/notice-cases" class="rounded-lg border border-slate-300 px-4 py-2 text-sm">Back</a>{% if can_manage %}<a href="/notice-cases/{{ case.id }}/edit" class="rounded-lg bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Edit</a>{% endif %}</div>
</div>
<div class="grid gap-4 md:grid-cols-4">
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200"><div class="text-xs text-slate-500">Status</div><div class="font-semibold">{{ case.status|replace('_',' ')|title }}</div></div>
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200"><div class="text-xs text-slate-500">Due Date</div><div class="font-semibold">{{ case.due_date or '-' }}</div></div>
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200"><div class="text-xs text-slate-500">Reference</div><div class="font-semibold">{{ case.reference_no or '-' }}</div></div>
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200"><div class="text-xs text-slate-500">DIN/Ack</div><div class="font-semibold">{{ case.din_ack_no or '-' }}</div></div>
</div>
<div class="grid gap-6 lg:grid-cols-2">
<section class="rounded-xl bg-white p-5 shadow-sm ring-1 ring-slate-200"><h2 class="font-bold">Issue Summary</h2><p class="mt-3 whitespace-pre-wrap text-sm text-slate-700">{{ case.issue_summary or 'No issue summary captured.' }}</p></section>
<section class="rounded-xl bg-white p-5 shadow-sm ring-1 ring-slate-200"><h2 class="font-bold">Assignments</h2><dl class="mt-3 grid grid-cols-2 gap-3 text-sm"><dt class="text-slate-500">Partner</dt><dd>{{ case.assigned_partner.full_name if case.assigned_partner else '-' }}</dd><dt class="text-slate-500">Manager</dt><dd>{{ case.assigned_manager.full_name if case.assigned_manager else '-' }}</dd><dt class="text-slate-500">Staff</dt><dd>{{ case.assigned_staff.full_name if case.assigned_staff else '-' }}</dd><dt class="text-slate-500">FY/AY</dt><dd>{{ case.financial_year or '-' }} / {{ case.assessment_year or '-' }}</dd></dl></section>
</div>
<div class="grid gap-6 lg:grid-cols-2">
<section class="rounded-xl bg-white p-5 shadow-sm ring-1 ring-slate-200"><h2 class="font-bold">Add Timeline Event</h2><form method="post" action="/notice-cases/{{ case.id }}/events" class="mt-4 space-y-3"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><div class="grid gap-3 md:grid-cols-3"><select name="event_type" class="rounded-lg border px-3 py-2 text-sm">{% for e in event_types %}<option>{{ e }}</option>{% endfor %}</select><input type="date" name="event_date" class="rounded-lg border px-3 py-2 text-sm"><input type="date" name="next_due_date" class="rounded-lg border px-3 py-2 text-sm" title="Next due date"></div><textarea name="description" rows="3" required placeholder="Event details" class="w-full rounded-lg border px-3 py-2 text-sm"></textarea><button class="rounded-lg bg-slate-900 px-4 py-2 text-sm font-semibold text-white">Add Event</button></form></section>
<section class="rounded-xl bg-white p-5 shadow-sm ring-1 ring-slate-200"><h2 class="font-bold">Timeline</h2><div class="mt-4 space-y-3">{% for e in case.events %}<div class="border-l-2 border-brand-600 pl-3"><div class="text-sm font-semibold">{{ e.event_type }} · {{ e.event_date }}</div><div class="whitespace-pre-wrap text-sm text-slate-600">{{ e.description }}</div>{% if e.next_due_date %}<div class="text-xs text-slate-400">Next due: {{ e.next_due_date }}</div>{% endif %}</div>{% else %}<p class="text-sm text-slate-500">No timeline events.</p>{% endfor %}</div></section>
</div>
<div class="grid gap-6 lg:grid-cols-2">
<section class="rounded-xl bg-white p-5 shadow-sm ring-1 ring-slate-200"><h2 class="font-bold">Hearings</h2><form method="post" action="/notice-cases/{{ case.id }}/hearings" class="mt-4 grid gap-3 md:grid-cols-2"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><input type="date" name="hearing_date" required class="rounded-lg border px-3 py-2 text-sm"><input name="hearing_time" placeholder="Time" class="rounded-lg border px-3 py-2 text-sm"><input name="venue_or_mode" placeholder="Venue / Online mode" class="rounded-lg border px-3 py-2 text-sm"><input name="officer_name" placeholder="Officer name" class="rounded-lg border px-3 py-2 text-sm"><select name="status" class="rounded-lg border px-3 py-2 text-sm">{% for s in hearing_statuses %}<option value="{{ s }}">{{ s|title }}</option>{% endfor %}</select><textarea name="agenda" placeholder="Agenda" class="rounded-lg border px-3 py-2 text-sm md:col-span-2"></textarea><button class="rounded-lg bg-slate-900 px-4 py-2 text-sm font-semibold text-white md:col-span-2">Add Hearing</button></form><div class="mt-4 space-y-2 text-sm">{% for h in case.hearings %}<div class="rounded-lg bg-slate-50 p-3"><b>{{ h.hearing_date }}</b> {{ h.hearing_time or '' }} · {{ h.status|title }}<br>{{ h.venue_or_mode or '' }} {{ h.officer_name or '' }}</div>{% endfor %}</div></section>
<section class="rounded-xl bg-white p-5 shadow-sm ring-1 ring-slate-200"><h2 class="font-bold">Orders</h2><form method="post" action="/notice-cases/{{ case.id }}/orders" class="mt-4 grid gap-3 md:grid-cols-2"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><select name="order_type" class="rounded-lg border px-3 py-2 text-sm">{% for o in order_types %}<option>{{ o }}</option>{% endfor %}</select><input name="order_no" placeholder="Order No" class="rounded-lg border px-3 py-2 text-sm"><input type="date" name="order_date" required class="rounded-lg border px-3 py-2 text-sm"><input type="date" name="appeal_due_date" class="rounded-lg border px-3 py-2 text-sm"><input name="tax_amount" placeholder="Tax" type="number" class="rounded-lg border px-3 py-2 text-sm"><input name="interest_amount" placeholder="Interest" type="number" class="rounded-lg border px-3 py-2 text-sm"><input name="penalty_amount" placeholder="Penalty" type="number" class="rounded-lg border px-3 py-2 text-sm"><input name="demand_amount" placeholder="Total Demand" type="number" class="rounded-lg border px-3 py-2 text-sm"><textarea name="summary" placeholder="Order summary" class="rounded-lg border px-3 py-2 text-sm md:col-span-2"></textarea><label class="text-sm md:col-span-2"><input type="checkbox" name="appeal_filed" value="1"> Appeal filed</label><button class="rounded-lg bg-slate-900 px-4 py-2 text-sm font-semibold text-white md:col-span-2">Add Order</button></form><div class="mt-4 space-y-2 text-sm">{% for o in case.orders %}<div class="rounded-lg bg-slate-50 p-3"><b>{{ o.order_type }}</b> · {{ o.order_date }} · Demand: {{ o.demand_amount }}<br>{{ o.summary or '' }}</div>{% endfor %}</div></section>
</div>
<section class="rounded-xl bg-white p-5 shadow-sm ring-1 ring-slate-200"><div class="flex items-center justify-between"><h2 class="font-bold">Case Documents</h2></div>{% if can_upload %}<form method="post" enctype="multipart/form-data" action="/notice-cases/{{ case.id }}/documents/upload" class="mt-4 grid gap-3 md:grid-cols-5"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><input name="title" placeholder="Title" class="rounded-lg border px-3 py-2 text-sm"><select name="document_type" class="rounded-lg border px-3 py-2 text-sm">{% for d in case_document_types %}<option value="{{ d }}">{{ d }}</option>{% endfor %}</select><input name="description" placeholder="Description" class="rounded-lg border px-3 py-2 text-sm"><input type="file" name="file" required class="rounded-lg border px-3 py-2 text-sm"><button class="rounded-lg bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Upload</button></form>{% endif %}<div class="mt-4 overflow-hidden rounded-lg border"><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">Document</th><th class="px-3 py-2">Type</th><th class="px-3 py-2">Uploaded</th><th class="px-3 py-2 text-right">Action</th></tr></thead><tbody class="divide-y divide-slate-100">{% for d in case.documents if not d.is_deleted %}<tr><td class="px-3 py-2"><div class="font-semibold">{{ d.title }}</div><div class="text-xs text-slate-500">{{ d.original_filename }}</div></td><td class="px-3 py-2 text-center">{{ d.document_type }}</td><td class="px-3 py-2 text-center">{{ d.uploaded_at_utc.date() if d.uploaded_at_utc else '' }}</td><td class="px-3 py-2 text-right"><a href="/notice-cases/documents/{{ d.id }}/download" class="font-semibold text-brand-700">Download</a>{% if can_delete_documents %}<form method="post" action="/notice-cases/documents/{{ d.id }}/delete" class="inline"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><button class="ml-3 text-red-600" onclick="return confirm('Delete this document?')">Delete</button></form>{% endif %}</td></tr>{% else %}<tr><td colspan="4" class="px-3 py-6 text-center text-slate-500">No documents uploaded.</td></tr>{% endfor %}</tbody></table></div></section>
</div>
{% endblock %}
@@ -0,0 +1,44 @@
{% extends "ui/templates/base/layout.html" %}
{% block content %}
<div class="mx-auto max-w-5xl space-y-6">
<div>
<h1 class="text-2xl font-bold text-slate-900">{{ title }}</h1>
<p class="mt-1 text-sm text-slate-500">Capture notice/case details, due dates and responsibility.</p>
<p class="mt-1 text-xs font-semibold uppercase tracking-wide text-slate-400">Active FY: {{ active_financial_year or '-' }}{% if active_assessment_year %} · AY {{ active_assessment_year }}{% endif %}</p>
</div>
{% if form_error %}<div class="rounded-lg bg-red-50 p-3 text-sm text-red-700">{{ form_error }}</div>{% endif %}
<form method="post" class="space-y-5 rounded-xl bg-white p-5 shadow-sm ring-1 ring-slate-200">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<div class="grid gap-4 md:grid-cols-3">
<label class="space-y-1"><span class="text-sm font-medium">Client</span><select name="client_id" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm" {% if mode=='edit' %}disabled{% endif %}>{% for c in clients %}<option value="{{ c.id }}" {% if selected_client_id==c.id or (case and case.client_id==c.id) %}selected{% endif %}>{{ c.client_name }}{% if c.client_code %} ({{ c.client_code }}){% endif %}</option>{% endfor %}</select>{% if mode=='edit' %}<input type="hidden" name="client_id" value="{{ case.client_id }}">{% endif %}</label>
<label class="space-y-1"><span class="text-sm font-medium">Engagement Link</span><select name="engagement_id" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"><option value="">Not linked</option>{% for e in engagements %}<option value="{{ e.id }}" {% if case and case.engagement_id==e.id %}selected{% endif %}>{{ e.financial_year }} - {{ e.catalogue.service_name if e.catalogue else e.service_catalogue_id }}</option>{% endfor %}</select></label>
<label class="space-y-1"><span class="text-sm font-medium">Priority</span><select name="priority" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm">{% for p in case_priorities %}<option value="{{ p }}" {% if case and case.priority==p %}selected{% endif %}>{{ p|title }}</option>{% endfor %}</select></label>
</div>
<div class="grid gap-4 md:grid-cols-3">
<label class="space-y-1"><span class="text-sm font-medium">Department</span><select name="department" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm">{% for d in departments %}<option value="{{ d }}" {% if case and case.department==d %}selected{% endif %}>{{ d }}</option>{% endfor %}</select></label>
<label class="space-y-1"><span class="text-sm font-medium">Case Type</span><select name="case_type" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm">{% for t in case_types %}<option value="{{ t }}" {% if case and case.case_type==t %}selected{% endif %}>{{ t }}</option>{% endfor %}</select></label>
<label class="space-y-1"><span class="text-sm font-medium">Status</span><select name="status" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm">{% for s in case_statuses %}<option value="{{ s }}" {% if case and case.status==s %}selected{% endif %}>{{ s|replace('_',' ')|title }}</option>{% endfor %}</select></label>
</div>
<label class="block space-y-1"><span class="text-sm font-medium">Title</span><input name="title" value="{{ case.title if case else '' }}" required class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"></label>
<div class="grid gap-4 md:grid-cols-4">
<label class="space-y-1"><span class="text-sm font-medium">Reference No</span><input name="reference_no" value="{{ case.reference_no if case else '' }}" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"></label>
<label class="space-y-1"><span class="text-sm font-medium">DIN / Ack No</span><input name="din_ack_no" value="{{ case.din_ack_no if case else '' }}" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"></label>
<label class="space-y-1"><span class="text-sm font-medium">Notice Date</span><input type="date" name="notice_date" value="{{ case.notice_date if case and case.notice_date else '' }}" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"></label>
<label class="space-y-1"><span class="text-sm font-medium">Due Date</span><input type="date" name="due_date" value="{{ case.due_date if case and case.due_date else '' }}" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"></label>
</div>
<div class="grid gap-4 md:grid-cols-3">
<label class="space-y-1"><span class="text-sm font-medium">Financial Year</span><input name="financial_year" value="{{ case.financial_year if case else active_financial_year or '' }}" placeholder="2025-26" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"></label>
<label class="space-y-1"><span class="text-sm font-medium">Assessment Year</span><input name="assessment_year" value="{{ case.assessment_year if case else active_assessment_year or '' }}" placeholder="2026-27" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"></label>
<label class="space-y-1"><span class="text-sm font-medium">Period</span><input name="period_label" value="{{ case.period_label if case else '' }}" placeholder="Apr 2025 / Q1 / FY" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"></label>
</div>
<div class="grid gap-4 md:grid-cols-3">
{% for field,label in [('assigned_partner_user_id','Partner'),('assigned_manager_user_id','Manager'),('assigned_staff_user_id','Staff')] %}
<label class="space-y-1"><span class="text-sm font-medium">{{ label }}</span><select name="{{ field }}" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"><option value="">Not assigned</option>{% for u in assignable_users %}<option value="{{ u.id }}" {% if case and case[field]==u.id %}selected{% endif %}>{{ u.full_name or u.login_id or u.email }}</option>{% endfor %}</select></label>
{% endfor %}
</div>
<label class="block space-y-1"><span class="text-sm font-medium">Issue Summary</span><textarea name="issue_summary" rows="4" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm">{{ case.issue_summary if case else '' }}</textarea></label>
<label class="block space-y-1"><span class="text-sm font-medium">Remarks</span><textarea name="remarks" rows="3" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm">{{ case.remarks if case else '' }}</textarea></label>
<div class="flex justify-end gap-3"><a href="/notice-cases" class="rounded-lg border border-slate-300 px-4 py-2 text-sm">Cancel</a><button class="rounded-lg bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Save</button></div>
</form>
</div>
{% endblock %}
@@ -0,0 +1,49 @@
{% extends "ui/templates/base/layout.html" %}
{% block content %}
<div class="space-y-6">
<div class="flex flex-wrap items-start justify-between gap-4">
<div>
<h1 class="text-2xl font-bold text-slate-900">Notices & Cases</h1>
<p class="mt-1 text-sm text-slate-500">Track GST, Income Tax, ROC, PF/ESI notices, appeals, hearings, orders and case documents.</p>
<p class="mt-1 text-xs font-semibold uppercase tracking-wide text-slate-400">
Showing: {% if financial_year == 'all' %}All Financial Years{% else %}FY {{ financial_year }}{% endif %}{% if assessment_year %} · AY {{ assessment_year }}{% endif %}
</p>
</div>
{% if can_manage %}<a href="/notice-cases/new" class="rounded-lg bg-brand-600 px-4 py-2 text-sm font-semibold text-white shadow hover:bg-brand-700">New Case</a>{% endif %}
</div>
<div class="grid gap-4 md:grid-cols-5">
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200"><div class="text-xs text-slate-500">Total</div><div class="mt-1 text-2xl font-semibold">{{ summary.total }}</div></div>
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200"><div class="text-xs text-slate-500">Open</div><div class="mt-1 text-2xl font-semibold text-blue-700">{{ summary.open }}</div></div>
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200"><div class="text-xs text-slate-500">Reply Pending</div><div class="mt-1 text-2xl font-semibold text-amber-700">{{ summary.reply_pending }}</div></div>
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200"><div class="text-xs text-slate-500">Hearings</div><div class="mt-1 text-2xl font-semibold text-purple-700">{{ summary.hearing_scheduled }}</div></div>
<div class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-red-200"><div class="text-xs text-red-500">Overdue</div><div class="mt-1 text-2xl font-semibold text-red-700">{{ summary.overdue }}</div></div>
</div>
<form method="get" class="grid gap-3 rounded-xl bg-white p-4 shadow-sm ring-1 ring-slate-200 md:grid-cols-7">
<input name="q" value="{{ q }}" placeholder="Search case/client/ref" class="rounded-lg border border-slate-300 px-3 py-2 text-sm md:col-span-2">
<select name="department" class="rounded-lg border border-slate-300 px-3 py-2 text-sm"><option value="">All Departments</option>{% for d in departments %}<option value="{{ d }}" {% if department==d %}selected{% endif %}>{{ d }}</option>{% endfor %}</select>
<select name="status" class="rounded-lg border border-slate-300 px-3 py-2 text-sm"><option value="">All Status</option>{% for s in case_statuses %}<option value="{{ s }}" {% if status==s %}selected{% endif %}>{{ s|replace('_',' ')|title }}</option>{% endfor %}</select>
<select name="financial_year" class="rounded-lg border border-slate-300 px-3 py-2 text-sm">
<option value="all" {% if financial_year == 'all' %}selected{% endif %}>All FY</option>
{% for fy in financial_year_options %}<option value="{{ fy.year_code }}" {% if financial_year == fy.year_code %}selected{% endif %}>FY {{ fy.year_code }}{% if fy.is_current %} (Current){% endif %}</option>{% endfor %}
</select>
<input name="assessment_year" value="{{ assessment_year }}" placeholder="AY optional" class="rounded-lg border border-slate-300 px-3 py-2 text-sm">
{% if include_archived %}<input type="hidden" name="include_archived" value="true">{% endif %}
<button class="rounded-lg bg-slate-900 px-4 py-2 text-sm font-semibold text-white">Filter</button>
</form>
<div class="overflow-hidden rounded-xl bg-white shadow-sm ring-1 ring-slate-200">
<table class="min-w-full divide-y divide-slate-200 text-sm">
<thead class="bg-slate-50 text-left text-xs font-semibold uppercase tracking-wide text-slate-500"><tr><th class="px-4 py-3">Case</th><th class="px-4 py-3">Client</th><th class="px-4 py-3">Department</th><th class="px-4 py-3">FY / AY</th><th class="px-4 py-3">Due Date</th><th class="px-4 py-3">Status</th><th class="px-4 py-3 text-right">Action</th></tr></thead>
<tbody class="divide-y divide-slate-100">
{% for row in rows %}
<tr class="hover:bg-slate-50"><td class="px-4 py-3"><div class="font-semibold text-slate-900">{{ row.case_code }}</div><div class="text-slate-500">{{ row.title }}</div><div class="text-xs text-slate-400">{{ row.reference_no or row.din_ack_no or '' }}</div></td><td class="px-4 py-3">{{ row.client.client_name if row.client else '-' }}</td><td class="px-4 py-3">{{ row.department }}<div class="text-xs text-slate-400">{{ row.case_type }}</div></td><td class="px-4 py-3"><div>{{ row.financial_year or '-' }}</div><div class="text-xs text-slate-400">{{ row.assessment_year or '-' }}</div></td><td class="px-4 py-3">{{ row.due_date or '-' }}</td><td class="px-4 py-3"><span class="rounded-full bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700">{{ row.status|replace('_',' ')|title }}</span></td><td class="px-4 py-3 text-right"><a href="/notice-cases/{{ row.id }}" class="font-semibold text-brand-700 hover:underline">Open</a></td></tr>
{% else %}
<tr><td colspan="7" class="px-4 py-8 text-center text-slate-500">No notice/case records found for the selected year/filter.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}