Skip to content

T3435 mycompassion child information translations - #2144

Open
danpa32 wants to merge 4 commits into
18.0from
T3435-mycompassion-child-information-translations
Open

T3435 mycompassion child information translations#2144
danpa32 wants to merge 4 commits into
18.0from
T3435-mycompassion-child-information-translations

Conversation

@danpa32

@danpa32 danpa32 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

T3435 — MyCompassion: child information page translation issues + letters download error

Related PR

Original report

Quality test failure on the MyCompassion portal's "Child information" page: several pieces of information have errors in some languages, especially french.

Known separate/open issue — not fixed

ir.advanced.translation.get() fell back to _(src) (English) when no translation row existed for a term, but returned a hard "" when a row did exist for the language but the specific requested gender/plural field (e.g. female_singular) was left empty — exactly the "Ma mère travaille comme ." case, where a French row existed with male_singular filled in but female_singular blank. Fixed to fall back to _(src) in that case too, so an incomplete translation degrades to English instead of disappearing. Note: the actual missing French text for this specific occupation is a data gap in that table, not something this code fix can supply — someone needs to fill in the actual female_singular value for whichever source string this is which bring the known separate issue. This fix only prevents the blank symptom for its own scenario (translation row exists, specific field blank) going forward; the actual French text for whatever specific occupation values are missing is still absent from the ir.advanced.translation table and needs a data fix, not a code fix.

How to test manually

  1. Upgrade advanced_translation, child_compassion, sbc_compassion with -u ... --i18n-overwrite.
  2. On the MyCompassion portal in French, open a child's page: favorite subjects/hobbies lists should join with "et", not "and".
  3. "Mon centre" tab: house construction material fields should show in French (e.g. "Brique, parpaing et ciment").
  4. Download a correspondence letters PDF for a partner with at least one corrupted/unreadable scanned letter attachment — should succeed and include every other letter, instead of a 400 Bad Request.

AdvancedTranslatable.get_list() (used for e.g. a child's favorite
subjects/hobbies on the MyCompassion portal) joins the last two values
with a hardcoded code-domain string, _("and") - but the
advanced_translation module shipped zero French/German/Italian
translations at all (only Nordic languages), so non-English users saw
e.g. "Art, Mathématiques and Education physique" - correctly
translated items, English conjunction.

Add fr_CH/de/it.po with just the two code strings this module
actually uses ("and", "Unknown" from the same get_list()/get_date()
pattern) - not attempting to translate the rest of this untouched
module as part of this fix.
…lations

ir.advanced.translation.get() fell back to _(src) (the English source)
when no translation row existed for the term, but returned a hard ""
when a row existed for the language yet the specific requested
gender/plural field was left empty - e.g. "Ma mère travaille comme ."
on the MyCompassion portal, where a French row existed with
male_singular filled in but female_singular blank.

Fall back to _(src) in that case too, matching the no-row behavior,
so an incomplete translation degrades to English instead of silently
disappearing. The underlying missing French text itself is a data gap
in that table, not something this code change can supply.
CompassionProject._get_materials() (backing typical_wall/roof/floor_
material, shown on the MyCompassion portal's "My center" tab) had 15
hardcoded English labels never wrapped in _(), so they were never
extractable as translatable strings - e.g. "Construction typique des
maisons: Brick, block and cement" always showed the English label
regardless of the viewer's language.

Wrap the labels with _() and add the French/German/Italian
translations to the module's existing i18n files, inserted by hand at
their correct alphabetical position rather than through a full
po_build.py rebuild - the module currently has ~230+ pre-existing
untranslated strings per language and a handful of stale entries
unrelated to this change; a full rebuild would have entangled this
narrow fix with that unrelated, much larger pre-existing gap.
…load

sbc_compassion's _render_qweb_pdf override merges scanned correspondence
letters via _merge_pdfs() without a handle_error callback, so a single
unreadable/corrupted sponsor_letter_scan attachment (or one with an
unrecognized mimetype, or one that fails image-to-PDF conversion)
raised UserError("Odoo is unable to merge the generated PDFs.") -
surfaced to the portal as a 400 Bad Request, blocking the download of
every other letter in the batch too.

Guard the per-attachment conversion and pass a tolerant handle_error
to _merge_pdfs() that logs and skips the bad stream instead, so the
customer still gets every other letter that could be produced.
@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

The correspondence-report change can return an empty document for a normal recovery scenario, so it needs correction before merge.

A focused runtime harness exercised both unrecognized and exception-throwing scan conversions, compared them with the normal no-scan fallback, and reproduced the omission reliably.

Files Needing Attention: sbc_compassion/models/ir_actions_report.py, especially the fallback-ID calculation after skipped scan conversions.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a finding-comment-proof for a posted P1 finding and linked it to the related review comment.
  • T-Rex reviewed the P1 harness artifacts and logs, including the focused harness output, the baseline QWeb fallback log, and the failed scan-conversion log.
  • T-Rex produced a second finding-comment-proof for a posted P1 finding and linked it to the related review comment.
  • T-Rex performed a general-contract-validation-proof analysis showing that without_scan_ids is empty, so QWeb is not invoked and the path returns a zero-page PDF, with no production files changed.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. General comment

    P1 Unreadable correspondence scans suppress QWeb rendering for all affected selected letters

    • Bug
      • The focused runtime run selected IDs 101 and 102, gave each a matching scan attachment, and made conversions return None (then None plus an exception). In both cases, FALLBACK_CALLS [] and MERGE_CALLS [[]] were observed; the returned document was a valid-looking 311-byte PDF envelope with /Count 0, so none of the requested letters were rendered.
    • Cause
      • without_scan_ids at sbc_compassion/models/ir_actions_report.py:58 is computed from every matching attachment ({att.res_id for att in attachments}), including attachments skipped at lines 40-55. Thus failed conversion does not restore that record to the QWeb fallback set, and lines 72-75 merge no usable content.
    • Fix
      • Track the correspondence IDs for which to_pdf_stream successfully produced a stream, then calculate the QWeb fallback set from res_ids - successful_scan_ids. Preserve the existing warning behavior and add regression cases for all-None and exception conversions.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "[T3435] FIX one corrupted letter scan bl..." | Re-trigger Greptile

continue
streams.append(stream)

without_scan_ids = set(res_ids) - {att.res_id for att in attachments}

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 Failed scans suppress letter rendering

without_scan_ids is calculated from every matching attachment, including attachments skipped because to_pdf_stream() returned None or raised an exception. When every selected letter has an unreadable or unsupported scan, no IDs are sent to the QWeb fallback and _merge_pdfs() receives no usable streams, returning a successful zero-page PDF. Track only IDs whose scans converted successfully, then render all remaining selected letters through QWeb.

Artifacts

Focused correspondence PDF failure harness source

  • Minimal Odoo stand-ins import the unchanged production method and exercise the no-attachment baseline plus all-failed attachment conversions, establishing the compared execution scope.

Baseline QWeb fallback execution log without scan attachments

  • The baseline command selected IDs 101 and 102 with no scan attachments and recorded `FALLBACK_CALLS [[101, 102]]`, showing the requested letters would normally be rendered.

Failed scan conversion execution log returning a zero-page PDF

  • The failure command made all selected scan conversions return `None` or raise and recorded no fallback, an empty merge input, and a successful PDF with `/Count 0`, confirming the defect.

Captured focused harness source output

  • The captured source-display command records the exact authored harness used for the baseline and failure executions, providing reproducible test evidence.

View artifacts

T-Rex Ran code and verified through T-Rex

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.

This is a valid comment that needs to be fixed.

continue
streams.append(stream)

without_scan_ids = set(res_ids) - {att.res_id for att in attachments}

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.

This is a valid comment that needs to be fixed.

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