Skip to content

REP-2256-feat(journal-entries): add --adjusting-entry filter to list - #44

Open
valeyakymenko wants to merge 1 commit into
mainfrom
valentyny/rep-2256-cli-adjusting-entries-adjusting-entry-list-filter-and-cli
Open

valeyakymenko wants to merge 1 commit into
mainfrom
valentyny/rep-2256-cli-adjusting-entries-adjusting-entry-list-filter-and-cli

Conversation

@valeyakymenko

Copy link
Copy Markdown

Summary

dualentry journal-entries list can now return only adjusting entries, or only regular ones, with --adjusting-entry true|false. The API already had this filter and the CLI had no way to ask for it. Leaving the flag off lists both, same as today.

Validation errors now keep the API's error_code. The API refuses an adjusting entry with a stable code like adjusting_entry_bank_account, but the CLI printed only the message, so a script could only match on wording.

Changes

  • journal-entries list --adjusting-entry true|false: sends is_adjusting_entry to the API and works with --all. The value is case-insensitive and anything else is a usage error. Other resources reject the flag, like any filter they don't offer.
  • Validation errors: a 422 with an error_code now prints Validation error [code]: ..., on every command. A 422 without a code prints as before.
  • Changelog: two entries under Unreleased.
  • Tests: 12 new ones in tests/test_filter_gating.py and tests/test_client.py.

journal-entries create and update need no change, they already send is_adjusting_entry from the JSON file.

Test plan

  • Unit tests pass (pytest on Python 3.13): 301 passed, 136 skipped. The skipped ones are tests/test_integration.py, which needs an API key.
  • Linter passes (ruff check and ruff format --check)
  • Changelog check passes (scripts/check_changelog.py origin/main)
  • Manually tested with dualentry <command> against a real API (see Artifacts)

Artifacts

Run against a local API server on a private test database with fake data. Nothing is mocked, every dualentry call below is a real HTTP request. jq trims -o json rows to the fields that matter here, and the [exit N] lines come from the script that ran the commands.

The files: adjusting.json sets "is_adjusting_entry": true, regular.json leaves it out, disabled-company.json uses a company with adjusting entries turned off, bank-line.json has a line on a bank account, recurring.json is a recurring template with the flag set.

The flag

$ dualentry journal-entries list --help | grep -A1 -- --adjusting-entry
│ --adjusting-entry          true|false  true: only adjusting entries; false: only regular ones. Omit for    │
│                                        both.                                                               │

Filtering

$ dualentry journal-entries create --file adjusting.json -o json | jq -c '{number, memo, is_adjusting_entry}'
{"number":1,"memo":"Year-end accrual","is_adjusting_entry":true}

$ dualentry journal-entries create --file regular.json -o json | jq -c '{number, memo, is_adjusting_entry}'
{"number":2,"memo":"Monthly reclass","is_adjusting_entry":false}

$ dualentry journal-entries list -o json | jq -c '{count, rows: [.items[] | {number, memo, is_adjusting_entry}]}'
{"count":2,"rows":[{"number":1,"memo":"Year-end accrual","is_adjusting_entry":true},{"number":2,"memo":"Monthly reclass","is_adjusting_entry":false}]}

$ dualentry journal-entries list --adjusting-entry true -o json | jq -c '{count, rows: [.items[] | {number, memo, is_adjusting_entry}]}'
{"count":1,"rows":[{"number":1,"memo":"Year-end accrual","is_adjusting_entry":true}]}

$ dualentry journal-entries list --adjusting-entry false -o json | jq -c '{count, rows: [.items[] | {number, memo, is_adjusting_entry}]}'
{"count":1,"rows":[{"number":2,"memo":"Monthly reclass","is_adjusting_entry":false}]}

$ dualentry journal-entries list --adjusting-entry TRUE --all -o json | jq -c '{count, rows: [.items[] | {number, memo, is_adjusting_entry}]}'
{"count":1,"rows":[{"number":1,"memo":"Year-end accrual","is_adjusting_entry":true}]}

$ dualentry journal-entries list -o json | jq -c '{count, every_row_has_the_field: (.items | all(has("is_adjusting_entry")))}'
{"count":2,"every_row_has_the_field":true}

What the server received for those list calls, with no flag, true, false, and --all:

