Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ RUN apt-get update -qq && \
libpq-dev \
curl \
netcat-traditional \
wkhtmltopdf \
chromium \
libyaml-dev

# Add Node, required for asset pipeline.
Expand Down
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ gem 'devise', '~>4.9.4'
gem 'devise-i18n', '~>1.15.0'
gem 'factory_bot_rails', '~> 6.5.1'
gem 'faker', '~> 3.5.3'
gem 'grover', '~> 1.2.4'
gem 'http', '~> 5.3.1'
gem 'jbuilder', '~> 2.14.1'
gem 'jquery-rails', '~> 4.6.1'
Expand Down Expand Up @@ -43,8 +44,6 @@ gem 'sprockets-rails', '~> 3.5', '>= 3.5.2'
gem 'turbo-rails', '~> 2.0', '>= 2.0.20'
gem 'uglifier', '~> 4.2.1'
gem 'validates_timeliness', '~> 7.1.0'
gem 'wicked_pdf', '~> 2.8.2'
gem 'wkhtmltopdf-binary', '~> 0.12.6.10'

group :development, :test do
gem 'awesome_print', '~> 1.9.2'
Expand Down
9 changes: 3 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ GEM
google-protobuf (4.33.0-x86_64-linux-gnu)
bigdecimal
rake (>= 13)
grover (1.2.4)
nokogiri (~> 1)
guard (2.19.1)
formatador (>= 0.2.4)
listen (>= 2.7, < 4.0)
Expand Down Expand Up @@ -596,10 +598,6 @@ GEM
base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
wicked_pdf (2.8.2)
activesupport
ostruct
wkhtmltopdf-binary (0.12.6.10)
zeitwerk (2.7.3)

PLATFORMS
Expand All @@ -625,6 +623,7 @@ DEPENDENCIES
factory_bot_rails (~> 6.5.1)
faker (~> 3.5.3)
foreman (~> 0.90.0)
grover (~> 1.2.4)
guard-livereload (~> 2.5.2)
guard-rspec (~> 4.7.3)
http (~> 5.3.1)
Expand Down Expand Up @@ -682,8 +681,6 @@ DEPENDENCIES
uglifier (~> 4.2.1)
validates_timeliness (~> 7.1.0)
web-console (~> 4.2.1)
wicked_pdf (~> 2.8.2)
wkhtmltopdf-binary (~> 0.12.6.10)

BUNDLED WITH
2.6.9
8 changes: 1 addition & 7 deletions app/assets/stylesheets/pdf.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
// There is a bug with Bootstrap tables in PDF, so we use td in a th, but it needs to be bold
thead,
tfoot {
td {
font-weight: bold;
}
}
// PDF-specific styles
42 changes: 36 additions & 6 deletions app/controllers/invoices_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ def index

def show
@invoice = invoice
token_based_access = !integer_id?(params[:id])

# Authorize for authenticated access (integer ID), skip for token-based access
authorize @invoice, :show? unless token_based_access

respond_to do |format|
format.html
format.pdf do
render pdf: "Factuur #{@invoice.human_id}",
template: 'invoices/show.html.erb',
lowquality: true
end
format.pdf { render_invoice_pdf }
end
end

Expand All @@ -42,6 +42,9 @@ def create

def pay # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
@invoice = invoice
token_based_access = !integer_id?(params[:id])

authorize @invoice, :pay? unless token_based_access

if @invoice.paid?
redirect_to invoice_path params[:id]
Expand Down Expand Up @@ -73,14 +76,41 @@ def send_invoice

private

def integer_id?(id)
Integer(id)
true
rescue ArgumentError
false
end

def invoice
@invoice = Invoice.find(Integer(params[:id]))
authorize @invoice
rescue ArgumentError
@invoice = Invoice.find_by!(token: params[:id])
end

def permitted_attributes
params.require(:invoice).permit(%i[user_id activity_id name_override email_override rows], rows_attributes: %i[name amount price])
end

def render_invoice_pdf # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
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
send_data pdf, filename: "Factuur-#{@invoice.human_id}.pdf", type: 'application/pdf', disposition: 'attachment'
rescue StandardError => e
Rails.logger.error "Failed to generate PDF for invoice #{@invoice.id}: #{e.message}"
if request.format.pdf?
render plain: 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.', status: :internal_server_error
else
flash[:error] = 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.'
redirect_to invoice_path(@invoice)
end
end
end
3 changes: 3 additions & 0 deletions app/controllers/zatladder_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def current_year
end
end

# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def zatladder_spendings(from, to)
users = User.in_amber.exists? ? User.in_amber : User.sofia_account
@users_spendings = users.calculate_spendings(from:, to:)
Expand All @@ -33,6 +34,8 @@ def zatladder_spendings(from, to)
spendings: @users_spendings.fetch(user.id, 0)
}
end
zatladder.reject! { |user| user[:spendings].zero? }
zatladder.sort_by { |id| id[:spendings] }.reverse!
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
end
16 changes: 13 additions & 3 deletions app/mailers/invoice_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,19 @@ def invoice_mail(invoice) # rubocop:disable Metrics/AbcSize, Metrics/MethodLengt
@cab_disabled = true
end

attachments["#{invoice.human_id}.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(pdf: invoice.human_id.to_s, template: 'invoices/show', layout: 'pdf')
)
begin
html = render_to_string(
template: 'invoices/show',
formats: [:html],
layout: 'pdf'
)
pdf = Grover.new(html).to_pdf
attachments["#{invoice.human_id}.pdf"] = pdf
rescue StandardError => e
Rails.logger.error "Failed to generate PDF attachment for invoice #{invoice.id}: #{e.message}"
Rails.logger.error e.backtrace.join("\n")
# Continue sending email without PDF attachment
end

mail to: @invoice.email, subject: "Factuur #{invoice.human_id} #{Rails.application.config.x.company_name}"
end
Expand Down
4 changes: 4 additions & 0 deletions app/policies/invoice_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ def send_invoice?
user&.treasurer?
end

def download?
user&.treasurer?
end

def pay?
show?
end
Expand Down
8 changes: 8 additions & 0 deletions app/views/invoices/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
<% if policy(Invoice).send_invoice? %>
<th scope="col">Verstuur</th>
<% end %>
<% if policy(Invoice).download? %>
<th scope="col">Download</th>
<% end %>
</tr>
</thead>
<tbody class="table-group-divider">
Expand Down Expand Up @@ -77,6 +80,11 @@
<% end %>
</td>
<% end %>
<% if policy(Invoice).download? %>
<td>
<%= link_to 'Downloaden', invoice_path(invoice, format: :pdf), class: 'btn btn-primary', download: "Factuur-#{invoice.human_id}.pdf" %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
Expand Down
20 changes: 10 additions & 10 deletions app/views/invoices/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@
<table class="table table-striped">
<thead>
<tr>
<td scope="col" class="col-8">Consumpties</td>
<td scope="col" class="col-2">Aantal</td>
<td scope="col" class="col-2">Totaalbedrag</td>
<th scope="col" class="col-8">Consumpties</th>
<th scope="col" class="col-2">Aantal</th>
<th scope="col" class="col-2">Totaalbedrag</th>
</tr>
</thead>
<tbody class="table-group-divider">
Expand All @@ -110,9 +110,9 @@
</tbody>
<tfoot class="table-group-divider">
<tr>
<td class="border-bottom-0">Totaal</td>
<th class="border-bottom-0">Totaal</th>
<td class="border-bottom-0" />
<td class="border-bottom-0"><%= number_to_currency(@invoice.activity.revenue_by_user(@invoice.user), unit: '€') %></td>
<th class="border-bottom-0"><%= number_to_currency(@invoice.activity.revenue_by_user(@invoice.user), unit: '€') %></th>
</tr>
</tfoot>
</table>
Expand All @@ -124,9 +124,9 @@
<table class="table table-striped">
<thead>
<tr>
<td scope="col" class="col-8"><% if @invoice.activity.count_per_product(user: @invoice.user).any? %>Overige kosten<% else %>Kosten<% end %></td>
<td scope="col" class="col-2">Aantal</td>
<td scope="col" class="col-2">Totaalbedrag</td>
<th scope="col" class="col-8"><% if @invoice.activity.count_per_product(user: @invoice.user).any? %>Overige kosten<% else %>Kosten<% end %></th>
<th scope="col" class="col-2">Aantal</th>
<th scope="col" class="col-2">Totaalbedrag</th>
</tr>
</thead>
<tbody class="table-group-divider">
Expand All @@ -140,9 +140,9 @@
</tbody>
<tfoot class="table-group-divider">
<tr>
<td class="border-bottom-0">Totaal</td>
<th class="border-bottom-0">Totaal</th>
<td class="border-bottom-0" />
<td class="border-bottom-0"><%= number_to_currency(@invoice.row_amount, unit: '€') %></td>
<th class="border-bottom-0"><%= number_to_currency(@invoice.row_amount, unit: '€') %></th>
</tr>
</tfoot>
</table>
Expand Down
19 changes: 19 additions & 0 deletions config/initializers/grover.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Grover Global Configuration
#
# Use this to set up shared configuration options for your entire application.
# Any of the configuration options shown here can also be applied to single
# models by passing arguments to the Grover.new call.
#
# To learn more, check out the README:
# https://github.com/Studiosity/grover

Grover.configure do |config|
# Common PDF options
config.options = {
format: 'A4',
print_background: true,
prefer_css_page_size: false,
display_url: "https://#{Rails.application.config.x.sofia_host}"

}
end
21 changes: 0 additions & 21 deletions config/initializers/wicked_pdf.rb

This file was deleted.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"jquery": "^3.7.1",
"moment": "^2.30.1",
"popper.js": "^1.16.1",
"puppeteer": "^24.35.0",
"remove-accents": "^0.5.0",
"vue": "^2.7.16",
"vue-loader": "^15.11.1",
Expand Down
Loading