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,53 @@
{% extends "ui/templates/base/layout.html" %}
{% block content %}
<div class="space-y-6">
<div class="flex items-start justify-between">
<div>
<h1 class="text-2xl font-semibold text-slate-900">Import Fee Structure</h1>
<p class="mt-1 text-sm text-slate-500">Upload Excel with Fee_Structure and Fee_Services sheets.</p>
</div>
<div class="flex flex-wrap gap-2">
<a href="/billing/fee-structures/template" class="rounded-xl border border-emerald-300 bg-emerald-50 px-4 py-2 text-sm font-medium text-emerald-800 shadow-sm hover:bg-emerald-100">Download Excel Template</a>
<a href="/billing/fee-structures/list" class="rounded-xl border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 shadow-sm hover:bg-slate-50">Fee Structure List</a>
</div>
</div>
{% if result %}
<div class="rounded-2xl border {{ 'border-emerald-200 bg-emerald-50 text-emerald-900' if result.success else 'border-red-200 bg-red-50 text-red-900' }} p-4">
{% if result.success %}
<div class="font-semibold">Import completed</div>
<div class="mt-1 text-sm">Created: {{ result.created }} | Updated: {{ result.updated }}</div>
{% else %}
<div class="font-semibold">Import failed</div>
<ul class="mt-2 list-disc pl-5 text-sm">
{% for error in result.errors %}<li>{{ error }}</li>{% endfor %}
</ul>
{% endif %}
</div>
{% endif %}
<form method="post" enctype="multipart/form-data" class="space-y-5 rounded-2xl border border-slate-200 bg-white p-6 shadow-soft">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />
<label class="block">
<span class="text-sm font-medium text-slate-700">Excel File</span>
<input type="file" name="import_file" accept=".xlsx,.xlsm" required class="mt-1 block w-full rounded-xl border border-slate-300 px-3 py-2 text-sm" />
</label>
<div class="rounded-xl bg-slate-50 p-4 text-sm text-slate-600">
<div class="font-semibold text-slate-800">How to import using template</div>
<ol class="mt-2 list-decimal space-y-1 pl-5">
<li>Click <strong>Download Excel Template</strong>.</li>
<li>Fill <strong>Fee_Structure</strong> for client-wise package/header details.</li>
<li>Fill <strong>Fee_Services</strong> for services included in each package.</li>
<li>Upload the completed file here. Imported fee structures can then be used in <strong>Generate Bills</strong>.</li>
</ol>
<div class="mt-4 font-semibold text-slate-800">Required sheets</div>
<div class="mt-1">Fee_Structure: client, billing group, mode, frequency, fee and tax details.</div>
<div>Fee_Services: services included in each billing group.</div>
</div>
<div class="flex justify-end gap-3">
<a href="/billing/fee-structures/list" class="rounded-xl border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700">Back</a>
<button class="rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white hover:bg-brand-700">Import Fee Structure</button>
</div>
</form>
</div>
{% endblock %}
@@ -0,0 +1,63 @@
{% extends "ui/templates/base/layout.html" %}
{% block content %}
<div class="space-y-6">
<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div>
<h1 class="text-2xl font-semibold text-slate-900">Fee Structure</h1>
<p class="mt-1 text-sm text-slate-500">Client-wise billing packages with multiple services grouped for future invoice generation.</p>
</div>
<div class="flex flex-wrap gap-2">
<a href="/billing/generate" class="rounded-xl border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 shadow-sm hover:bg-slate-50">Generate Bills</a>
<a href="/billing" class="rounded-xl border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 shadow-sm hover:bg-slate-50">Invoices</a>
{% if can_import %}
<a href="/billing/fee-structures/template" class="rounded-xl border border-emerald-300 bg-emerald-50 px-4 py-2 text-sm font-medium text-emerald-800 shadow-sm hover:bg-emerald-100">Download Template</a>
<a href="/billing/fee-structures/import" class="rounded-xl bg-emerald-600 px-4 py-2 text-sm font-semibold text-white shadow-soft hover:bg-emerald-700">Import Using Template</a>
{% endif %}
</div>
</div>
<form method="get" class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="flex gap-3">
<input name="q" value="{{ q or '' }}" placeholder="Search group, client code or client name" class="w-full rounded-xl border border-slate-300 px-3 py-2 text-sm focus:border-brand-500 focus:outline-none" />
<button class="rounded-xl bg-slate-900 px-4 py-2 text-sm font-semibold text-white">Search</button>
</div>
</form>
<div class="overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-soft">
<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">Group Code</th>
<th class="px-4 py-3">Client</th>
<th class="px-4 py-3">Package</th>
<th class="px-4 py-3">Mode</th>
<th class="px-4 py-3">Frequency</th>
<th class="px-4 py-3 text-right">Fee</th>
<th class="px-4 py-3">Services</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100">
{% for row in rows %}
<tr class="align-top hover:bg-slate-50">
<td class="px-4 py-3 font-medium text-slate-900">{{ row.group_code }}</td>
<td class="px-4 py-3 text-slate-700">{{ row.client.client_name if row.client else row.client_id }}</td>
<td class="px-4 py-3 text-slate-700">{{ row.group_name }}</td>
<td class="px-4 py-3"><span class="rounded-full bg-slate-100 px-2 py-1 text-xs">{{ row.billing_mode }}</span></td>
<td class="px-4 py-3">{{ row.frequency }}</td>
<td class="px-4 py-3 text-right font-semibold">₹ {{ '%.2f'|format(row.fee_amount or 0) }}</td>
<td class="px-4 py-3 text-xs text-slate-600">
{% for item in row.services %}
<div>{{ item.service.service_code if item.service else item.service_id }} - {{ item.line_description or (item.service.service_name if item.service else '') }}</div>
{% else %}
<span class="text-slate-400">No services mapped</span>
{% endfor %}
</td>
</tr>
{% else %}
<tr><td colspan="7" class="px-4 py-8 text-center text-slate-500">No fee structures found.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}