"GET /public/v2/journal-entries/?limit=20&offset=0 HTTP/1.1" 200 785
"GET /public/v2/journal-entries/?is_adjusting_entry=true&limit=20&offset=0 HTTP/1.1" 200 702
"GET /public/v2/journal-entries/?is_adjusting_entry=false&limit=20&offset=0 HTTP/1.1" 200 698
"GET /public/v2/journal-entries/?is_adjusting_entry=true&limit=100&offset=0 HTTP/1.1" 200 702

Human output

$ dualentry journal-entries list --adjusting-entry true
                                      Journal Entries                                       
┏━━━━━━━┳━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┓
┃    ID ┃ # ┃    Date    ┃ Company         ┃ Memo             ┃ Currency ┃ Amount ┃ Status ┃
┡━━━━━━━╇━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━┩
│ JE-13 │ 1 │ 2026-12-31 │ Example Company │ Year-end accrual │   USD    │ $60.00 │ posted │
└───────┴───┴────────────┴─────────────────┴──────────────────┴──────────┴────────┴────────┘

Showing 1 of 1

$ dualentry journal-entries list --adjusting-entry false
                                      Journal Entries                                       
┏━━━━━━━┳━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┓
┃    ID ┃ # ┃    Date    ┃ Company         ┃ Memo             ┃ Currency ┃ Amount ┃ Status ┃
┡━━━━━━━╇━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━┩
│ JE-14 │ 2 │ 2026-12-31 │ Example Company │ Monthly reclass  │   USD    │ $60.00 │ posted │
└───────┴───┴────────────┴─────────────────┴──────────────────┴──────────┴────────┴────────┘

Showing 1 of 1

API refusals keep their code

$ dualentry journal-entries create --file disabled-company.json

  ✗ Error: Validation error [adjusting_entries_disabled]: {'is_adjusting_entry': ['Adjusting entries are not enabled for this company.']}

[exit 1]

$ dualentry journal-entries create --file bank-line.json

  ✗ Error: Validation error [adjusting_entry_bank_account]: {'items': ['Bank and credit card accounts cannot be used on an adjusting entry.']}

[exit 1]

$ dualentry recurring journal-entries create --file recurring.json

  ✗ Error: Validation error [recurring_adjusting_entry]: {'record_payload.is_adjusting_entry': ['Recurring journal entries cannot be adjusting entries.']}

[exit 1]

With a key whose role can edit journal entries but has no adjusting entry permission:

$ dualentry journal-entries create --file adjusting.json

  ✗ Error: Validation error [adjusting_entry_permission_required]: {'is_adjusting_entry': ['You do not have permission to post adjusting entries.']}

[exit 1]

Bad input

Neither call reaches the API.

$ dualentry journal-entries list --adjusting-entry yes
Usage: dualentry journal-entries list [OPTIONS]
Try 'dualentry journal-entries list --help' for help.
╭─ Error ────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Invalid value for '--adjusting-entry': expected true or false, got 'yes'                                   │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
[exit 2]

$ dualentry invoices list --adjusting-entry true
Usage: dualentry invoices list [OPTIONS]
Try 'dualentry invoices list --help' for help.
╭─ Error ────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ invoices does not support --adjusting-entry. Supported filters: --company, --customer, --end-date,         │
│ --search, --start-date, --status.                                                                          │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
[exit 2]

Before, on main (743e99d)

$ dualentry journal-entries list --adjusting-entry true
Usage: dualentry journal-entries list [OPTIONS]
Try 'dualentry journal-entries list --help' for help.
╭─ Error ────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ No such option: --adjusting-entry                                                                          │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
[exit 2]

$ dualentry journal-entries create --file disabled-company.json

  ✗ Error: Validation error: {'is_adjusting_entry': ['Adjusting entries are not enabled for this company.']}

[exit 1]

Not exercised

  • journal-entries update: this PR doesn't change it.
  • The --all resume hint with the flag: it needs a crawl past the page limit, so it has a unit test only.
  • tests/test_integration.py and the production API: this ran against the local server only.

`journal-entries list --adjusting-entry true|false` returns only adjusting
entries, or only regular ones, through the API's is_adjusting_entry filter.
Leaving the flag off lists both, as before. Other resources reject the flag.

Validation errors now name the API error_code when the API returns one, so
scripts can branch on the code instead of the message.
@valeyakymenko valeyakymenko self-assigned this Nov 5, 2026
@valeyakymenko
valeyakymenko requested a review from POD666 November 5, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants