Skip to content

Conversation

@lodewiges
Copy link
Contributor

@lodewiges lodewiges commented Jan 20, 2026

There where multiple issue with Html based pdf generation on staging, and this should simplify it.

Summary by CodeRabbit

  • Bug Fixes

    • Payment button now appears only when payment provider is configured.
    • Invoice status row is shown only to treasurer users.
    • If PDF generation fails when emailing invoices, emails still send without the PDF.
  • Refactor

    • PDFs are generated from tokenized invoice URLs for rendering.
    • Removed the previous inline PDF layout and CSS aggregation used for PDF output.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 20, 2026 08:55
@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Switched PDF generation from rendering HTML in-process to having Grover fetch a tokenized invoice URL; removed the PDF layout that inlined CSS, adjusted view/controller flags for PDF mode, tightened payment button visibility, and simplified Grover initializer options.

Changes

Cohort / File(s) Summary
PDF rendering: controller & mailer
app/controllers/invoices_controller.rb, app/mailers/invoice_mailer.rb
Replaced inline HTML-to-PDF rendering with Grover fetching a tokenized URL (invoice_url(@invoice.token, pdf: true)). Controller toggles @show_navigationbar/@show_extras based on pdf param. Mailer now uses URL-based Grover, logs backtrace on failures and proceeds without attachment.
Invoice view
app/views/invoices/show.html.erb
Status row now conditional for treasurer users; payment button shown only when unpaid AND Mollie API key present.
PDF layout removal
app/views/layouts/pdf.html.erb
Deleted: previously inlined CSS by reading asset files and provided the PDF HTML layout.
Grover initializer
config/initializers/grover.rb
Inlined config.options assignment, removed some keys (e.g., display_url, prefer_css_page_size), and set executable_path/launch_args inline using env checks.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as InvoicesController
    participant Grover as Grover
    participant View as InvoiceView
    participant Mailer as InvoiceMailer

    Note over Client,Controller: Request PDF for invoice
    Client->>Controller: GET /invoices/:id?pdf=true
    Controller->>Controller: set `@show_navigationbar`=false, `@show_extras`=false
    Controller->>Grover: Grover.fetch(invoice_url(token, pdf: true))
    Grover->>Controller: HTTP GET invoice_url(token, pdf: true)
    Controller->>View: render invoices/show (pdf: true) -> HTML
    View-->>Grover: HTML response fetched by Grover
    Grover-->>Controller: PDF bytes returned
    Controller-->>Client: send PDF response

    Note over Mailer,Grover: Mailer PDF generation
    Mailer->>Grover: Grover.new(invoice_url(token, pdf: true))
    Grover->>Mailer: fetch HTML via token URL -> PDF bytes (or error logged)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

status:ready to review

Poem

🐰 I hopped from HTML to a tokened trail,
Grover fetches pages without fail.
No layout file, just a URL bright,
PDFs delivered through the night.
Hop, hop, attach — and off I sail! 🥕📄

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is minimal and lacks required sections. It missing testing details, checklist items, and detailed summary of changes. Complete the PR description template by adding: database migration checklist items, testing verification steps, detailed summary of UI/functional changes, and any related issues or dependencies.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: converting PDF generation from HTML-based to URL-based approach.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request refactors PDF generation for invoices from an HTML-based approach to a URL-based approach using Grover. The change addresses staging environment issues with the previous HTML-based implementation.

Changes:

  • Simplified Grover configuration by removing HTML-specific options and streamlining development vs production conditional logic
  • Deleted the custom PDF layout file that handled CSS inlining for HTML-based generation
  • Modified invoice mailer and controller to generate PDFs by passing URLs to Grover instead of rendered HTML strings
  • Added conditional logic to hide navigation bar and extras when rendering invoices for PDF generation
  • Updated payment button conditional to also check for Mollie API key presence

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
config/initializers/grover.rb Simplified configuration by removing HTML-based options (display_url, prefer_css_page_size) and consolidating conditional logic into inline ternary operators
app/views/layouts/pdf.html.erb Deleted custom PDF layout that was only needed for HTML-based generation
app/views/invoices/show.html.erb Added Mollie API key check to payment button conditional
app/mailers/invoice_mailer.rb Changed from rendering HTML string to using token-based URL for PDF generation
app/controllers/invoices_controller.rb Added logic to hide UI elements when pdf parameter is present; updated render_invoice_pdf to use URL-based approach

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +66 to 68
<% if !@invoice.paid? && Rails.application.config.x.mollie_api_key.present? %>
<%= link_to pay_invoice_url @invoice.token do %>
<button class="col-sm-3 offset-sm-9 btn btn-primary">Betalen</button>
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The compound condition can be simplified for better readability. Instead of using the negation operator with unless, consider using a positive condition with if. The current change from unless @invoice.paid? to if [email protected]? && Rails.application.config.x.mollie_api_key.present? could be written more idiomatically as if @invoice.unpaid? && Rails.application.config.x.mollie_api_key.present? or keep the unless pattern consistent.

Suggested change
<% if [email protected]? && Rails.application.config.x.mollie_api_key.present? %>
<%= link_to pay_invoice_url @invoice.token do %>
<button class="col-sm-3 offset-sm-9 btn btn-primary">Betalen</button>
<% if Rails.application.config.x.mollie_api_key.present? %>
<% unless @invoice.paid? %>
<%= link_to pay_invoice_url @invoice.token do %>
<button class="col-sm-3 offset-sm-9 btn btn-primary">Betalen</button>
<% end %>

Copilot uses AI. Check for mistakes.
Comment on lines +100 to +106
def render_invoice_pdf
token_based_access = !integer_id?(params[:id])
authorize @invoice, :download? unless token_based_access

html = render_to_string(
template: 'invoices/show',
formats: [:html],
layout: 'pdf'
)
pdf = Grover.new(html).to_pdf
# Use token-based URL for unauthenticated Grover access
url = invoice_url(@invoice.token, pdf: true)
pdf = Grover.new(url).to_pdf
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The new URL-based PDF generation logic lacks test coverage. Since the codebase has comprehensive test coverage for other controller actions (as seen in spec/controllers/invoices_controller/), this change should include tests that verify the PDF generation works correctly with the new URL-based approach, including tests for successful PDF generation and error handling.

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +15
# Use token-based URL for unauthenticated Grover access
url = url_for(controller: 'invoices', action: 'show', id: invoice.token, pdf: true, only_path: false)
pdf = Grover.new(url).to_pdf
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The new URL-based PDF attachment generation lacks test coverage. Since the codebase has comprehensive test coverage for controllers, this change should include tests that verify the PDF attachment is correctly generated and attached to the email, including tests for error handling when PDF generation fails.

Copilot uses AI. Check for mistakes.
@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

❌ Patch coverage is 42.85714% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.11%. Comparing base (2109237) to head (f7468d5).

Files with missing lines Patch % Lines
app/controllers/invoices_controller.rb 60.00% 2 Missing ⚠️
app/mailers/invoice_mailer.rb 0.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           staging    #1212      +/-   ##
===========================================
+ Coverage    77.08%   77.11%   +0.03%     
===========================================
  Files           54       54              
  Lines         1370     1372       +2     
===========================================
+ Hits          1056     1058       +2     
  Misses         314      314              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/controllers/invoices_controller.rb (1)

100-116: Use only_path: false for explicit full URL generation, matching the pattern in InvoiceMailer.

The current code relies on implicit request context for the host, while the mailer explicitly uses only_path: false. Since action_controller.default_url_options is not configured (only action_mailer.default_url_options is), make the URL generation explicit for consistency and clarity:

url = invoice_url(`@invoice.token`, pdf: true, only_path: false)

This matches the safer, more explicit pattern already used in InvoiceMailer (line 14) and ensures the URL works reliably regardless of request context variations.

🧹 Nitpick comments (1)
app/views/invoices/show.html.erb (1)

66-70: Consider hiding the payment button when rendering for PDF.

The added mollie_api_key.present? check is a good improvement. However, the controller sets @show_extras = false when pdf: true, but this flag isn't used here. The payment button will still appear in the PDF if Mollie is configured and the invoice is unpaid, which is likely undesirable since users can't click buttons in a PDF.

Suggested fix
-      <% if [email protected]? && Rails.application.config.x.mollie_api_key.present? %>
+      <% if `@show_extras` != false && [email protected]? && Rails.application.config.x.mollie_api_key.present? %>

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