Skip to content

55 aggregations filter administrationId on @self.administrationId, a placeholder that does not exist — all return empty #1255

Description

@rubenvdlinde

55 aggregations filter on a placeholder that does not exist, and return empty over live data

This is #1216 again, ×55.
That issue was closed by fixing one aggregation; the same defect was left in
every other declaration that scopes by administration.

Each of these declares:

"filter": { "administrationId": "@self.administrationId" }

@self.administrationId is not a placeholder OpenRegister implements.
PlaceholderResolver::resolve() only acts on values beginning with $ (it
implements $currentUser and the date expressions); a value starting with @
fails str_starts_with($value, '$') and is returned unchanged. So the filter
that actually runs is the literal string comparison
administrationId = '@self.administrationId', which matches nothing.

Measured

On a live instance, against GLLine (which has rows):

query rows
objects/shillinq/GLLine?_limit=1 3
objects/shillinq/GLLine?administrationId=@self.administrationId 0
aggregations/shillinq/GLLine/byCostCenter "groups": []

Nothing errors. A filter on a value nothing holds returns an empty set with
HTTP 200
, which renders as the page's own empty state and reads as "no data
yet" — exactly how #1216 hid.

The design answer

Administrations are a shillinq-specific layer over OpenRegister's organisation
tenancy
. Being shillinq-specific, an administration is not @self metadata —
@self is OpenRegister's own envelope. administrationId is a normal
property
, and it should be filtered like any other property, by the caller.

That is what the fix for #1216 did, and it is the pattern to apply:

  1. remove administrationId from the declaration's filter;
  2. the caller passes it as a narrowing filter —
    ?filter[administrationId]=<active> — which
    openregister#2852
    accepts and can never relax.

⚠️ Order matters, and getting it backwards is a tenant leak. Today these
return nothing, which is the safe direction. Removing the declared filter
without a caller that supplies one turns "returns nothing" into "returns every
administration". Update the caller first, or land both in one commit.

The join half comes free

15 of these also declare a join, and in every one of the 15 the gap is
administrationId and the joined schema declares it too. Those do not need
anything added to join.filter — a tenant cannot be hardcoded there, it varies
per caller — because
openregister#2869
forwards the caller's narrowing filter to the joined aggregate, restricted to
keys the joined schema declares. So step 2 above scopes both halves.

(A further 7 join declarations have parent filter keys absent from
join.filter, but the joined schema does not declare those keys, so there is
nothing to mirror and no gap.)

Callers

Some have one, some do not. An aggregation with no caller must not simply
have its filter deleted — it would be left open for whoever adds the first
caller.

aggregation caller
TrialBalanceLine.trialBalanceByAccountPeriod lib/Service/TrialBalanceService.php
TrialBalance.trialBalanceByAccount lib/Service/TrialBalanceService.php
QuarterlyTaxStatement.quarterlyTaxStatement lib/Service/TaxReportService.php
BudgetLine.budgetVsActuals lib/Service/BudgetGridReader.php
VatReturn.rubrieken lib/Reporting/Generator/VatReturnReportGenerator.php
GLLine.byCostCenter / byCostCenterHierarchy / byProject / byAnalyticalDimension src/views/bookkeeping/dimensions/SegmentPnLDashboard.vue
BbvAccountMapping.byProgrammaCode / byAutorisatieniveau, GLLine.byCostObject none found

Full inventory

Total: 55 aggregations across 22 fragment files.

30-bookkeeping-ib-aangifte-zzp.json — 2
  • IBWinstOpgave.costOfRevenue
  • IBWinstOpgave.revenueExcludingVat
add-shillinq-bbv-compliance.json — 2
  • BbvAccountMapping.byAutorisatieniveau (declares a join)
  • BbvAccountMapping.byProgrammaCode (declares a join)
add-shillinq-bookkeeping-operations.json — 5
  • BbvAccountMapping.byTaakveld
  • BcfClaim.compensableVatByAccount
  • IcpStatement.icpTransactions
  • SchatkistPosition.position
  • VatReturn.rubrieken
bookkeeping-btw-oss-eu.json — 2
  • OssReturn.linesByCountryRate
  • OssThresholdCounter.b2cEuTurnoverByYear
bookkeeping-cost-centers-dimensions.json — 5
  • GLLine.byAnalyticalDimension (declares a join)
  • GLLine.byCostCenter (declares a join)
  • GLLine.byCostCenterHierarchy (declares a join)
  • GLLine.byCostObject (declares a join)
  • GLLine.byProject (declares a join)
bookkeeping-detachering-payroll-administratie.json — 1
  • Payroll.annualEmployeeDeductions
bookkeeping-icp-opgaaf.json — 1
  • IcpSupply.icpLedgerByBuyerSupplyType
bookkeeping-ifrs-rj-dual-gaap.json — 1
  • ReconciliationBridge.bridgeByPeriodStandard
bookkeeping-ifrs15-revenue.json — 1
  • RevenueWaterfall.revenueWaterfallByContractPeriod
bookkeeping-innovatiebox-administratie.json — 1
  • IBProfitAttribution.innovatieboxAdministratie (declares a join)
bookkeeping-intercompany-elimination.json — 2
  • CounterpartyBalance.counterpartyBalanceByPair
  • IntercompanyMatch.matchByRelationPeriod
bookkeeping-kor-kleine-ondernemersregeling.json — 1
  • KORAnnualTurnover.korTurnoverByYear
bookkeeping-programmabegroting.json — 2
  • Programma.programmaRollup
  • Programmabegroting.sluitendByBegroting
bookkeeping-rechtmatigheidsverantwoording.json — 2
  • Rechtmatigheidsbevinding.foutenPerBoekjaar
  • Rechtmatigheidstoets.clusteringPerLeverancier
bookkeeping-sbr-xbrl-reporting.json — 4
  • SBRDocumentType.glBalanceDelta
  • SBRDocumentType.mappingCoveragePercent
  • SBRDocumentType.unmappedAccountCount
  • SBRDocumentType.unmappedAccountList
bookkeeping-trial-balance.json — 1
  • TrialBalanceLine.trialBalanceByAccountPeriod (declares a join)
bookkeeping-vpb-corporate-tax.json — 1
  • QuarterlyTaxStatement.quarterlyTaxStatement (declares a join)
bookkeeping-waterschappen-bbv-variant-02-aggregation-compliance.json — 2
  • BBVProgramme.totalBudget
  • BBVProgramme.ytdSpend (declares a join)
bookkeeping-wet-fido-treasury.json — 1
  • KasgeldLimiet.kasgeldRolling3Month
budget-core-schema.json — 1
  • BudgetLine.budgetVsActuals (declares a join)
inventory-stock-movement-ledger.json — 3
  • StockMove.movesByType
  • StockMove.netQuantityForLocation
  • StockMove.reservedQuantityForLocation
shillinq_register.json — 14
  • BalanceSheet.balanceSheetTotals (declares a join)
  • IbAangifteExport.costs
  • IbAangifteExport.revenue
  • IcpStatement.lines
  • Iv3Export.buckets (declares a join)
  • KorRegime.ytdRevenue
  • SisaReport.findingCounts
  • SisaReport.onTimeSettlement
  • TrialBalance.trialBalanceByAccount (declares a join)
  • TrialBalance.trialBalanceTotals
  • VatReturn.rubrieken (declares a join)
  • ZzpDeduction.taxableProfit
  • ZzpDeduction.ytdQualifyingHours
  • kernGegevensConfig.kerngegevensRatios (declares a join)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

triageAwaiting triage

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions