Review calculations with Google Sheets

This page covers the spreadsheet review of a modelo calculation: exporting it to Google Sheets, checking how each total is reached with live formulas, and pulling your reviewed edits back as typed filing inputs. Pull returns those edits without persisting them. This workflow is for reviewing calculated values after your profile and transactions are ready. It is not a bank statement import or bulk edit tool.

Google Sheets is the review surface. The codebase also contains an offline .xlsx serializer, but the current operator command surface does not expose it. Use Google Sheets when you want to review and adjust.

The local configuration commands on this page (status, folder binding, logout) and the ledger readiness checks run live at build time. The commands that reach Google Drive and Sheets run against your own authorized account rather than the documentation sandbox, so they are shown as display-only frames.

Before you start

You need:

Cadrumo creates its cadrumo-vault/ folder inside that Drive folder. It does not use an older aeat-vault/ folder; export a new workbook before pulling edits into Cadrumo.

Configure Google access

Register the Desktop OAuth client for the active profile and run the consent flow. Both reach Google, so they are display-only here:

1Register the Desktop OAuth client for the active profile.
aeat config google register --client-json ./client_secret.json
aeat config google register --client-json ./client_secret.json
2Run the Google consent flow.
aeat config google login
aeat config google login

Check the Google status and set the Drive folder where Cadrumo will create spreadsheets. These are local configuration commands, so they run here. On an unconfigured profile the status reads not-connected, and the folder you set reads back verbatim:

