Add previous FY mirror selection and force fresh TDS review
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
{% extends "ui/templates/base/layout.html" %}
|
||||
{% block content %}
|
||||
{% set mirror = mirror_status.mirror if mirror_status and mirror_status.mirror else {} %}
|
||||
{% set mirror_effective_ready = mirror.ready_for_financial_year or preview %}
|
||||
<div class="space-y-6">
|
||||
<div class="flex flex-wrap items-start justify-between gap-4">
|
||||
<div>
|
||||
@@ -18,7 +19,7 @@
|
||||
|
||||
<section class="grid gap-4 md:grid-cols-3">
|
||||
<div class="rounded-2xl bg-white p-5 shadow-soft"><div class="text-xs font-semibold uppercase tracking-wide text-slate-500">ERP Local Agent</div><div class="mt-2 text-lg font-semibold {{ 'text-emerald-700' if agent_online else 'text-red-700' }}">{{ 'Connected' if agent_online else 'Offline' }}</div></div>
|
||||
<div class="rounded-2xl bg-white p-5 shadow-soft"><div class="text-xs font-semibold uppercase tracking-wide text-slate-500">SQLite Mirror</div><div class="mt-2 text-lg font-semibold {{ 'text-emerald-700' if mirror.ready_for_financial_year else 'text-amber-700' }}">{{ 'Ready' if mirror.ready_for_financial_year else 'Mirror required' }}</div>{% if mirror.ready_for_financial_year and mirror.company %}<div class="mt-1 text-xs text-slate-500">{{ mirror.company.company_name }} · {{ fy_start }} to {{ fy_end }}</div>{% elif mirror.financial_year_reason %}<div class="mt-1 text-xs text-amber-700">{{ mirror.financial_year_reason }}</div>{% endif %}</div>
|
||||
<div class="rounded-2xl bg-white p-5 shadow-soft"><div class="text-xs font-semibold uppercase tracking-wide text-slate-500">SQLite Mirror</div><div class="mt-2 text-lg font-semibold {{ 'text-emerald-700' if mirror_effective_ready else 'text-amber-700' }}">{{ 'Ready' if mirror_effective_ready else 'Mirror required' }}</div>{% if mirror_effective_ready and mirror.company %}<div class="mt-1 text-xs text-slate-500">{{ mirror.company.company_name }} · {{ fy_start }} to {{ fy_end }}</div>{% elif mirror.financial_year_reason %}<div class="mt-1 text-xs text-amber-700">{{ mirror.financial_year_reason }}</div>{% endif %}</div>
|
||||
<div class="rounded-2xl bg-white p-5 shadow-soft"><div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Write-back</div><div class="mt-2 text-lg font-semibold text-slate-700">Controlled</div><div class="mt-1 text-xs text-slate-500">Tally is contacted only after approval/posting.</div></div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -307,9 +307,16 @@
|
||||
<span class="rounded-full bg-emerald-50 px-3 py-1 text-xs font-semibold text-emerald-700">Read-only export</span>
|
||||
</div>
|
||||
<div class="mt-4 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900"><strong>Before export:</strong> open the mapped company in TallyPrime and set Tally's active period (Alt+F2) to cover the full period you want exported. The ODBC mirror reads Tally's active period; the ERP does not change Tally's period automatically.</div>
|
||||
<form method="post" action="/tools/tally/full-export" class="mt-5 grid gap-4 lg:grid-cols-4 lg:items-end">
|
||||
<form method="post" action="/tools/tally/full-export" class="mt-5 grid gap-4 lg:grid-cols-5 lg:items-end" id="mirrorExportForm">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />
|
||||
<input type="hidden" name="client_id" value="{{ selected_client.id }}" />
|
||||
<label class="text-sm font-medium text-slate-700">Target Financial Year
|
||||
<select id="mirrorFinancialYear" name="financial_year" required class="mt-1 w-full rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm">
|
||||
{% for fy in mirror_fy_options %}
|
||||
<option value="{{ fy }}" {% if fy == selected_financial_year %}selected{% endif %}>FY {{ fy }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label class="text-sm font-medium text-slate-700">Mapped Tally Company
|
||||
<select name="tally_guid" required class="mt-1 w-full rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm">
|
||||
<option value="">Select mapped company</option>
|
||||
@@ -320,10 +327,14 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label class="text-sm font-medium text-slate-700">From Date<input type="date" name="date_from" required value="{{ transaction_date_from }}" class="mt-1 w-full rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm" /></label>
|
||||
<label class="text-sm font-medium text-slate-700">To Date<input type="date" name="date_to" required value="{{ transaction_date_to }}" class="mt-1 w-full rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm" /></label>
|
||||
<label class="text-sm font-medium text-slate-700">From Date<input id="mirrorDateFrom" type="date" name="date_from" required value="{{ transaction_date_from }}" class="mt-1 w-full rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm" /></label>
|
||||
<label class="text-sm font-medium text-slate-700">To Date<input id="mirrorDateTo" type="date" name="date_to" required value="{{ transaction_date_to }}" class="mt-1 w-full rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm" /></label>
|
||||
<button id="fullExportButton" type="submit" class="rounded-xl bg-emerald-700 px-4 py-2 text-sm font-semibold text-white hover:bg-emerald-800">Mirror Tally to SQLite</button>
|
||||
</form>
|
||||
<div class="mt-3 flex flex-wrap items-center gap-3 text-sm">
|
||||
<button type="button" id="mirrorPreviousFY" class="rounded-lg border border-slate-300 bg-white px-3 py-1.5 font-semibold text-slate-700">Use Previous FY</button>
|
||||
<span class="text-slate-500">Select an FY here to create or refresh that year's separate local mirror in the client's FY storage hierarchy.</span>
|
||||
</div>
|
||||
<div id="fullExportProgress" class="mt-5 hidden rounded-xl border border-slate-200 bg-slate-50 p-4">
|
||||
<div class="flex items-center justify-between gap-3"><div><div id="fullExportStage" class="font-semibold text-slate-900">Waiting…</div><div id="fullExportMessage" class="mt-1 text-xs text-slate-500"></div></div><div id="fullExportPct" class="text-lg font-bold text-slate-900">0%</div></div>
|
||||
<div class="mt-3 h-3 overflow-hidden rounded-full bg-slate-200"><div id="fullExportBar" class="h-full bg-emerald-600 transition-all duration-300" style="width:0%"></div></div>
|
||||
@@ -576,4 +587,28 @@
|
||||
pollFullExport();
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const fy=document.getElementById("mirrorFinancialYear");
|
||||
const from=document.getElementById("mirrorDateFrom");
|
||||
const to=document.getElementById("mirrorDateTo");
|
||||
const previous=document.getElementById("mirrorPreviousFY");
|
||||
function applyFY(value){
|
||||
const m=/^(\d{4})-(\d{2})$/.exec(value||"");
|
||||
if(!m||!from||!to)return;
|
||||
const y=parseInt(m[1],10);
|
||||
from.value=String(y).padStart(4,"0")+"-04-01";
|
||||
to.value=String(y+1).padStart(4,"0")+"-03-31";
|
||||
}
|
||||
if(fy)fy.addEventListener("change",function(){applyFY(fy.value);});
|
||||
if(previous&&fy)previous.addEventListener("click",function(){
|
||||
if(fy.selectedIndex+1<fy.options.length){
|
||||
fy.selectedIndex+=1;
|
||||
applyFY(fy.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
{% extends "ui/templates/base/layout.html" %}
|
||||
{% block content %}
|
||||
<div class="space-y-6">
|
||||
<div class="flex flex-wrap items-start justify-between gap-3"><div><p class="text-xs font-semibold uppercase tracking-[0.16em] text-brand-600">TDS & Withholding Tax</p><h1 class="mt-1 text-2xl font-semibold text-slate-900">TDS Compliance Review</h1><p class="mt-1 text-sm text-slate-500">Review expenses, purchases, journals and creditor postings from the client SQLite Accounting Mirror. Rules and thresholds come from the editable TDS Rule Master.</p></div><div class="flex gap-2"><a href="/tools/accounting/tds/rules" class="rounded-xl border px-3 py-2 text-sm font-semibold">Rule Master</a><a href="/tools/tally" class="rounded-xl border px-3 py-2 text-sm font-semibold">Tally</a></div></div>{% if error %}<div class="rounded-xl bg-red-50 p-3 text-sm text-red-800">{{ error }}</div>{% endif %}<form method="get" class="rounded-2xl bg-white p-5 shadow-soft"><div class="grid gap-3 lg:grid-cols-3"><label class="text-sm">Client<select name="client_id" required class="mt-1 w-full rounded-xl border px-3 py-2"><option value="">Select client</option>{% for c in clients %}<option value="{{ c.id }}" {% if selected_client and c.id==selected_client.id %}selected{% endif %}>{{ c.client_name }}</option>{% endfor %}</select></label><label class="text-sm">From<input type="date" name="date_from" value="{{ date_from }}" required class="mt-1 w-full rounded-xl border px-3 py-2"></label><label class="text-sm">To<input type="date" name="date_to" value="{{ date_to }}" required class="mt-1 w-full rounded-xl border px-3 py-2"></label></div><input type="hidden" name="run" value="1"><button class="mt-4 rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Run TDS Review</button></form>{% if review %}<div class="flex justify-end gap-2"><a href="/tools/tally/analysis/{{ review.analysis_run_id }}/download?client_id={{ selected_client.id }}&financial_year={{ date_from[:4] }}-{{ date_to[2:4] }}&format=xlsx" class="rounded-xl border border-emerald-300 bg-emerald-50 px-3 py-2 text-sm font-semibold text-emerald-800">Download Excel</a><a href="/tools/tally/analysis/{{ review.analysis_run_id }}/download?client_id={{ selected_client.id }}&financial_year={{ date_from[:4] }}-{{ date_to[2:4] }}&format=pdf" class="rounded-xl border px-3 py-2 text-sm font-semibold">Download PDF</a></div><div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
|
||||
<div class="flex flex-wrap items-start justify-between gap-3"><div><p class="text-xs font-semibold uppercase tracking-[0.16em] text-brand-600">TDS & Withholding Tax</p><h1 class="mt-1 text-2xl font-semibold text-slate-900">TDS Compliance Review</h1><p class="mt-1 text-sm text-slate-500">Review expenses, purchases, journals and creditor postings from the client SQLite Accounting Mirror. Rules and thresholds come from the editable TDS Rule Master.</p></div><div class="flex gap-2"><a href="/tools/accounting/tds/rules" class="rounded-xl border px-3 py-2 text-sm font-semibold">Rule Master</a><a href="/tools/tally" class="rounded-xl border px-3 py-2 text-sm font-semibold">Tally</a></div></div>{% if error %}<div class="rounded-xl bg-red-50 p-3 text-sm text-red-800">{{ error }}</div>{% endif %}<form method="get" class="rounded-2xl bg-white p-5 shadow-soft"><div class="grid gap-3 lg:grid-cols-3"><label class="text-sm">Client<select name="client_id" required class="mt-1 w-full rounded-xl border px-3 py-2"><option value="">Select client</option>{% for c in clients %}<option value="{{ c.id }}" {% if selected_client and c.id==selected_client.id %}selected{% endif %}>{{ c.client_name }}</option>{% endfor %}</select></label><label class="text-sm">From<input type="date" name="date_from" value="{{ date_from }}" required class="mt-1 w-full rounded-xl border px-3 py-2"></label><label class="text-sm">To<input type="date" name="date_to" value="{{ date_to }}" required class="mt-1 w-full rounded-xl border px-3 py-2"></label></div><input type="hidden" name="run" value="1"><input type="hidden" name="run_token" value="{{ run_token }}"><button class="mt-4 rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Run TDS Review</button></form>{% if review %}
|
||||
<div class="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm">
|
||||
<div><span class="font-semibold">Analysis Run #{{ review.analysis_run_id }}</span><span class="ml-2 text-slate-500">{{ review.company_name }} · {{ review.date_from }} to {{ review.date_to }}</span></div>
|
||||
<div class="text-xs text-slate-500">Fresh run {{ run_token[:8] }}</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-2"><a href="/tools/tally/analysis/{{ review.analysis_run_id }}/download?client_id={{ selected_client.id }}&financial_year={{ date_from[:4] }}-{{ date_to[2:4] }}&format=xlsx" class="rounded-xl border border-emerald-300 bg-emerald-50 px-3 py-2 text-sm font-semibold text-emerald-800">Download Excel</a><a href="/tools/tally/analysis/{{ review.analysis_run_id }}/download?client_id={{ selected_client.id }}&financial_year={{ date_from[:4] }}-{{ date_to[2:4] }}&format=pdf" class="rounded-xl border px-3 py-2 text-sm font-semibold">Download PDF</a></div><div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
|
||||
{% for k,v in review.summary.items() %}
|
||||
<div class="rounded-xl bg-white p-4 shadow-soft">
|
||||
<div class="text-xs uppercase text-slate-500">{{ k|replace('_',' ') }}</div>
|
||||
|
||||
Reference in New Issue
Block a user