damoiser / qr-bills

Ruby Gem to generate QR-Bills for Swiss payments
BSD 3-Clause "New" or "Revised" License
21 stars 15 forks source link

Problem displaying a QR Bill + the gem is changing the project I18n.locale #16

Closed Texicitys closed 2 years ago

Texicitys commented 2 years ago

Hello,

Like in my previous message (#8), I have problem to simply display a QR Bill using this gem.

Here is my controller :

class MainController < ApplicationController
  skip_authorization_check

  def index
    QRBills.create_creditor_reference("MTR81UUWZYO48NY55NP3")

    # get the QR params, so you will get the full hash structure and as well some default values
    params = QRBills.get_qr_params

    # fill the params, for example
    params[:bill_type]                                      = QRBills.get_qrbill_with_creditor_reference_type
    params[:qrcode_filepath]                                = "#{Dir.pwd}/tmp/qrcode-html.png"
    params[:output_params][:format]                         = "html"
    params[:bill_params][:creditor][:iban]                  = "CH93 0076 2011 6238 5295 7"
    params[:bill_params][:creditor][:address][:type]        = "S"
    params[:bill_params][:creditor][:address][:name]        = "Compagnia di assicurazione forma & scalciante"
    params[:bill_params][:creditor][:address][:line1]       = "Via cantonale"
    params[:bill_params][:creditor][:address][:line2]       = "24"
    params[:bill_params][:creditor][:address][:postal_code] = "3000"
    params[:bill_params][:creditor][:address][:town]        = "Lugano"
    params[:bill_params][:creditor][:address][:country]     = "CH"
    params[:bill_params][:amount]                           = 12345.15
    params[:bill_params][:currency]                         = "CHF"
    params[:bill_params][:debtor][:address][:type]          = "S"
    params[:bill_params][:debtor][:address][:name]          = "Foobar Barfoot"
    params[:bill_params][:debtor][:address][:line1]         = "Via cantonale"
    params[:bill_params][:debtor][:address][:line2]         = "25"
    params[:bill_params][:debtor][:address][:postal_code]   = "3001"
    params[:bill_params][:debtor][:address][:town]          = "Comano"
    params[:bill_params][:debtor][:address][:country]       = "CH"
    # you can get the new creditor reference using QRBills.create_creditor_reference("your_reference")
    params[:bill_params][:reference]                        = "RF89MTR81UUWZYO48NY55NP3"
    params[:bill_params][:reference_type]                   = "SCOR"
    params[:bill_params][:additionally_information]         = "pagamento riparazione monopattino"

    # generate the QR Bill
    @bill = QRBills.generate(params)
  end
end

Here is my view :

=@bill[:output].html_safe

And here is the result : image

I also tried with pdf output (using wicked_pdf gem) but the result is less good : Consroller :

respond_to do |format|
      format.html
      format.pdf {
        render :pdf => "show"
      }
    end

Same view on show.pdf.haml

=@bill[:output].html_safe

And here is the result when I want to display the pdf in my browser : image

create_creditor_reference changes the I18n local

Another problem that I just saw, when I'm adding this line in my controller (only this line is enough) :

QRBills.create_creditor_reference("MTR81UUWZYO48NY55NP3")

It change my I18n.locale to :it (italian)... Maybe it is linked with the 11's line of this file : https://github.com/damoiser/qr-bills/blob/master/lib/qr-bills/qr-html-layout.rb ?

Just let me know if I have to create another issue for that. I'm not sure it is linked.

I'm on : Rails 6.0.4.1 Ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux] Qr-bills (1.0.2)

Thanks for your help !

RandieM commented 2 years ago

Hi @Texicitys.

You will need to upgrade qr-bills to it's latest version. This will take care of the language issue.

You did not mention which version of wkhtmltopdf you are using, but I am assuming it's the latest. Try to use 0.12.5 and see if this helps with PDF generation. To the best of my knowledge, this problem is totally unrelated to the qr-bills gem.

Texicitys commented 2 years ago

Thanks for the reply,

I'm using qr-bills (1.0.2), wicked_pdf (2.1.0) and wkhtmltopdf-binary (0.12.6.5).

I just upgraded qr-bills and downgrade wkhtmltopdf-binary to use :

qr-bills (1.0.4)
      i18n (>= 1.8.3, < 2)
      rqrcode (>= 1.1.2, < 2)
wicked_pdf (2.1.0)
      activesupport
    wkhtmltopdf-binary (0.12.5)

And I got this error.. :

RuntimeError in UsersController#show

Failed to execute: ["/home/yves/.rbenv/versions/2.7.2/bin/wkhtmltopdf", "file:////tmp/wicked_pdf20211109-12903-fvzutt.html", "/tmp/wicked_pdf_generated_file20211109-12903-9zoqp0.pdf"] Error: PDF could not be generated! Command Error: /home/yves/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/wkhtmltopdf-binary-0.12.5/bin/wkhtmltopdf:40:in `<top (required)>': Invalid platform, must be running on Ubuntu 14.04/16.04/18.04 CentOS 6/7, Debian 8/9, or intel-based macOS (missing binary: /home/yves/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/wkhtmltopdf-binary-0.12.5/bin/wkhtmltopdf_ubuntu_20.04_amd64). (RuntimeError) from /home/yves/.rbenv/versions/2.7.2/bin/wkhtmltopdf:23:in `load' from /home/yves/.rbenv/versions/2.7.2/bin/wkhtmltopdf:23:in `<main>' 

I m on : Ubuntu 20.04.3 LTS.

So I upgraded again wkhtmltopdf to have :

qr-bills (~> 1.0.4)
wicked_pdf (2.1.0)
      activesupport
    wkhtmltopdf-binary (0.12.6.5)

And it display this : image

I18n.locale

For the I18n.locale problem, now it is a coinflip : once in 2 when I refresh the page it toggle between locale = :it or :fr (the local of my website).

I looks like now i need to go until this line @bill = QRBills.generate(params) for the gem changes the locale to :it.

Thanks for you help !

RandieM commented 2 years ago

It seems to me that you are not passing the locale anywhere in your controller.

As the error message clearly suggests, you are missing the wkhtmltopdf binary for your OS version. Simply copy the latest available ubuntu binary from /home/yves/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/wkhtmltopdf-binary-0.12.5/bin/ and rename it to wkhtmltopdf_ubuntu_20.04_amd64. You can find the answers to such questions by doing a simple search online though. These are not related to this gem.

Texicitys commented 2 years ago

I just created a new project to test (so you can easily reproduce the bug) :

Console

$ rails new blog
$ cd blog
$ generate controller Articles index

gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.2'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.4', '>= 6.1.4.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

gem 'qr-bills'
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 4.1.0'
  # Display performance information such as SQL time and flame graphs for each request in your browser.
  # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 3.26'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

app/controllers/articles_controller.rb

class ArticlesController < ApplicationController
  def index
    respond_to do |format|
      QRBills.create_creditor_reference("MTR81UUWZYO48NY55NP3")
      # get the QR params, so you will get the full hash structure and as well some default values
      params = QRBills.get_qr_params

      # fill the params, for example
      params[:bill_type]                                      = QRBills.get_qrbill_with_creditor_reference_type
      params[:qrcode_filepath]                                = "#{Dir.pwd}/tmp/qrcode-html.png"
      params[:output_params][:format]                         = "html"
      params[:bill_params][:creditor][:iban]                  = "CH93 0076 2011 6238 5295 7"
      params[:bill_params][:creditor][:address][:type]        = "S"
      params[:bill_params][:creditor][:address][:name]        = "Compagnia di assicurazione forma & scalciante"
      params[:bill_params][:creditor][:address][:line1]       = "Via cantonale"
      params[:bill_params][:creditor][:address][:line2]       = "24"
      params[:bill_params][:creditor][:address][:postal_code] = "3000"
      params[:bill_params][:creditor][:address][:town]        = "Lugano"
      params[:bill_params][:creditor][:address][:country]     = "CH"
      params[:bill_params][:amount]                           = 12345.15
      params[:bill_params][:currency]                         = "CHF"
      params[:bill_params][:debtor][:address][:type]          = "S"
      params[:bill_params][:debtor][:address][:name]          = "Foobar Barfoot"
      params[:bill_params][:debtor][:address][:line1]         = "Via cantonale"
      params[:bill_params][:debtor][:address][:line2]         = "25"
      params[:bill_params][:debtor][:address][:postal_code]   = "3001"
      params[:bill_params][:debtor][:address][:town]          = "Comano"
      params[:bill_params][:debtor][:address][:country]       = "CH"
      # you can get the new creditor reference using QRBills.create_creditor_reference("your_reference")
      params[:bill_params][:reference]                        = "RF89MTR81UUWZYO48NY55NP3"
      params[:bill_params][:reference_type]                   = "SCOR"
      params[:bill_params][:additionally_information]         = "pagamento riparazione monopattino"

      # generate the QR Bill
      bill = QRBills.generate(params)

      # bill format is given in the params, default is html
      # bill has the following format:
      #    bill = {
      #      params: params,
      #      output: "output"
      #    }
      format.html
      format.pdf do
        render pdf: "index"   # Excluding ".pdf" extension.
      end
    end
  end
end

app/views/articles/index.pdf.erb

<h1>Articles#index</h1>
<p>Find me in app/views/articles/index.html.erb</p>

Here is the result :

Started GET "/articles/index.pdf" for 127.0.0.1 at 2021-11-09 23:05:04 +0100
Processing by ArticlesController#index as PDF
  Rendering articles/index.pdf.erb
  Rendered articles/index.pdf.erb (Duration: 0.4ms | Allocations: 104)
[wicked_pdf]: ["/home/yves/.rbenv/versions/2.7.2/bin/wkhtmltopdf", "file:////tmp/wicked_pdf20211109-26343-ht61gy.html", "/tmp/wicked_pdf_generated_file20211109-26343-1bhgdgd.pdf"]
  Rendering text template
  Rendered text template (Duration: 0.3ms | Allocations: 25)
Sent data index.pdf (15.7ms)
Completed 200 OK in 714ms (Views: 3.1ms | ActiveRecord: 0.0ms | Allocations: 3682)

Started GET "/articles/index.pdf" for 127.0.0.1 at 2021-11-09 23:06:20 +0100
Processing by ArticlesController#index as PDF
Completed 500 Internal Server Error in 565ms (Allocations: 203968)

I18n::InvalidLocale ("it" is not a valid locale):

app/controllers/articles_controller.rb:35:in `block in index'
app/controllers/articles_controller.rb:3:in `index'

image

Texicitys commented 2 years ago

It seems to me that you are not passing the locale anywhere in your controller.

I'm passing the locale in my application.rbfile :

config.i18n.default_locale = :fr
config.i18n.available_locales = %i[fr de it en]

The gem should not change the locale to :it .

As the error message clearly suggests, you are missing the wkhtmltopdf binary for your OS version. Simply copy the latest available ubuntu binary from /home/yves/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/wkhtmltopdf-binary-0.12.5/bin/ and rename it to wkhtmltopdf_ubuntu_20.04_amd64. You can find the answers to such questions by doing a simple search online though. These are not related to this gem.

This error only appears because you asked me to downgrade the wkhtmltopdf version... So I just upgraded it again and it solved this issue of the missing wkhtmltopdf binary for my OS version. But not the displaying issue. But if you say that QR-bill gem is only compatible with wkhtmltopdf version 0.12.5 I will actually have no choice to try your suggestion. But do you really think the newest version of wkhtmltopdf is not compatible with QR-Bill gem ?

Thanks

RandieM commented 2 years ago

But if you say that QR-bill gem is only compatible with wkhtmltopdf version 0.12.5 I will actually have no choice to try your suggestion. But do you really think the newest version of wkhtmltopdf is not compatible with QR-Bill gem ?

I actually said the exact opposite. Your PDF rendering problem has nothing to do with the qr-bills gem. Please report this problem to the wkhtmltopdf-binary repository.

Texicitys commented 2 years ago

I have no problem with wkhtmltopdf since years but thanks for your answer. I also use nearly 40 gems with no problem. But feel free to close the issue if you are not able to reproduce my error and you look veeeeery sure since the beginning that the problem is not from your gem.

It is just strange that I could reproduce the same bug in an empty project. Just copy/pasting your samples.. ;-)

But I can understand if you have no time to spend on that. I will still follow the project and be aware if you do some updates. I hope I will have the time and the skill to help you soon !

Cheers and thanks again for this gem who looks great :-)

solaris007 commented 2 years ago

The PNG won't be show in your browser, as /home/yves ... is not exposed in the ruby routes. The image src of the PNG is intended to be used by a PDF generator as an absolute path on the file system.

To debug why the PNG is not shown in your PDF, set a breakpoint on line 49 of the wicked_pdf gem's ./lib/wicked_pdf.rb (the line is: pdf = pdf_from_html_file(string_file.path, options), grab the string_file.path, copy the HTML file to somewhere. Then execute wkhtmltopdf directly on the command line to process that file. Check the output. If the image is there, its a problem in the ruby/rails stack. If not, wkhtmltopdf can't access the image file (permissions?).

damoiser commented 2 years ago

Hi @Texicitys, please try again, with the PR of @danielpuglisi this should be fixed as the locale is now set dynamically based on the main-app. Fix is available in the new version v1.0.7

RandieM commented 2 years ago

In case this is of any use to anyone in the future:

Regarding images not appearing in PDF files, when using wkhtmltopdf-binary version >= 0.12.6: https://github.com/zakird/wkhtmltopdf_binary_gem/issues/93