Fix depreciation mirror selection and TDS capital account exclusion
This commit is contained in:
@@ -18,7 +18,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><div class="mt-1 text-xs text-slate-500">{{ mirror.company.company_name if mirror.ready_for_financial_year and mirror.company else '' }}</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">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>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}"><input type="hidden" name="client_id" value="{{ selected_client.id }}"><input type="hidden" name="fy_start" value="{{ fy_start }}"><input type="hidden" name="fy_end" value="{{ fy_end }}">
|
||||
<section class="rounded-2xl bg-white p-5 shadow-soft">
|
||||
<div class="grid gap-4 md:grid-cols-2">
|
||||
<div><label class="text-sm font-medium text-slate-700">Depreciation Expense Ledger</label><select name="depreciation_expense_ledger" class="mt-1 w-full rounded-xl border border-slate-300 px-3 py-2"><option value="">Depreciation</option>{% for name in preview.all_ledgers %}<option value="{{ name }}">{{ name }}</option>{% endfor %}</select></div>
|
||||
<div><label class="text-sm font-medium text-slate-700">Depreciation Debit Ledger</label><select id="depreciation-debit-ledger" name="depreciation_expense_ledger" class="mt-1 w-full rounded-xl border border-slate-300 px-3 py-2"><option value="">Depreciation</option>{% for name in preview.all_ledgers %}<option value="{{ name }}">{{ name }}</option>{% endfor %}</select><p class="mt-1 text-xs text-slate-500">Any existing ledger may be selected, including the asset ledger itself.</p></div>
|
||||
<div><label class="text-sm font-medium text-slate-700">Depreciation Reserve / Credit Ledger</label><select name="depreciation_reserve_ledger" class="mt-1 w-full rounded-xl border border-slate-300 px-3 py-2"><option value="">Depreciation Reserve</option>{% for name in preview.all_ledgers %}<option value="{{ name }}">{{ name }}</option>{% endfor %}</select></div>
|
||||
</div>
|
||||
<p class="mt-3 text-xs text-slate-500">These ledger selections are stored with the draft. Phase 6 can post the Journal only after the saved draft is explicitly approved.</p>
|
||||
@@ -60,7 +60,7 @@
|
||||
<button type="button" id="apply-bulk-rate" class="rounded-lg border border-brand-300 bg-white px-3 py-2 text-sm font-semibold text-brand-700 hover:bg-brand-50">Apply rate to selected</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto"><table class="min-w-full text-sm"><thead class="bg-slate-50 text-left text-xs uppercase tracking-wide text-slate-500"><tr><th class="px-4 py-3 w-10">Select</th><th class="px-4 py-3">Ledger</th><th class="px-4 py-3 text-right">Opening WDV</th><th class="px-4 py-3 text-right">Additions ≥180 days</th><th class="px-4 py-3 text-right">Additions <180 days</th><th class="px-4 py-3 text-right">Reductions</th><th class="px-4 py-3">Rate</th></tr></thead><tbody class="divide-y divide-slate-100">
|
||||
<div class="overflow-x-auto"><table class="min-w-full text-sm"><thead class="bg-slate-50 text-left text-xs uppercase tracking-wide text-slate-500"><tr><th class="px-4 py-3 w-10">Select</th><th class="px-4 py-3">Ledger</th><th class="px-4 py-3 text-right">Opening WDV</th><th class="px-4 py-3 text-right">Additions ≥180 days</th><th class="px-4 py-3 text-right">Additions <180 days</th><th class="px-4 py-3 text-right">Other Reductions</th><th class="px-4 py-3 text-right">Depreciation Already Recorded</th><th class="px-4 py-3">Rate</th><th class="px-4 py-3">Posting Ledger</th></tr></thead><tbody class="divide-y divide-slate-100">
|
||||
{% for row in preview.fixed_asset_ledgers %}
|
||||
<tr>
|
||||
<td class="px-4 py-3"><input type="checkbox" class="asset-select rounded border-slate-300" data-ledger-key="{{ row.ledger_key }}"></td>
|
||||
@@ -69,9 +69,11 @@
|
||||
<td class="px-4 py-3 text-right">{{ '%.2f'|format(row.additions_full_rate) }}</td>
|
||||
<td class="px-4 py-3 text-right">{{ '%.2f'|format(row.additions_half_rate) }}</td>
|
||||
<td class="px-4 py-3 text-right">{{ '%.2f'|format(row.reductions) }}</td>
|
||||
<td class="px-4 py-3 text-right">{% if row.depreciation_already_recorded %}<div class="font-semibold text-emerald-700">{{ '%.2f'|format(row.recorded_depreciation) }}</div><div class="text-[11px] text-slate-500">{{ row.recorded_depreciation_voucher_count }} voucher(s)</div>{% else %}<span class="text-slate-400">—</span>{% endif %}</td>
|
||||
<td class="px-4 py-3"><select id="rate-{{ loop.index0 }}" data-ledger-key="{{ row.ledger_key }}" name="rate__{{ row.ledger_key }}" class="asset-rate rounded-lg border border-slate-300 px-2 py-1.5"><option value="0" {% if row.rate_percent == 0 %}selected{% endif %}>0%</option>{% for rate in [5,10,15,20,25,30,40,45,60,80,100] %}<option value="{{ rate }}" {% if row.rate_percent == rate %}selected{% endif %}>{{ rate }}%</option>{% endfor %}</select></td>
|
||||
<td class="px-4 py-3"><button type="button" class="use-asset-as-debit text-xs font-semibold text-brand-700 underline underline-offset-2" data-ledger-name="{{ row.ledger_name }}">Use as debit ledger</button></td>
|
||||
</tr>
|
||||
{% else %}<tr><td colspan="7" class="px-4 py-8 text-center text-slate-500">No active Fixed Asset ledgers were found. Zero-opening ledgers without additions are intentionally omitted.</td></tr>{% endfor %}
|
||||
{% else %}<tr><td colspan="9" class="px-4 py-8 text-center text-slate-500">No active Fixed Asset ledgers were found. Zero-opening ledgers without additions are intentionally omitted.</td></tr>{% endfor %}
|
||||
</tbody></table></div>
|
||||
<div class="flex justify-end border-t border-slate-200 px-5 py-4"><button type="submit" {% if not preview.fixed_asset_ledgers %}disabled{% endif %} class="rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50">Calculate & Save Draft</button></div>
|
||||
</section>
|
||||
@@ -94,7 +96,7 @@
|
||||
</div>
|
||||
{% if depreciation_run.tally_posting_error %}<div class="mt-3 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800">{{ depreciation_run.tally_posting_error }}</div>{% endif %}
|
||||
|
||||
<div class="mt-4 overflow-x-auto"><table class="min-w-full text-sm"><thead class="bg-slate-50 text-left text-xs uppercase text-slate-500"><tr><th class="px-3 py-2">Ledger</th><th class="px-3 py-2 text-right">Rate</th><th class="px-3 py-2 text-right">Depreciation</th><th class="px-3 py-2 text-right">Closing WDV</th></tr></thead><tbody class="divide-y divide-slate-100">{% for row in depreciation_run.lines %}<tr><td class="px-3 py-2">{{ row.ledger_name }}</td><td class="px-3 py-2 text-right">{{ '%.2f'|format(row.rate_percent) }}%</td><td class="px-3 py-2 text-right">{{ '%.2f'|format(row.depreciation_amount) }}</td><td class="px-3 py-2 text-right">{{ '%.2f'|format(row.closing_wdv) }}</td></tr>{% endfor %}</tbody></table></div>
|
||||
<div class="mt-4 overflow-x-auto"><table class="min-w-full text-sm"><thead class="bg-slate-50 text-left text-xs uppercase text-slate-500"><tr><th class="px-3 py-2">Ledger</th><th class="px-3 py-2 text-right">Rate</th><th class="px-3 py-2 text-right">Calculated</th><th class="px-3 py-2 text-right">Already Recorded</th><th class="px-3 py-2 text-right">Unrecorded</th><th class="px-3 py-2 text-right">Closing WDV</th></tr></thead><tbody class="divide-y divide-slate-100">{% for row in depreciation_run.lines %}<tr><td class="px-3 py-2">{{ row.ledger_name }}</td><td class="px-3 py-2 text-right">{{ '%.2f'|format(row.rate_percent) }}%</td><td class="px-3 py-2 text-right">{{ '%.2f'|format(row.depreciation_amount) }}</td><td class="px-3 py-2 text-right">{{ '%.2f'|format(row.recorded_depreciation or 0) }}</td><td class="px-3 py-2 text-right font-semibold">{{ '%.2f'|format(row.remaining_unrecorded_depreciation if row.remaining_unrecorded_depreciation is defined else row.depreciation_amount) }}</td><td class="px-3 py-2 text-right">{{ '%.2f'|format(row.closing_wdv) }}</td></tr>{% endfor %}</tbody></table></div>
|
||||
{% if depreciation_run.status == 'draft' %}
|
||||
<form method="post" action="/tools/tally/depreciation/approve" class="mt-5 rounded-xl border border-amber-200 bg-amber-50 p-4">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}"><input type="hidden" name="client_id" value="{{ selected_client.id }}"><input type="hidden" name="run_id" value="{{ depreciation_run.id }}"><input type="hidden" name="fy_start" value="{{ depreciation_run.fy_start }}">
|
||||
@@ -155,4 +157,19 @@
|
||||
<div class="mt-3 overflow-x-auto"><table class="min-w-full text-sm"><thead><tr class="text-left text-xs uppercase text-slate-500"><th class="p-2">Run</th><th class="p-2">FY</th><th class="p-2">Period</th><th class="p-2">Completed</th><th class="p-2"></th></tr></thead><tbody>{% for row in analysis_history %}<tr class="border-t"><td class="p-2">#{{ row.id }}</td><td class="p-2">{{ row.financial_year }}</td><td class="p-2">{{ row.period_from }} → {{ row.period_to }}</td><td class="p-2">{{ row.completed_at_utc }}</td><td class="p-2 text-right"><a class="font-semibold text-brand-700" href="/tools/tally/analysis/{{ row.id }}/download?client_id={{ selected_client.id }}&financial_year={{ row.financial_year }}&format=xlsx">Excel</a> · <a class="font-semibold text-brand-700" href="/tools/tally/analysis/{{ row.id }}/download?client_id={{ selected_client.id }}&financial_year={{ row.financial_year }}&format=pdf">PDF</a></td></tr>{% endfor %}</tbody></table></div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded",function(){
|
||||
const debit=document.getElementById("depreciation-debit-ledger");
|
||||
document.querySelectorAll(".use-asset-as-debit").forEach(function(button){
|
||||
button.addEventListener("click",function(){
|
||||
if(!debit)return;
|
||||
debit.value=button.dataset.ledgerName||"";
|
||||
debit.scrollIntoView({behavior:"smooth",block:"center"});
|
||||
debit.focus();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -810,9 +810,10 @@ def depreciation_it_tool(
|
||||
node = get_active_storage_node_for_branch(db, scope.tenant_id, scope.branch_id)
|
||||
online = _node_online(node)
|
||||
today = date.today()
|
||||
start_year = today.year if today.month >= 4 else today.year - 1
|
||||
start_text = fy_start or date(start_year, 4, 1).isoformat()
|
||||
end_text = fy_end or date(start_year + 1, 3, 31).isoformat()
|
||||
active_start_year = today.year if today.month >= 4 else today.year - 1
|
||||
explicit_period = bool(str(fy_start or "").strip() and str(fy_end or "").strip())
|
||||
start_text = fy_start or date(active_start_year, 4, 1).isoformat()
|
||||
end_text = fy_end or date(active_start_year + 1, 3, 31).isoformat()
|
||||
preview = None
|
||||
depreciation_run = None
|
||||
mirror_status = None
|
||||
@@ -820,17 +821,30 @@ def depreciation_it_tool(
|
||||
analysis_history = []
|
||||
|
||||
if selected_client and node and online:
|
||||
storage_payload = _accounting_storage_payload(
|
||||
selected_client, _financial_year_for_date(date.fromisoformat(start_text))
|
||||
)
|
||||
selected_fy=_financial_year_for_date(date.fromisoformat(start_text))
|
||||
storage_payload=_accounting_storage_payload(selected_client,selected_fy)
|
||||
try:
|
||||
status_response = request_agent_command(
|
||||
node.node_code, "accounting_mirror_status", storage_payload, timeout_seconds=20
|
||||
status_response=request_agent_command(
|
||||
node.node_code,"accounting_mirror_status",storage_payload,timeout_seconds=20
|
||||
)
|
||||
if status_response.get("ok"):
|
||||
mirror_status = status_response.get("result") or {}
|
||||
mirror_status=status_response.get("result") or {}
|
||||
else:
|
||||
command_error = str(status_response.get("error") or "Accounting Mirror status failed.")
|
||||
command_error=str(status_response.get("error") or "Accounting Mirror status failed.")
|
||||
|
||||
if not explicit_period and not ((mirror_status or {}).get("mirror") or {}).get("ready_for_financial_year"):
|
||||
prior_start_year=active_start_year-1
|
||||
prior_start=date(prior_start_year,4,1)
|
||||
prior_end=date(prior_start_year+1,3,31)
|
||||
prior_fy=_financial_year_for_date(prior_start)
|
||||
prior_payload=_accounting_storage_payload(selected_client,prior_fy)
|
||||
prior_response=request_agent_command(
|
||||
node.node_code,"accounting_mirror_status",prior_payload,timeout_seconds=20
|
||||
)
|
||||
prior_status=(prior_response.get("result") or {}) if prior_response.get("ok") else {}
|
||||
if ((prior_status.get("mirror") or {}).get("ready_for_financial_year")):
|
||||
start_text=prior_start.isoformat(); end_text=prior_end.isoformat()
|
||||
storage_payload=prior_payload; mirror_status=prior_status
|
||||
|
||||
if mirror_status and (mirror_status.get("mirror") or {}).get("ready_for_financial_year"):
|
||||
preview_response = request_agent_command(
|
||||
|
||||
@@ -4,7 +4,7 @@ import io
|
||||
from pathlib import Path
|
||||
import zipfile
|
||||
|
||||
ERP_LOCAL_AGENT_VERSION = "1.25.5"
|
||||
ERP_LOCAL_AGENT_VERSION = "1.25.6"
|
||||
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)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
__version__ = "1.25.5"
|
||||
__version__ = "1.25.6"
|
||||
AGENT_NAME = "ERP Local Agent"
|
||||
|
||||
@@ -968,6 +968,61 @@ class LocalAccountingStore:
|
||||
"provisional": fy_end > today,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _looks_like_depreciation_text(value: str) -> bool:
|
||||
text = re.sub(r"[^a-z0-9]+", " ", str(value or "").casefold()).strip()
|
||||
if not text:
|
||||
return False
|
||||
return any(token in text for token in (
|
||||
"depreciation","depn","depreciation expense","depreciation reserve",
|
||||
"accumulated depreciation","provision for depreciation",
|
||||
))
|
||||
|
||||
def _recorded_depreciation_for_asset(self, db: sqlite3.Connection, *, tally_guid: str,
|
||||
asset_ledger_name: str, start_date: str, end_date: str) -> dict:
|
||||
rows = db.execute(
|
||||
"""SELECT v.id AS voucher_id,
|
||||
COALESCE(NULLIF(v.effective_date,''),v.voucher_date) AS movement_date,
|
||||
v.voucher_type_name,v.voucher_number,v.reference,v.narration,
|
||||
e.amount,e.is_deemed_positive
|
||||
FROM tally_voucher_ledger_entries e
|
||||
JOIN tally_vouchers v ON v.id=e.voucher_id
|
||||
WHERE v.tally_guid=?
|
||||
AND lower(trim(COALESCE(e.ledger_name,'')))=lower(trim(?))
|
||||
AND COALESCE(NULLIF(v.effective_date,''),v.voucher_date)>=?
|
||||
AND COALESCE(NULLIF(v.effective_date,''),v.voucher_date)<=?
|
||||
AND lower(COALESCE(v.is_cancelled,'')) NOT IN ('yes','true','1')
|
||||
AND lower(COALESCE(v.is_optional,'')) NOT IN ('yes','true','1')
|
||||
ORDER BY movement_date,v.id""",
|
||||
(tally_guid,asset_ledger_name,start_date,end_date),
|
||||
).fetchall()
|
||||
total=0.0; vouchers=[]; seen=set()
|
||||
for row in rows:
|
||||
if self._is_debit_entry(row):
|
||||
continue
|
||||
counter_rows=db.execute(
|
||||
"""SELECT ledger_name FROM tally_voucher_ledger_entries
|
||||
WHERE voucher_id=? AND lower(trim(COALESCE(ledger_name,'')))<>lower(trim(?))""",
|
||||
(int(row["voucher_id"]),asset_ledger_name),
|
||||
).fetchall()
|
||||
counters=[str(x["ledger_name"] or "").strip() for x in counter_rows]
|
||||
text=" ".join([str(row["voucher_type_name"] or ""),str(row["reference"] or ""),
|
||||
str(row["narration"] or ""),*counters])
|
||||
if not self._looks_like_depreciation_text(text):
|
||||
continue
|
||||
total += abs(float(row["amount"] or 0))
|
||||
vid=int(row["voucher_id"])
|
||||
if vid not in seen:
|
||||
seen.add(vid)
|
||||
vouchers.append({
|
||||
"voucher_id":vid,"date":str(row["movement_date"] or ""),
|
||||
"voucher_type":str(row["voucher_type_name"] or ""),
|
||||
"voucher_number":str(row["voucher_number"] or ""),
|
||||
"reference":str(row["reference"] or ""),
|
||||
"counter_ledgers":counters,
|
||||
})
|
||||
return {"amount":round(total,2),"voucher_count":len(vouchers),"vouchers":vouchers,"already_recorded":bool(total>0)}
|
||||
|
||||
def depreciation_preview(self, client_id: int, *, tally_guid: str, fy_start: str, fy_end: str) -> dict:
|
||||
if not self.exists(client_id):
|
||||
raise ValueError("Accounting storage is not initialized for this client.")
|
||||
@@ -1003,13 +1058,20 @@ class LocalAccountingStore:
|
||||
AND lower(COALESCE(v.is_optional,'')) NOT IN ('yes','true','1')""",
|
||||
(tally_guid,name,start.isoformat(),movement_end.isoformat()),
|
||||
).fetchall()
|
||||
full=half=reductions=0.0
|
||||
recorded_dep=self._recorded_depreciation_for_asset(
|
||||
db,tally_guid=tally_guid,asset_ledger_name=name,
|
||||
start_date=start.isoformat(),end_date=movement_end.isoformat()
|
||||
)
|
||||
recorded_dep_amount=float(recorded_dep.get("amount") or 0)
|
||||
full=half=0.0; raw_credit_reductions=0.0
|
||||
for e in entries:
|
||||
amt=abs(float(e["amount"] or 0))
|
||||
if self._is_debit_entry(e):
|
||||
if self._half_rate_addition(str(e["movement_date"] or ""), end): half += amt
|
||||
else: full += amt
|
||||
else: reductions += amt
|
||||
else:
|
||||
raw_credit_reductions += amt
|
||||
reductions=max(0.0,raw_credit_reductions-recorded_dep_amount)
|
||||
opening_wdv = abs(float(row["opening_balance"] or 0))
|
||||
tally_closing = abs(float(row["closing_balance"] or 0))
|
||||
additions_total = round(full + half, 2)
|
||||
@@ -1024,6 +1086,10 @@ class LocalAccountingStore:
|
||||
"ledger_key":key,"ledger_guid":str(row["master_guid"] or ""),"ledger_name":name,"parent_group":str(row["parent"] or ""),
|
||||
"opening_wdv":opening_wdv,"tally_closing_balance":tally_closing,
|
||||
"additions_full_rate":round(full,2),"additions_half_rate":round(half,2),"reductions":round(reductions,2),
|
||||
"recorded_depreciation":round(recorded_dep_amount,2),
|
||||
"depreciation_already_recorded":bool(recorded_dep.get("already_recorded")),
|
||||
"recorded_depreciation_voucher_count":int(recorded_dep.get("voucher_count") or 0),
|
||||
"recorded_depreciation_vouchers":list(recorded_dep.get("vouchers") or []),
|
||||
"rate_percent":rules.get(key,0.0),
|
||||
"movement_entries":len(entries),
|
||||
})
|
||||
@@ -1050,7 +1116,12 @@ class LocalAccountingStore:
|
||||
full_base=max(0.0, opening+full-reductions)
|
||||
dep=min(closing_before, (full_base*rate/100.0)+(half*rate/200.0))
|
||||
dep=round(dep,2); closing=round(max(0.0,closing_before-dep),2); total+=dep
|
||||
line={**row,"rate_percent":rate,"depreciation_amount":dep,"closing_wdv":closing,"closing_before_depreciation":round(closing_before,2)}
|
||||
recorded_dep=float(row.get("recorded_depreciation") or 0)
|
||||
line={**row,"rate_percent":rate,"depreciation_amount":dep,
|
||||
"recorded_depreciation":round(recorded_dep,2),
|
||||
"depreciation_already_recorded":bool(recorded_dep>0),
|
||||
"remaining_unrecorded_depreciation":round(max(0.0,dep-recorded_dep),2),
|
||||
"closing_wdv":closing,"closing_before_depreciation":round(closing_before,2)}
|
||||
lines.append(line)
|
||||
mapping=preview["mapping"]
|
||||
with self.connect(client_id) as db:
|
||||
@@ -1067,7 +1138,19 @@ class LocalAccountingStore:
|
||||
db.execute("""INSERT INTO it_depreciation_run_lines(run_id,line_no,ledger_key,ledger_guid,ledger_name,parent_group,opening_wdv,additions_full_rate,additions_half_rate,reductions,rate_percent,depreciation_amount,closing_wdv,payload_json)
|
||||
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
|
||||
(run_id,i,row["ledger_key"],row["ledger_guid"],row["ledger_name"],row["parent_group"],row["opening_wdv"],row["additions_full_rate"],row["additions_half_rate"],row["reductions"],row["rate_percent"],row["depreciation_amount"],row["closing_wdv"],json.dumps(row,ensure_ascii=False,separators=(",",":"))))
|
||||
return {"run_id":run_id,"status":"draft","company_name":str(mapping.get("company_name") or ""),"fy_start":str(fy_start),"fy_end":str(fy_end),"total_depreciation":round(total,2),"depreciation_expense_ledger":str(depreciation_expense_ledger or ""),"depreciation_reserve_ledger":str(depreciation_reserve_ledger or ""),"lines":lines,"proposed_entry":{"debit_ledger":str(depreciation_expense_ledger or "Depreciation"),"credit_ledger":str(depreciation_reserve_ledger or "Depreciation Reserve"),"amount":round(total,2)},"no_tally_writeback":True}
|
||||
total_recorded=round(sum(float(x.get("recorded_depreciation") or 0) for x in lines),2)
|
||||
total_remaining=round(sum(float(x.get("remaining_unrecorded_depreciation") or 0) for x in lines),2)
|
||||
return {"run_id":run_id,"status":"draft","company_name":str(mapping.get("company_name") or ""),
|
||||
"fy_start":str(fy_start),"fy_end":str(fy_end),"total_depreciation":round(total,2),
|
||||
"total_recorded_depreciation":total_recorded,
|
||||
"total_remaining_unrecorded_depreciation":total_remaining,
|
||||
"depreciation_expense_ledger":str(depreciation_expense_ledger or ""),
|
||||
"depreciation_reserve_ledger":str(depreciation_reserve_ledger or ""),
|
||||
"lines":lines,
|
||||
"proposed_entry":{"debit_ledger":str(depreciation_expense_ledger or "Depreciation"),
|
||||
"credit_ledger":str(depreciation_reserve_ledger or "Depreciation Reserve"),
|
||||
"amount":round(total,2)},
|
||||
"no_tally_writeback":True}
|
||||
|
||||
def get_it_depreciation_run(self, client_id: int, run_id: int) -> dict:
|
||||
with self.connect(client_id) as db:
|
||||
|
||||
@@ -3164,22 +3164,27 @@ class AgentCommandProcessor:
|
||||
if not value:
|
||||
return False
|
||||
exact = {
|
||||
"capital account",
|
||||
"capital accounts",
|
||||
"partners capital",
|
||||
"partner capital",
|
||||
"partners capital accounts",
|
||||
"partner capital accounts",
|
||||
"proprietors capital",
|
||||
"proprietor capital",
|
||||
"owners capital",
|
||||
"owner capital",
|
||||
"share capital",
|
||||
"reserves surplus",
|
||||
"reserves and surplus",
|
||||
"capital account","capital accounts","partners capital","partner capital",
|
||||
"partners capital accounts","partner capital accounts","proprietors capital",
|
||||
"proprietor capital","owners capital","owner capital","share capital",
|
||||
"reserves surplus","reserves and surplus","partners current account",
|
||||
"partner current account","partners current accounts","partner current accounts",
|
||||
"proprietors current account","proprietor current account",
|
||||
"owners current account","owner current account",
|
||||
}
|
||||
if value in exact:
|
||||
return True
|
||||
owner_prefix = (
|
||||
value.startswith("partner ") or value.startswith("partners ")
|
||||
or value.startswith("proprietor ") or value.startswith("proprietors ")
|
||||
or value.startswith("owner ") or value.startswith("owners ")
|
||||
)
|
||||
current_account_like = (
|
||||
" current account" in value or " current accounts" in value
|
||||
or " current a c" in value or value.endswith(" current ac")
|
||||
)
|
||||
if owner_prefix and current_account_like:
|
||||
return True
|
||||
return (
|
||||
value.startswith("capital account ")
|
||||
or value.endswith(" capital account")
|
||||
|
||||
Reference in New Issue
Block a user