From cbe594e73bc7ff5d4cb781bd049476d7ae263d43 Mon Sep 17 00:00:00 2001 From: A R R R Associates Date: Sun, 6 Sep 2026 21:05:07 +0530 Subject: [PATCH] Fix mirror FY period detection and add TDS exception links --- .../templates/accounting/tds_compliance.html | 90 ++++++++++++++++++- app/modules/documents/agent_package.py | 2 +- .../erp_local_agent/__init__.py | 2 +- .../erp_local_agent/accounting_mirror.py | 8 +- 4 files changed, 97 insertions(+), 5 deletions(-) diff --git a/app/modules/accounting/templates/accounting/tds_compliance.html b/app/modules/accounting/templates/accounting/tds_compliance.html index f3a0acd..8f6dc0e 100644 --- a/app/modules/accounting/templates/accounting/tds_compliance.html +++ b/app/modules/accounting/templates/accounting/tds_compliance.html @@ -1,7 +1,19 @@ {% extends "ui/templates/base/layout.html" %} {% block content %}
-

TDS & Withholding Tax

TDS Compliance Review

Review expenses, purchases, journals and creditor postings from the client SQLite Accounting Mirror. Rules and thresholds come from the editable TDS Rule Master.

{% if error %}
{{ error }}
{% endif %}
{% if review %}
{% for k,v in review.summary.items() %}
{{ k|replace('_',' ') }}
{{ v }}
{% endfor %}
+

TDS & Withholding Tax

TDS Compliance Review

Review expenses, purchases, journals and creditor postings from the client SQLite Accounting Mirror. Rules and thresholds come from the editable TDS Rule Master.

{% if error %}
{{ error }}
{% endif %}
{% if review %}
+ {% for k,v in review.summary.items() %} +
+
{{ k|replace('_',' ') }}
+
{{ v }}
+ {% if k == 'tds_not_deducted' and v %} + + {% elif k == 'short_deduction' and v %} + + {% endif %} +
+ {% endfor %} +

TDS Category Summary

Rule/category-wise totals for quick review before transaction-level exceptions.

@@ -14,6 +26,7 @@ + @@ -27,9 +40,82 @@ + {% endfor %}
Liability Not Deducted ShortReview
{{ '%.2f'|format(row.liability) }} {{ row.tds_not_deducted }} {{ row.short_deduction }} +
+ {% if row.tds_not_deducted %} + + {% endif %} + {% if row.short_deduction %} + + {% endif %} +
+
-
{% for x in review.transactions %}{% endfor %}
DatePartyLedger / RuleBaseExpectedActualLiabilityStatus
{{ x.date }}{{ x.party }}{{ x.nature_ledger }}
{{ x.rule_name }} · {{ x.legacy_section }}
{{ '%.2f'|format(x.taxable_base) }}{{ '%.2f'|format(x.expected_tds) }}{{ '%.2f'|format(x.actual_tds) }}{{ '%.2f'|format(x.liability) }}{{ x.status }}
{% endif %}{% if history %}

TDS Analysis History

{% for row in history %}{% endfor %}
#{{ row.id }}{{ row.financial_year }}{{ row.period_from }} → {{ row.period_to }}Excel · PDF
{% endif %}
+
+
+
+
+

Transaction Review

+

Showing all candidate transactions.

+
+ +
+ {% for x in review.transactions %}{% endfor %}
DatePartyLedger / RuleBaseExpectedActualLiabilityStatus
{{ x.date }}{{ x.party }}{{ x.nature_ledger }}
{{ x.rule_name }} · {{ x.legacy_section }}
{{ '%.2f'|format(x.taxable_base) }}{{ '%.2f'|format(x.expected_tds) }}{{ '%.2f'|format(x.actual_tds) }}{{ '%.2f'|format(x.liability) }}{{ x.status }}
{% endif %}{% if history %}

TDS Analysis History

{% for row in history %}{% endfor %}
#{{ row.id }}{{ row.financial_year }}{{ row.period_from }} → {{ row.period_to }}Excel · PDF
{% endif %} + +{% if review %} + +{% endif %} + {% endblock %} diff --git a/app/modules/documents/agent_package.py b/app/modules/documents/agent_package.py index 6fbc137..6beb4cb 100644 --- a/app/modules/documents/agent_package.py +++ b/app/modules/documents/agent_package.py @@ -4,7 +4,7 @@ import io from pathlib import Path import zipfile -ERP_LOCAL_AGENT_VERSION = "1.25.3" +ERP_LOCAL_AGENT_VERSION = "1.25.4" ERP_LOCAL_AGENT_NAME = "ERP Local Agent" RUNTIME_ROOT = Path(__file__).resolve().parent / "local_agent_runtime" _DETERMINISTIC_ZIP_TIMESTAMP = (2026, 1, 1, 0, 0, 0) diff --git a/app/modules/documents/local_agent_runtime/erp_local_agent/__init__.py b/app/modules/documents/local_agent_runtime/erp_local_agent/__init__.py index 5eda983..b927b8e 100644 --- a/app/modules/documents/local_agent_runtime/erp_local_agent/__init__.py +++ b/app/modules/documents/local_agent_runtime/erp_local_agent/__init__.py @@ -1,2 +1,2 @@ -__version__ = "1.25.3" +__version__ = "1.25.4" AGENT_NAME = "ERP Local Agent" diff --git a/app/modules/documents/local_agent_runtime/erp_local_agent/accounting_mirror.py b/app/modules/documents/local_agent_runtime/erp_local_agent/accounting_mirror.py index f64f24e..5e1ba65 100644 --- a/app/modules/documents/local_agent_runtime/erp_local_agent/accounting_mirror.py +++ b/app/modules/documents/local_agent_runtime/erp_local_agent/accounting_mirror.py @@ -140,7 +140,13 @@ class AccountingMirrorEngine: except sqlite3.Error: unbalanced = 0 try: - period_row = db.execute("SELECT MIN(date) AS from_date, MAX(date) AS to_date FROM voucher").fetchone() + # The proven v3.0.1 mirror stores the voucher date in + # voucher.voucher_date. Earlier status code queried a non-existent + # "date" column, silently returned a blank period and caused valid + # FY mirrors to be shown as "Mirror required". + period_row = db.execute( + "SELECT MIN(voucher_date) AS from_date, MAX(voucher_date) AS to_date FROM voucher" + ).fetchone() voucher_period = dict(period_row) if period_row else {"from_date": "", "to_date": ""} except sqlite3.Error: voucher_period = {"from_date": "", "to_date": ""}