Skip to content

T3333 letter report fixes - #2158

Merged
ecino merged 5 commits into
18.0from
T3333-letter-report-fixes
Sep 17, 2026
Merged

ecino merged 5 commits into
18.0from
T3333-letter-report-fixes

Conversation

@danpa32

@danpa32 danpa32 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

T3333 — MyCompassion "write a letter" quality-test failures

Original ask

A quality test on "MyCompassion: write a letter" failed on 2026-07-22 with several defects reported from a single manual walkthrough:

  • No menu icons top right, child picture missing, child arrow selector missing, Compassion logo missing top left, on the new-letter page.
  • No margin under the "Preview"/"Send" buttons.
  • Saving a draft shows a green "letter saved" confirmation in English instead of the sponsor's language.
  • The letter preview's attached-pictures page showed "Additional pictures" in large block capitals.
  • Opening a just-sent letter from MyCompassion gave an internal server error.
  • Backend → Sponsorships → Correspondence → Letters → a letter → action wheel → "Correspondence Report" downloads the PDF instead of displaying it, on Mac.

Related PRs

What changed

compassion-modules (sbc_compassion)

  • efd3e51bthe 500. get_attachments_per_page() crashed with AttributeError: 'bool' object has no attribute 'startswith' on any attachment with a NULL mimetype, reached via /b2s_image. It ran unconditionally on every letter because the report template's t-if/t-foreach sat on the same node — QWeb compiles t-foreach before t-if, so the guard never actually gated the call. Nested the directives and guarded the mimetype check. Reproduced the exact crash live on stage18_neutralized by temporarily reverting the fix, then confirmed 8 UUIDs (5 previously-crashing + 3 controls) all return 200 afterward with zero occurrences of the error in the log.
  • 1a7cd55c — narrowed original_attachment_ids's domain to res_field = False, removing the actual source of the NULL-mimetype rows (attachment-backed binary fields like sponsor_letter_scan) from a field meant only for attached images. Separable from the crash fix per the original plan.
  • 11cb201fthe blank-PDF issue (bigger than the reported ticket). While investigating the 500, found that report_needs_original_text gated the letter-text overlay on "not yet sent to GMC" as a proxy for "no image exists yet" — false for any S2B letter that was sent but never got a scanned photo back. Those letters render as a valid but completely empty PDF: no image, no text, despite the sponsor's message sitting untouched in the database. Replaced the gate with a real check (_has_page_image_source(), reading only stored URL columns, never triggering an external Cloudinary/Connect fetch). Verified on real stage18_neutralized data: a previously blank letter now renders its full text; a letter with a real returned image still correctly shows no overlay (no regression); a not-yet-sent letter renders exactly as before.
  • 2e0937b8 — found while manually testing the above with a long letter: spread_text_to_pages() (which measures whether a page's text overflows its template text box and pushes the excess onto a new page) existed but was only wired up as a manual "Spread text to pages" backend button — the normal S2B letter-generation flow never called it, so a long sponsor letter would silently overflow its text box into the next page's rendering area instead of being paginated. Now called automatically after letter creation (draft and real generation both).

get_attachments_per_page() crashed with AttributeError on any attachment
whose mimetype is NULL, hit via /b2s_image. It ran unconditionally on
every letter because the report template's t-foreach was compiled before
its guarding t-if (both directives were on the same node) - nest them so
the condition actually gates the call.
…ent_ids

The "Attached images" field picked up sponsor_letter_scan/zip_file
attachments (res_field set), which is where the NULL-mimetype rows
crashing get_attachments_per_page() come from. Restrict the domain to
res_field = False so it only sees actual attached images.
…tatus

report_needs_original_text was gated on "not yet sent to GMC", using that
as a proxy for "no image exists yet". For S2B letters that were sent but
never got a photo back, this skipped the text overlay too, rendering a
silently blank page despite the sponsor's text sitting in the database.
Gate it on whether an image source is actually known instead, via a new
_has_page_image_source() that only reads stored URL columns and never
triggers an external Cloudinary/Connect fetch.
spread_text_to_pages() measures whether a page's text overflows its
template text box and pushes the excess onto a new page, but it was only
wired up as a manual backend button. The normal letter-generation flow
never called it, so a sufficiently long sponsor letter would overflow its
text box and bleed into the next page's rendering area instead of being
split across pages.
@greptile-apps

greptile-apps Bot commented Sep 17, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

Safe to merge.

Reviews (2) · Last reviewed commit: "[T3333] Require every page to have an im..."

Comment thread sbc_compassion/models/correspondence.py Outdated
_has_page_image_source() used .filtered() + bool(), which is true as soon
as any single page has a known image. Since the letter-wide overlay flag
gates every page uniformly, a multi-page letter where only some pages
have a source would suppress the text overlay everywhere, leaving the
uncovered pages with neither an image nor the sponsor's text - the same
blank-page failure this fix was meant to close, just on a narrower case.

Found by greptile review on PR #2158.
@ecino
ecino merged commit ad2fe70 into 18.0 Sep 17, 2026
2 checks passed
@ecino
ecino deleted the T3333-letter-report-fixes branch September 17, 2026 09:10
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