Skip to content

T3435 mycompassion child information translations - #2144

Merged
ecino merged 6 commits into
18.0from
T3435-mycompassion-child-information-translations
Sep 9, 2026
Merged

T3435 mycompassion child information translations#2144
ecino merged 6 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: 5/5

No blocking failure remains.

The exercised correspondence scan conversion and malformed-PDF merge paths both preserve the affected letter through QWeb fallback rendering.

T-Rex T-Rex Logs

What T-Rex did

  • Ran the correspondence scan fallback harness against the pre-fix source and the current source; the current source produced QWeb PDF bytes for correspondence IDs 101 and 102, unlike the pre-fix runs that produced empty output.
  • Ran the PDF fallback harness in current mode; the test showed a merge-time rejection of malformed PDF bytes, QWeb rendered correspondence 42, and the document contained the fallback content.
  • Validated the harness usage by capturing before-and-after states with a dedicated comparison run to establish traceability of the fix.
  • Observed the current harness output detailing the malformed-PDF rejection, the corresponding letter (42) served via QWeb fallback, and confirmation that the fallback content is used; the validation script and checksum were uploaded for verification.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (3): Last reviewed commit: "[T3435] FIX corrupted-but-PDF-mimetype s..." | Re-trigger Greptile

Comment thread sbc_compassion/models/ir_actions_report.py Outdated
Comment thread sbc_compassion/models/ir_actions_report.py Outdated
Greptile review on PR #2144 (confirmed by @ecino): without_scan_ids only
tracked correspondence ids with no scan attachment at all, so a letter
whose attachment existed but failed to convert (unreadable, or
unsupported mimetype) was skipped from the merge entirely instead of
falling back to the QWeb render - a batch where every scan failed
produced a silent empty PDF instead of the letters. Track failed
conversions and fold them into the same fallback set.

Verified via throwaway migration script: simulating every scan failing
to convert now produces the QWeb-rendered fallback (1694 bytes) instead
of an empty merge.
Comment thread sbc_compassion/models/ir_actions_report.py
@danpa32
danpa32 requested a review from ecino September 8, 2026 08:03
Greptile review round 2 on PR #2144: the previous fix (letters whose
scan fails to *convert*) didn't cover a scan that converts fine but is
structurally malformed - to_pdf_stream() doesn't validate PDF content
for application/pdf attachments, it just wraps the raw bytes, so such a
stream reaches _merge_pdfs() unflagged. When the merge step then
rejects it, the existing handle_error callback only logged the error -
with no way to map the rejected stream back to its correspondence, that
letter silently vanished from the batch PDF with no QWeb fallback.

Track each stream's originating res_id, collect merge-rejected IDs in
the error callback, and re-render + merge those through QWeb before
returning the final PDF.

Verified via throwaway migration script against stage18_neutralized:
one correspondence with a genuinely valid 1-page scan and one with a
malformed-but-application/pdf-mimetype scan - merge log confirms the
malformed one was rejected at merge time, and the final PDF came out
at 2 pages (valid scan merged directly, malformed one via QWeb
fallback) instead of silently dropping to 1.
@ecino
ecino merged commit 1dd96a7 into 18.0 Sep 9, 2026
2 checks passed
@ecino
ecino deleted the T3435-mycompassion-child-information-translations branch September 9, 2026 06:16
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