Skip to content

[18.0][IMP] hr_expense_sequence: propagate number to journal entries - #377

Open
JordiBForgeFlow wants to merge 3 commits into
OCA:18.0from
ForgeFlow:18.0-imp-hr_expense_sequence-move-ref
Open

[18.0][IMP] hr_expense_sequence: propagate number to journal entries#377
JordiBForgeFlow wants to merge 3 commits into
OCA:18.0from
ForgeFlow:18.0-imp-hr_expense_sequence-move-ref

Conversation

@JordiBForgeFlow

@JordiBForgeFlow JordiBForgeFlow commented Jul 30, 2026

Copy link
Copy Markdown
Member

Problem

hr_expense_sequence numbers expense reports (EX0001), but that number stops
at hr.expense.sheet. The accounting documents the report generates are
referenced by free text instead:

  • employee-paid → the vendor bill gets ref = sheet.name (the report summary);
  • company-paid → each payment entry gets ref = expense.name.

So there is no way to tie a payable line back to the expense report it came
from, and reconciling the accounts payable by report number is impossible.

What this does

The report number is prefixed onto the reference of every journal entry the
report generates:

Before After
Vendor bill (employee-paid) Client visit EX0001 - Client visit
Payment entries (company-paid) Flight EX0001 - Flight

account.move.line.ref is a stored, trigram-indexed related field on
account.move.ref, so the number lands on every journal item — searchable,
groupable and sortable from the reconciliation widget, the Journal Items list
and the Aged Payable report.

A prefix rather than a replacement, for two reasons:

  • company-paid reports generate one entry per expense line; replacing the
    reference would give every entry of a report the same value and you could no
    longer tell the flight from the hotel;
  • sorting journal items by Reference now groups a report's items together while
    each line still says what it was.

Searching by number is unaffected — the search view matches ref with ilike
on a trigram index.

Implementation

Two hooks, both taken after super() so the value being prefixed is whatever
core (or another module) decided:

  • hr.expense.sheet._prepare_bills_vals() — employee-paid vendor bill;
  • hr.expense._prepare_payments_vals() — company-paid payment entries.

_prepare_move_vals() is not enough on its own: both callers set ref
explicitly after spreading its result, so it would be overwritten.

Two non-obvious points, both commented in the code:

  • ref and payment_reference are set to the same value. Core builds t
    payable line's label from both and concatenates them when they differ
    (account_move_line.py:_compute_name), so prefixing only ref would have
    produced EX0001 - Client visit - EX0001 on the AP line.
  • The payment memo is set too. account.payment._inverse_memo writes
    onto account.move.ref, and payments are created after the moves in
    _do_create_moves, so setting the move reference alone is silently undone

Reports without a number (/) are left completely untouched. No new depende
hr_expense already depends on account. Version bumped to 18.0.1.1.0.

Tests

tests/test_hr_expense_sequence_account_move.py, 6 tests: employee-paid bill

payments, a manually forced number, no number, and an empty reference (no
dangling separator).

Run green both standalone and with hr_expense_invoice installed — that mod
bypasses move creation on approval for employee-paid reports, so the tests
assert after action_sheet_move_post().

Not covered

  • Entries created before installing this module keep their original
    reference; assign_old_sequences numbers the existing reports but does not
    rewrite their posted entries.
  • Reversals lose the reference: core's _do_reverse_moves forces
    ref: False. They auto-reconcile against the original, so this does not b
    anything, but the number is not on them.

Find attached a video that shows the behaviour:

hr_expense_sequence_move_ref.mp4

Set the expense report number as the reference of the accounting
documents it generates, so the accounts payable can be reconciled by
expense report number:

- Reports paid by the employee: the number is set on the vendor bill's
  `ref` and `payment_reference`.
- Reports paid by the company: the number is set on each payment's
  `memo` and on the `ref` of its journal entry. The memo is needed as
  its inverse writes back on the move reference.

`account.move.line.ref` is a stored related field on `account.move.ref`,
so the number ends up on every journal item, searchable from the
reconciliation widget and the aged payable report.
@OCA-git-bot OCA-git-bot added series:18.0 mod:hr_expense_sequence Module hr_expense_sequence labels Jul 30, 2026
`hr_expense_invoice` bypasses the creation of the journal entries on
approval for employee-paid reports, so they only exist after
`action_sheet_move_post`. Asserting right after the approval made the
tests fail whenever that module is installed alongside, as on the CI.
… reference

Setting the report number as the whole reference discarded the one the
accounting documents already carried. That is a real loss for reports
paid by the company, which generate one journal entry per expense line:
every entry of a report ended up with the same reference, so the flight
could no longer be told from the hotel in the accounts payable.

The number is now a prefix, `EX0001 - Client visit`. Searching by number
still works, since `ref` is a trigram-indexed field matched with ilike,
and sorting journal items by reference now groups them by report.

`ref` and `payment_reference` are set to the same value on purpose: core
builds the payable line label out of both and concatenates them when
they differ, which would have produced `EX0001 - Client visit - EX0001`.
@JordiBForgeFlow

Copy link
Copy Markdown
Member Author

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

Labels

mod:hr_expense_sequence Module hr_expense_sequence series:18.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants