Skip to content

T3389-gift-invoices-counter - #2141

Merged
ecino merged 1 commit into
18.0from
T3389-gift-invoices-counter
Sep 2, 2026
Merged

T3389-gift-invoices-counter#2141
ecino merged 1 commit into
18.0from
T3389-gift-invoices-counter

Conversation

@loris-fab

@loris-fab loris-fab commented Sep 1, 2026

Copy link
Copy Markdown

⚠️ PR liée : CompassionCH/compassion-accounting#283 — même ticket T3389. À merger ensemble. Celle-ci dépend de la méthode _get_open_invoices() introduite là-bas ; seule, elle ne fonctionne pas.

Goal

Complément du correctif T3389 pour les contrats Child Gift (type == "G").

Ces contrats ne portent pas leurs factures : quand un cadeau est facturé, build_inv_line_data rattache la ligne de facture au parrainage lié, pas au contrat cadeau. Sans traitement particulier, leur bouton afficherait donc toujours 0.

Ce module compensait, mais à deux endroits différents et avec deux critères différents d'où un compteur et une liste qui ne pouvaient pas coïncider.

Technical aspect

Deux rustines supprimées, remplacées par une seule surcharge du point d'extension créé dans compassion-accounting.

  • Supprimé dans _compute_invoices : contract.nb_invoices += len(gift_invoices). Ce code incrémentait un entier sans que les factures correspondantes existent dans un recordset , le bouton annonçait donc un nombre que rien ne pouvait afficher. Structurellement incompatible avec l'objectif « compteur = liste ».
  • Supprimé : la surcharge de open_invoices(). Elle faisait res["domain"] = [...], ce qui remplaçait le domaine du parent : les factures propres au contrat cadeau disparaissaient de la liste. Et son filtre était invoice_category == "gift" seul, sans aucun filtre d'état ni de paiement — la liste contenait donc aussi les cadeaux payés, annulés et brouillons.
  • Ajouté : _get_open_invoices(), qui pour les contrats G ajoute (union, pas remplacement) les factures de cadeau du parrainage lié, filtrées par le critère commun _filter_open_invoices(). Compteur et liste consommant tous deux cette méthode, ils ne peuvent plus diverger.
  • @api.depends complété : le compteur d'un contrat cadeau dépend des lignes de facture d'un autre contrat (le parrainage). Ce chemin n'était déclaré nulle part, donc l'encaissement d'un cadeau ne rafraîchissait pas le compteur.

Ce qui change pour l'utilisateur

Sur un contrat Child Gift :

Avant : compteur Avant : liste Après : les deux
cadeaux du parrainage, ouverts
cadeaux du parrainage, payés / annulés ✅ / ❌
ses factures propres, postées impayées jamais visibles

Le seul changement visible côté métier : les cadeaux payés ne sont plus dans « Open invoices ». Ils restent accessibles par le bouton « Gifts » juste à côté, qui n'est pas modifié.

Misc

  • Un cadeau impayé n'apparaît pas dans « Gifts » : l'enregistrement sponsorship.gift n'est créé qu'au paiement de la facture (invoice_paid_trigger_gifts). Les deux boutons sont donc complémentaires — facture ouverte avant paiement, cadeau après. Exception : avec l'option no_birthday_invoice, le cadeau est créé sans facture et n'apparaît que dans « Gifts ».
  • Le bouton du groupe n'affiche pas les cadeaux d'un contrat cadeau si le parrainage est dans un autre moyen de paiement. Volontaire : le groupe répond à « qu'est-ce qui sera encaissé par ce moyen de paiement ? », et cette facture sera encaissée par celui du parrainage. L'afficher des deux côtés rendrait le recouvrement ambigu.
  • Les filtres contextuels open_invoices_sponsorship_only / open_invoices_exclude_sponsorship sont inchangés : ils portent sur open_invoice_ids, qui reste réservé au métier (génération de cadeaux, cascade d'écriture).

nb_invoices was incremented without the matching records while open_invoices()
replaced the domain with every gift, unfiltered. Both are replaced by a single
_get_open_invoices() override, so counter and list always show the same set.
@loris-fab
loris-fab requested a review from ecino September 1, 2026 09:02
@loris-fab loris-fab self-assigned this Sep 1, 2026
@loris-fab
loris-fab marked this pull request as ready for review September 1, 2026 09:06
@greptile-apps

greptile-apps Bot commented Sep 1, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

Child Gift invoice retrieval is not safe with the currently available accounting dependency because the new parent-method call raises an exception.

The exact override boundary was exercised against the available accounting revision and reproduced the missing-parent exception; the same path completed successfully when run with the companion revision that adds the required API.

Files Needing Attention: sponsorship_compassion/models/contracts.py needs a deployment-compatible dependency strategy for _get_open_invoices().

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for a posted P1 finding by presenting the focused executable source and accompanying evidence, including the SHA-256 and the stack trace, and confirmed the gift-contract path succeeds under companion PR 283.
  • T-Rex produced a second finding-comment proof for the same P1 finding to reinforce the review evidence.
  • T-Rex validated contract behavior against dependency revision fcd9a5db49f5d1d3718b987a01f7d78400f289b6 and PR 283 head, showing the parent method exists, the override raises AttributeError, and the gift path completes with one open gift invoice.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. General comment

    P1 New invoice override crashes unless compassion-accounting PR 283 is deployed first

    • Bug
      • SponsorshipContract._get_open_invoices() unconditionally calls super()._get_open_invoices(), but the available recurring_contract dependency at fcd9a5db49f5d1d3718b987a01f7d78400f289b6 does not define that method. A focused execution of the actual override for a gift contract raises AttributeError: 'super' object has no attribute '_get_open_invoices'.
    • Cause
    • Fix

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "[T3389] FIX: gift contracts invoices cou..." | Re-trigger Greptile

build_inv_line_data), so they never show up in the gift contract own
invoice_line_ids.
"""
invoices = super()._get_open_invoices()

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 Missing parent invoice API

_get_open_invoices() unconditionally calls super()._get_open_invoices(), but the currently available recurring_contract dependency does not provide that method. Opening or computing invoices for a Child Gift contract therefore raises AttributeError until the companion accounting change is deployed. Deploy and enforce the compatible accounting revision with this module, or retain an implementation that works with the existing dependency.

Artifacts

Focused executable source for the parent-method and gift-contract check

  • The authored Python check parses the actual override, checks each dependency revision, and executes the gift-contract super-call boundary; it is the exact source used for the captures.

Captured source and SHA-256 for the focused executable check

  • The executed command captured the complete check source and its SHA-256 hash, tying the proof runs to the uploaded script.

Gift-contract execution against the available accounting dependency fails

  • The focused check ran against available compassion-accounting revision fcd9a5d and captured the missing parent method plus the resulting AttributeError, confirming the runtime failure.

Gift-contract execution with companion PR 283 parent API succeeds

View artifacts

T-Rex Ran code and verified through T-Rex

@loris-fab loris-fab Sep 1, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Correct, and intentional : this is a paired change, as stated at the top of the description: PR #2141
cannot work without #283, which introduces _get_open_invoices().
Both PRs carry the same ticket (T3389) and must be merged together.
On the three suggested options:

  • Merge/deploy the other PR first : that is the plan, and both descriptions say so.
  • Pin the compatible revision in the manifest : not possible: Odoo dependencies are module names
    only, with no version constraint, as the comment itself acknowledges. All repositories in this stack
    are checked out side by side on branch 18.0 and deployed together, so a cross-repo API addition
    consumed by a dependent module is the normal pattern here.
  • Keep an implementation that works without the parent API (hasattr guard or fallback) rejected
    on purpose. It would silently hide a missing dependency and leave the gift-contract counter wrong
    instead of failing loudly. An AttributeError at load time is the correct signal that the stack is
    incomplete.
    No code change.

@ecino
ecino merged commit 14e1b4d into 18.0 Sep 2, 2026
2 checks passed
@ecino
ecino deleted the T3389-gift-invoices-counter branch September 2, 2026 07:47
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