Selecting a period on a declaration fired one HTTP request per report reference
— 217 on a VAT return — and each one re-executed an entire Script Report just to
read a single column. Those 217 requests only ever ran 4 distinct reports: 120 of
VAT's 127 report fields read different columns out of the same report with the
same filters.
run_reports_batch groups the references by (report, filters) and executes each
report once, slicing every requested column out of the one result. The extraction
rule (take the report's total row, else sum every row) is ported verbatim — it
decides the figures that end up on a filed tax return.
The runtime lives here rather than in formula_editor because that app is a
design-time tool that gets removed from production machines; generated scripts no
longer reference it at all.
Errors are now surfaced instead of swallowed. A failed report used to yield 0 for
every field that asked for it, so a user without report permission got a
plausible-looking, fully-zeroed declaration and no hint anything was wrong.
Failing reports now contribute no values, the affected formulas are skipped rather
than zeroed, and the user is told which report failed and why.
Also fixes a Frappe core bug that threw on every declaration: Frappe writes the
active tab's fieldname into the URL hash, the URL API percent-encodes our
Azerbaijani fieldnames, and form.js then feeds that hash to jQuery as a CSS
selector.
Land tax and Property tax pointed js_parent_subtab at a parent tab that does not
exist in those doctypes, so their Əlavə tabs never nested.
VAT, one period change: 217 HTTP requests -> 1, 236 refresh_field -> 11, 4.5s -> 1.5s.
Verified identical output across all 426 formulas and all 337 report fields.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>