From aea067026887f835273220b2b4e39a32b0a86d87 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Wed, 5 May 2021 10:10:24 +0200 Subject: [PATCH 1/3] Add method payment_method to get the payment method from a payment - Method `payment_method_name` now use `payment_method` --- app/helpers/spree/payment_methods_helper.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/helpers/spree/payment_methods_helper.rb b/app/helpers/spree/payment_methods_helper.rb index 00abd77eef..361d6c6afd 100644 --- a/app/helpers/spree/payment_methods_helper.rb +++ b/app/helpers/spree/payment_methods_helper.rb @@ -1,9 +1,13 @@ module Spree module PaymentMethodsHelper - def payment_method_name(payment) + def payment_method(payment) # hack to allow us to retrieve the name of a "deleted" payment method id = payment.payment_method_id - Spree::PaymentMethod.find_with_destroyed(id).name + Spree::PaymentMethod.find_with_destroyed(id) + end + + def payment_method_name(payment) + payment_method(payment).name end end end From 7ab065e8cd12bb3c55f712582dd1eb79fe5f953e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Tue, 18 May 2021 16:32:47 +0200 Subject: [PATCH 2/3] Add section at the bottom of invoice: Payment Description at Checkout - If there is any payments, we use the last one to retrieve the payment method description Use the first completed payment to display payment description Completed is state = "checkout" or state = "completed" Squash w/ "Add section at the bottom of invoice: Payment Description at Checkout" Squash w "Add section at the bottom of invoice: Payment Description a" --- app/views/spree/shared/_payment.html.haml | 5 +++++ config/locales/en.yml | 1 + 2 files changed, 6 insertions(+) diff --git a/app/views/spree/shared/_payment.html.haml b/app/views/spree/shared/_payment.html.haml index f13e9b7892..0c1bc8c8d0 100644 --- a/app/views/spree/shared/_payment.html.haml +++ b/app/views/spree/shared/_payment.html.haml @@ -13,3 +13,8 @@ = t :email_payment_summary - if @order.payments.any? = render partial: 'spree/shared/payments_list', locals: { payments: @order.payments } + - if last_payment_method(@order).present? + %p.callout{style: "margin-top: 40px"} + %strong + = t :email_payment_description + %p{style: "margin: 5px"}= last_payment_method(@order).description diff --git a/config/locales/en.yml b/config/locales/en.yml index a8d7ec57e7..8ac5f28653 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1669,6 +1669,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using email_order_summary_includes_tax: "(includes tax):" email_payment_paid: PAID email_payment_not_paid: NOT PAID + email_payment_description: Payment Description at Checkout email_payment_summary: Payment summary email_payment_method: "Paying via:" email_so_placement_intro_html: "You have a new order with %{distributor}" From 325b97b6833fddde8e6bf2d42ab8a9111d20cc18 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Wed, 19 May 2021 11:55:24 +0200 Subject: [PATCH 3/3] Add tests around invoice printing in PDF - use PDF Reader to read pdf and get its content - check with we print the payment description information section with the right value --- Gemfile | 1 + Gemfile.lock | 11 +++ spec/features/admin/invoice_print_spec.rb | 103 ++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 spec/features/admin/invoice_print_spec.rb diff --git a/Gemfile b/Gemfile index 8afdfa339b..0664de682b 100644 --- a/Gemfile +++ b/Gemfile @@ -153,6 +153,7 @@ group :test do gem 'test-prof' gem 'webmock' gem 'rails-controller-testing' + gem 'pdf-reader' # See spec/spec_helper.rb for instructions # gem 'perftools.rb' end diff --git a/Gemfile.lock b/Gemfile.lock index 1be6d1112c..56b08eeafc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -47,6 +47,7 @@ PATH GEM remote: https://rubygems.org/ specs: + Ascii85 (1.1.0) actioncable (5.2.6) actionpack (= 5.2.6) nio4r (~> 2.0) @@ -113,6 +114,7 @@ GEM activerecord (>= 4.2) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) + afm (0.2.2) andand (1.3.3) angular-rails-templates (1.1.0) railties (>= 4.2, < 7) @@ -284,6 +286,7 @@ GEM temple (>= 0.8.0) tilt hashdiff (1.0.1) + hashery (2.1.2) highline (2.0.3) i18n (1.8.10) concurrent-ruby (~> 1.0) @@ -384,6 +387,12 @@ GEM xml-simple paypal-sdk-merchant (1.117.2) paypal-sdk-core (~> 0.3.0) + pdf-reader (2.4.2) + Ascii85 (~> 1.0) + afm (~> 0.2.1) + hashery (~> 2.0) + ruby-rc4 + ttfunk pg (1.2.3) power_assert (2.0.0) pry (0.13.1) @@ -571,6 +580,7 @@ GEM thread_safe (0.3.6) tilt (2.0.10) timecop (0.9.4) + ttfunk (1.7.0) tzinfo (1.2.9) thread_safe (~> 0.1) uglifier (4.2.0) @@ -694,6 +704,7 @@ DEPENDENCIES paperclip (~> 3.4.1) paranoia (~> 2.4) paypal-sdk-merchant (= 1.117.2) + pdf-reader pg (~> 1.2.3) pry pry-byebug diff --git a/spec/features/admin/invoice_print_spec.rb b/spec/features/admin/invoice_print_spec.rb new file mode 100644 index 0000000000..d2fff04c4e --- /dev/null +++ b/spec/features/admin/invoice_print_spec.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require "spec_helper" + +feature ' + As an administrator + I want to print a invoice as PDF +', js: false do + include WebHelper + include AuthenticationHelper + + let(:user) { create(:user) } + let(:product) { create(:simple_product) } + let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) } + let(:order_cycle) do + create(:simple_order_cycle, name: 'One', distributors: [distributor], + variants: [product.variants.first]) + end + + let(:order) do + create(:order_with_totals_and_distribution, user: user, distributor: distributor, + order_cycle: order_cycle, state: 'complete', + payment_state: 'balance_due') + end + + describe "that contains right Payment Description at Checkout information" do + let!(:payment_method1) do + create(:stripe_sca_payment_method, distributors: [distributor], description: "description1") + end + let!(:payment_method2) do + create(:stripe_sca_payment_method, distributors: [distributor], description: "description2") + end + + context "with no payment" do + it "do not display the payment description information" do + login_as_admin_and_visit spree.print_admin_order_path(order) + convert_pdf_to_page + expect(page).to have_no_content 'Payment Description at Checkout' + end + end + + context "with one payment" do + let!(:payment1) do + create(:payment, order: order, state: 'completed', payment_method: payment_method1) + end + before do + order.save! + end + + it "display the payment description section" do + login_as_admin_and_visit spree.print_admin_order_path(order) + convert_pdf_to_page + expect(page).to have_content 'Payment Description at Checkout' + expect(page).to have_content 'description1' + end + end + + context "with two payments, and one that failed" do + before do + order.update payments: [] + order.payments << create(:payment, order: order, state: 'completed', + payment_method: payment_method1, created_at: 1.day.ago) + order.payments << create(:payment, order: order, state: 'failed', + payment_method: payment_method2, created_at: 2.days.ago) + order.save! + end + + it "display the payment description section and use the one from the completed payment" do + login_as_admin_and_visit spree.print_admin_order_path(order) + convert_pdf_to_page + expect(page).to have_content 'Payment Description at Checkout' + expect(page).to have_content 'description1' + end + end + + context "with two completed payments" do + before do + order.update payments: [] + order.payments << create(:payment, order: order, state: 'completed', + payment_method: payment_method1, created_at: 2.days.ago) + order.payments << create(:payment, order: order, state: 'completed', + payment_method: payment_method2, created_at: 1.day.ago) + order.save! + end + + it "display the payment description section and use the one from the last payment" do + login_as_admin_and_visit spree.print_admin_order_path(order) + convert_pdf_to_page + expect(page).to have_content 'Payment Description at Checkout' + expect(page).to have_content 'description2' + end + end + end +end + +def convert_pdf_to_page + temp_pdf = Tempfile.new('pdf') + temp_pdf << page.source.force_encoding('UTF-8') + reader = PDF::Reader.new(temp_pdf) + pdf_text = reader.pages.map(&:text) + temp_pdf.close + page.driver.response.instance_variable_set('@body', pdf_text) +end