1Check the Google connection status for the active profile.
aeat --format json config google status
aeat --format json config google status
{
  "active_profile": "docs-sequence-sandbox",
  "command": "config.google.status",
  "notices": [],
  "result": {
    "account_email": null,
    "client_id": null,
    "client_registered": false,
    "granted_scopes": [],
    "issued_at": null,
    "last_refresh_at": null,
    "operation": "config.google.status",
    "profile": "<profile-id>",
    "reauth_required": null,
    "session_present": false
  },
  "schema_version": "2",
  "status": "success"
}
2Set the Drive folder where Cadrumo will create spreadsheets.
aeat config google folder set docs-folder-123
aeat config google folder set docs-folder-123
operation	config.google.folder.set
profile	<profile-id>
root_folder_id	docs-folder-123
3Confirm the folder binding.
aeat --format json config google folder view
aeat --format json config google folder view
{
  "active_profile": "docs-sequence-sandbox",
  "command": "config.google.folder.view",
  "notices": [],
  "result": {
    "configured": true,
    "operation": "config.google.folder.view",
    "profile": "<profile-id>",
    "root_folder_id": "docs-folder-123"
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the Drive folder binding reads back the value you set.

Probe the connection once the OAuth client is registered. The probe reaches Google, so it is display-only here:

1Probe the Google connection.
aeat config google probe
aeat config google probe

The Google integration is profile-scoped. If you switch profiles, check Google status and folder binding again.

Export a calculation workbook

Export the registry calculation surface for one modelo, year, and period. The export creates a Google Sheets workbook inside the configured cadrumo-vault/ area in Drive:

1Export the calculation surface for one modelo, year, and period.
aeat app modelo spreadsheet push --modelo 303 --year 2026 --period 1T
aeat app modelo spreadsheet push --modelo 303 --year 2026 --period 1T

It is a calculation review surface, not a bank statement export. Use aeat app ledger export when you need a CSV, JSONL, or XLSX snapshot of ledger rows.

Use --prefill-relations only when you want the spreadsheet to include values carried from related filings, such as annual summaries or prior-quarter carryovers.

Pull your edits back

After reviewing or editing the workbook, pull typed edits back from the Sheet. Add --assemble-observations when you want the command output to include edited row-level data assembled as structured observations. The command does not persist those observations:

1Pull typed edits back from the reviewed spreadsheet.
aeat app modelo spreadsheet pull --modelo 303 --year 2026 --period 1T --spreadsheet-id \
  <spreadsheet-id>
aeat app modelo spreadsheet pull --modelo 303 --year 2026 --period 1T --spreadsheet-id `
  <spreadsheet-id>

The pull command checks that the spreadsheet belongs to the current profile and matches the expected filing period. If it refuses, re-export and retry from the new spreadsheet.

Compute casilla values from the Sheet

Run compute when you want Cadrumo to calculate casilla values from the edits in the Sheet. It pulls the operator-edited cells, runs the calculation engine over them, and displays the result. It persists nothing:

1Compute casilla values from the operator-edited cells.
aeat app modelo spreadsheet calculate --modelo 303 --year 2026 --period 1T \
  --spreadsheet-id <spreadsheet-id>
aeat app modelo spreadsheet calculate --modelo 303 --year 2026 --period 1T `
  --spreadsheet-id <spreadsheet-id>

The compute command checks that the spreadsheet matches the expected filing period. If it refuses, re-export and retry from the new spreadsheet.

Check the spreadsheet calculation

Run the calc-sheets verification command for the same modelo, year, and period. If you have a scenario JSON with operator inputs and expected Agencia Estatal de Administración Tributaria (AEAT) outputs, pass it explicitly with --scenario:

1Verify the spreadsheet calculation for the modelo, year, and period.
aeat app modelo spreadsheet verify --modelo 303 --year 2026 --period 1T
aeat app modelo spreadsheet verify --modelo 303 --year 2026 --period 1T
2Verify against an explicit scenario JSON of inputs and expected outputs.
aeat app modelo spreadsheet verify --modelo 303 --year 2026 --period 1T --scenario \
  ./scenario.json
aeat app modelo spreadsheet verify --modelo 303 --year 2026 --period 1T --scenario `
  ./scenario.json

Verification compares the calculation surfaces implemented by the app. It does not submit a filing to AEAT.

Back up your encrypted records to Drive

Keep an off-machine copy of your encrypted records by mirroring them to the configured Drive folder. Preview with --dry-run first; it reports what would upload per storage area without changing anything. Narrow a large push with --namespace or --limit:

1Preview the encrypted backup to Drive without uploading.
aeat config profile archive push --dry-run
aeat config profile archive push --dry-run
2Mirror the encrypted records to the Drive folder.
aeat config profile archive push
aeat config profile archive push

Only ciphertext is uploaded. Your records leave the machine exactly as they sit encrypted on disk, and the master key never leaves your computer, so the Drive copy is unreadable without it. The mirror is one-way: Cadrumo writes the copy and never reads Drive back as a source of truth for your records.

Sign out of Google

Clear the Google session for the active profile. Logout is a local command, so it runs here. It removes the saved session token and its metadata. The registered OAuth client is kept on purpose, so a later aeat config google login can sign in again without re-importing the Cloud Console JSON:

1Clear the Google session for the active profile.
aeat --format json config google logout
aeat --format json config google logout
{
  "active_profile": "docs-sequence-sandbox",
  "command": "config.google.logout",
  "notices": [],
  "result": {
    "client_preserved": true,
    "metadata_removed": false,
    "operation": "config.google.logout",
    "profile": "<profile-id>",
    "token_removed": false
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the Google session clears for the active profile.

Where this fits

Use this after transaction review and classification. Confirm the period is ready before you rely on the calculation workbook:

1Run the period preflight.
aeat app ledger preflight --year 2026 --period 1T
aeat app ledger preflight --year 2026 --period 1T
bucket	<profile-id>
period	2026 1T
checked	2
issues	2
ready	false
issue	71a5db2bb891df295bee72544c40497d24d5c8cfc7edab745ce7339dcf8d6518	missing_business_classification	business classification 'NOT_YET_PROCESSED' is not ready for modelo calculation
issue	e3eeac5e306efe4e82a72896e92e7c236245ec85348834b2c10b120c67fe087d	missing_business_classification	business classification 'NOT_YET_PROCESSED' is not ready for modelo calculation
2Read the overall ledger state for the period.
aeat --format json app ledger status --year 2026 --period 1T
aeat --format json app ledger status --year 2026 --period 1T
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.status",
  "notices": [],
  "result": {
    "active_count": 2,
    "archived_count": 0,
    "bucket_id": "<bucket-id>",
    "business_expense_total": "0",
    "business_income_total": "0",
    "business_net_total": "0",
    "checked_transaction_count": 2,
    "pending_review_count": 2,
    "period": {
      "code": "1T",
      "filing_year": 2026
    },
    "readiness_issue_count": 2,
    "readiness_issues": [
      {
        "business_classification": "NOT_YET_PROCESSED",
        "category_id": null,
        "detail": "business classification 'NOT_YET_PROCESSED' is not ready for modelo calculation",
        "iva_amount": null,
        "iva_rate": null,
        "reason": "missing_business_classification",
        "taxable_base": null,
        "transaction_id": "71a5db2bb891df295bee72544c40497d24d5c8cfc7edab745ce7339dcf8d6518",
        "transaction_present": true
      },
      {
        "business_classification": "NOT_YET_PROCESSED",
        "category_id": null,
        "detail": "business classification 'NOT_YET_PROCESSED' is not ready for modelo calculation",
        "iva_amount": null,
        "iva_rate": null,
        "reason": "missing_business_classification",
        "taxable_base": null,
        "transaction_id": "e3eeac5e306efe4e82a72896e92e7c236245ec85348834b2c10b120c67fe087d",
        "transaction_present": true
      }
    ],
    "ready": false,
    "reviewed_count": 0,
    "skipped_count": 0,
    "split_count": 0,
    "stale_filings": [],
    "stashed_count": 0,
    "total_count": 2,
    "unconverted_currency_count": 0
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the period's readiness before relying on the workbook.

If the ledger still has missing categories, IVA fields, currency, or proportionality references, finish those in Classify transactions before relying on the calculation workbook.

For casilla-level manual inputs, bindings, offsets, and revisions, use Review and supply calculation inputs.

Next steps