Add Phase 11B client aware multi bank ownership and engagement archive

This commit is contained in:
A R R R Associates
2026-08-22 20:45:36 +05:30
parent 8748ee9539
commit 016299cf0c
9 changed files with 714 additions and 8 deletions
+7
View File
@@ -79,6 +79,13 @@ def import_completed_job(db, *, tenant_id, client_id, job_id, user_id):
raise ValueError("Completed Bank Analyzer workbook was not found.")
if job.tenant_id not in (None, tenant_id):
raise ValueError("Bank Analyzer job belongs to a different firm.")
if getattr(job, "client_id", None) and int(job.client_id) != int(client_id):
raise ValueError(
"This Bank Analyzer job is already bound to a different ERP client. "
"Import it using the client confirmed during statement ownership validation."
)
if getattr(job, "client_id", None) and getattr(job, "ownership_status", "") != "confirmed":
raise ValueError("Client-bound Bank Analyzer job has not passed ownership validation.")
frame = pd.read_excel(job.output_file, sheet_name="Transaction Classification")
tally_options = available_tally_guids(db, tenant_id, client_id)
@@ -12,7 +12,7 @@
<form method="post" action="/tools/accounting/bank-posting/import" class="grid gap-4 md:grid-cols-3">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<label class="text-sm font-medium">Client<select name="client_id" required class="mt-1 w-full rounded-xl border border-slate-300 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 font-medium">Completed Bank Analyzer job<select name="job_id" required class="mt-1 w-full rounded-xl border border-slate-300 px-3 py-2"><option value="">Select analysis</option>{% for j in jobs %}<option value="{{ j.id }}">{{ j.completed_at_utc or j.submitted_at_utc }} · {{ j.selected_bank|replace('_',' ')|title }} · {{ j.file_count }} file(s)</option>{% endfor %}</select></label>
<label class="text-sm font-medium">Completed Bank Analyzer job<select name="job_id" required class="mt-1 w-full rounded-xl border border-slate-300 px-3 py-2"><option value="">Select analysis</option>{% for j in jobs %}<option value="{{ j.id }}" data-client-id="{{ j.client_id or '' }}">{{ j.completed_at_utc or j.submitted_at_utc }} · {{ j.selected_bank|replace('_',' ')|title }} · {{ j.file_count }} file(s){% if j.client_id %} · Client #{{ j.client_id }}{% endif %}</option>{% endfor %}</select></label>
<div class="flex items-end"><button class="w-full rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Import to Accounting Engine</button></div>
</form>
</section>
@@ -73,4 +73,20 @@
</section>
{% endif %}
</div>
<script>
(function () {
const job = document.querySelector('select[name="job_id"]');
const client = document.querySelector('select[name="client_id"]');
if (!job || !client) return;
job.addEventListener("change", function () {
const option = job.options[job.selectedIndex];
const clientId = option ? option.dataset.clientId : "";
if (clientId) {
client.value = clientId;
}
});
})();
</script>
{% endblock %}