Skip to content

T2860 - FIX recurring invoice generation for annual contracts - #276

Merged
ecino merged 2 commits into
14.0from
T2860-Annual-contracts-create-more-invoices
Jun 25, 2026
Merged

T2860 - FIX recurring invoice generation for annual contracts#276
ecino merged 2 commits into
14.0from
T2860-Annual-contracts-create-more-invoices

Conversation

@danpa32

@danpa32 danpa32 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Two bugs in _generate_invoices / _should_skip_invoice_generation:

  1. Loop range used advance_billing_months + 1 as upper bound, causing an off-by-one that generated too many invoices. Fixed to advance_billing_months + month_interval - 1 so the number of generated periods is consistent across all billing cycles:

    • monthly/advance=1 → 1 invoice, monthly/advance=12 → 12 invoices
    • annual/advance=12 → 2 invoices (current + next year)
  2. Skip check did not exclude cancelled invoices, so a super-deleted (cancelled) invoice for a future period would permanently block regeneration of that period. Fixed by adding ("state", "not in", ["cancel"]) to the search domain.

Two bugs in _generate_invoices / _should_skip_invoice_generation:

1. Loop range used `advance_billing_months + 1` as upper bound, causing
   an off-by-one that generated too many invoices. Fixed to
   `advance_billing_months + month_interval - 1` so the number of
   generated periods is consistent across all billing cycles:
   - monthly/advance=1 → 1 invoice, monthly/advance=12 → 12 invoices
   - annual/advance=12 → 2 invoices (current + next year)

2. Skip check did not exclude cancelled invoices, so a super-deleted
   (cancelled) invoice for a future period would permanently block
   regeneration of that period. Fixed by adding
   `("state", "not in", ["cancel"])` to the search domain.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@danpa32
danpa32 requested review from NoeBerdoz and ecino June 24, 2026 09:30

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request reformats code, adjusts contributor list spacing, and updates the invoice generation logic to ignore cancelled invoices. It also modifies the offset range calculation in _generate_invoices. However, the new range calculation is missing starting_offset in its upper bound, which can result in an empty range and prevent invoices from being generated when there are waiting contracts.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread recurring_contract/models/contract_group.py
@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The changes are narrowly scoped to recurring invoice period generation and duplicate-period checks.

No correctness or security issues were identified in the reviewed changes, and the implementation matches the described contract for advance billing and cancelled invoices.

T-Rex T-Rex Logs

What T-Rex did

  • Ran the invoice-range proof-of-work experiment and captured before and after logs to verify base range computation, the head-range calculation, and the observed extra monthly invoices for starting_offset=0 across scenarios.
  • Ran the regeneration decision proof-of-work checks and captured before and after domain logs to verify how a state exclusion changes the _should_skip_invoice_generation flag and whether regeneration would proceed.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "FIX loop range truncation when starting_..." | Re-trigger Greptile

Comment thread recurring_contract/models/contract_group.py
Comment on lines +358 to +367
open_invoices = self.env["account.move"].search(
[
("invoice_date", "=", invoicing_date),
("partner_id", "=", self.partner_id.id),
("move_type", "=", "out_invoice"),
("state", "not in", ["cancel"]),
("line_ids.contract_id", "in", contracts.ids),
("line_ids.product_id", "in", contracts.mapped("product_ids").ids),
]
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Gift invoices still block

This base search now ignores cancelled moves, but the coupled sponsorship override has a separate gift-invoice lookup that still counts cancelled invoice lines: sponsorship_compassion/models/contract_group.py in compassion-modules. When a future gift invoice is cancelled, that override can still return has_all_gifts = True, so gift periods remain blocked even though regular contract periods can regenerate.

Artifacts

Repro: focused harness importing the real base and sponsorship override methods

  • Contains supporting evidence from the run (text/x-python; charset=utf-8).

Repro: harness output showing cancelled gift line counted and skip result True

  • Keeps the command output available without making the summary code-heavy.

View artifacts

T-Rex Ran code and verified through T-Rex

When _calculate_start_date_and_offset returns starting_offset=1 (waiting
contracts or block-day logic), the previous upper bound
`advance_billing_months + month_interval - 1` did not include the offset,
causing range(1, 1, 1) to be empty for monthly contracts with
advance_billing_months=1 — no invoices generated at all.

Fix: upper bound is now
`starting_offset + advance_billing_months + month_interval - 1`
so the number of generated periods is identical regardless of the offset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@ecino ecino left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you!

@ecino
ecino merged commit 0d382f6 into 14.0 Jun 25, 2026
2 checks passed
@ecino
ecino deleted the T2860-Annual-contracts-create-more-invoices branch June 25, 2026 08:20
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