Merge pull request #11345 from abdellani/support-enabling-invoices-to-individual-users

Support enabling invoices to individual users
This commit is contained in:
Konrad
2023-10-08 22:22:33 +02:00
committed by GitHub
9 changed files with 110 additions and 22 deletions

View File

@@ -90,7 +90,8 @@ module Spree
end
def invoice
Spree::OrderMailer.invoice_email(@order.id).deliver_later
Spree::OrderMailer.invoice_email(@order.id,
current_user_id: spree_current_user.id ).deliver_later
flash[:success] = t('admin.orders.invoice_email_sent')
respond_with(@order) { |format|
@@ -99,11 +100,16 @@ module Spree
end
def print
if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
@order = @order.invoices.find(params[:invoice_id]).presenter
if OpenFoodNetwork::FeatureToggle.enabled?(:invoices, spree_current_user)
@order = if params[:invoice_id].present?
@order.invoices.find(params[:invoice_id]).presenter
else
OrderInvoiceGenerator.new(@order).generate_or_update_latest_invoice
@order.invoices.first.presenter
end
end
render_with_wicked_pdf InvoiceRenderer.new.args(@order)
render_with_wicked_pdf InvoiceRenderer.new.args(@order, spree_current_user)
end
private

View File

@@ -31,7 +31,6 @@ module Spree
end
def invoice_links
return [] if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
return [] unless Spree::Config[:enable_invoices?]
[send_invoice_link, print_invoice_link]

View File

@@ -3,10 +3,13 @@
class BulkInvoiceJob < ApplicationJob
include CableReady::Broadcaster
delegate :render, to: ActionController::Base
attr_reader :options
def perform(order_ids, filepath, options = {})
@options = options
orders = sorted_orders(order_ids)
orders.filter!(&:invoiceable?) if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
orders.filter!(&:invoiceable?) if OpenFoodNetwork::FeatureToggle.enabled?(:invoices,
current_user)
orders.each(&method(:generate_invoice))
ensure_directory_exists filepath
@@ -29,13 +32,13 @@ class BulkInvoiceJob < ApplicationJob
end
def generate_invoice(order)
renderer_data = if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
renderer_data = if OpenFoodNetwork::FeatureToggle.enabled?(:invoices, current_user)
OrderInvoiceGenerator.new(order).generate_or_update_latest_invoice
order.invoices.first.presenter
else
order
end
invoice = renderer.render_to_string(renderer_data)
invoice = renderer.render_to_string(renderer_data, current_user)
pdf << CombinePDF.parse(invoice)
end
@@ -58,4 +61,10 @@ class BulkInvoiceJob < ApplicationJob
def pdf
@pdf ||= CombinePDF.new
end
def current_user
return unless options[:current_user_id]
@current_user ||= Spree::User.find(options[:current_user_id])
end
end

View File

@@ -46,16 +46,19 @@ module Spree
end
end
def invoice_email(order_or_order_id)
def invoice_email(order_or_order_id, options = {})
@order = find_order(order_or_order_id)
renderer_data = if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
current_user = if options[:current_user_id].present?
find_user(options[:current_user_id])
end
renderer_data = if OpenFoodNetwork::FeatureToggle.enabled?(:invoices, current_user)
OrderInvoiceGenerator.new(@order).generate_or_update_latest_invoice
@order.invoices.first.presenter
else
@order
end
pdf = InvoiceRenderer.new.render_to_string(renderer_data)
pdf = InvoiceRenderer.new.render_to_string(renderer_data, current_user)
attach_file("invoice-#{@order.number}.pdf", pdf)
I18n.with_locale valid_locale(@order.user) do
@@ -80,5 +83,9 @@ module Spree
def attach_file(filename, file)
attachments[filename] = file if file.present?
end
def find_user(current_user_id)
Spree::User.find(current_user_id)
end
end
end

View File

@@ -37,7 +37,8 @@ module Admin
BulkInvoiceJob.perform_later(
params[:bulk_ids],
"tmp/invoices/#{Time.zone.now.to_i}-#{SecureRandom.hex(2)}.pdf",
channel: SessionChannel.for_request(request)
channel: SessionChannel.for_request(request),
current_user_id: current_user.id
)
morph :nothing
@@ -74,7 +75,7 @@ module Admin
editable_orders.where(id: params[:bulk_ids]).find_each do |o|
next unless o.distributor.can_invoice? && o.invoiceable?
Spree::OrderMailer.invoice_email(o.id).deliver_later
Spree::OrderMailer.invoice_email(o.id, current_user_id: current_user.id).deliver_later
count += 1
end

View File

@@ -1,16 +1,18 @@
# frozen_string_literal: true
class InvoiceRenderer
def initialize(renderer = ApplicationController.new)
def initialize(renderer = ApplicationController.new, user = nil)
@renderer = renderer
@user = user
end
def render_to_string(order)
def render_to_string(order, user = @user)
renderer.instance_variable_set(:@order, order)
renderer.render_to_string_with_wicked_pdf(args(order))
renderer.render_to_string_with_wicked_pdf(args(order, user))
end
def args(order)
def args(order, user = @user)
@user = user
{
pdf: "invoice-#{order.number}.pdf",
template: invoice_template,
@@ -24,7 +26,7 @@ class InvoiceRenderer
attr_reader :renderer
def invoice_template
if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
if OpenFoodNetwork::FeatureToggle.enabled?(:invoices, @user)
invoice_presenter_template
elsif Spree::Config.invoice_style2?
"spree/admin/orders/invoice2"

View File

@@ -61,7 +61,7 @@
%li{ class: adjustments_classes }
= link_to_with_icon 'icon-cogs', t(:adjustments), spree.admin_order_adjustments_url(@order)
- if feature?(:invoices) && @order.can_show_invoice?
- if feature?(:invoices, spree_current_user) && @order.can_show_invoice?
- invoices_classes = "active" if current == 'Invoices'
%li{ class: invoices_classes }
= link_to_with_icon 'icon-cogs', t(:invoices), spree.admin_order_invoices_url(@order)

View File

@@ -238,7 +238,7 @@ describe Spree::OrderMailer do
it "should call the invoice render with order as argument" do
expect(generator).not_to receive(:generate_or_update_latest_invoice)
expect(order).not_to receive(:invoices)
expect(renderer).to receive(:render_to_string).with(order).and_return("invoice")
expect(renderer).to receive(:render_to_string).with(order, nil).and_return("invoice")
expect {
email.deliver_now
}.to_not raise_error
@@ -255,7 +255,7 @@ describe Spree::OrderMailer do
it "should call the invoice renderer with invoice's presenter as argument" do
expect(generator).to receive(:generate_or_update_latest_invoice)
expect(order).to receive(:invoices).and_return([invoice])
expect(renderer).to receive(:render_to_string).with(invoice.presenter)
expect(renderer).to receive(:render_to_string).with(invoice.presenter, nil)
email.deliver_now
end
end

View File

@@ -11,7 +11,9 @@ describe '
let(:user) { create(:user) }
let(:product) { create(:simple_product) }
let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) }
let(:distributor) {
create(:distributor_enterprise, owner: user, charges_sales_tax: true, abn: "123456")
}
let(:order_cycle) do
create(:simple_order_cycle, name: 'One', distributors: [distributor],
variants: [product.variants.first])
@@ -104,6 +106,68 @@ describe '
end
end
describe 'printing invoices' do
context 'when the order has no invoices' do
it 'creates an invoice for the order' do
expect(order.invoices.count).to eq 0
page.find("#links-dropdown", text: "ACTIONS").click
click_link "Print Invoice"
# wait for PDF to open in new window
new_window = windows.last
page.within_window new_window do
expect(order.invoices.count).to eq 1
end
invoice = order.invoices.first
expect(invoice.cancelled).to eq false
expect(invoice.number).to eq 1
end
end
context 'when the order has an invoice' do
let!(:latest_invoice){ create(:invoice, order:, number: 1, cancelled: false) }
context 'changes require regenerating' do
let(:new_note){ 'new note' }
before do
order.update!(note: new_note)
end
it 'updates the lastest invoice for the order' do
expect(order.invoices.count).to eq 1
page.find("#links-dropdown", text: "ACTIONS").click
click_link "Print Invoice"
new_window = windows.last
page.within_window new_window do
expect(order.invoices.count).to eq 1
end
expect(latest_invoice.reload.presenter.note).to eq new_note
expect(latest_invoice.reload.cancelled).to eq false
end
end
context 'changes require generating a new invoice' do
before do
order.line_items.first.update!(quantity: 2)
end
it 'creates a new invoice for the order' do
expect(order.invoices.count).to eq 1
page.find("#links-dropdown", text: "ACTIONS").click
click_link "Print Invoice"
new_window = windows.last
page.within_window new_window do
expect(order.invoices.count).to eq 2
end
expect(latest_invoice.reload.cancelled).to eq true
expect(latest_invoice.presenter.sorted_line_items.first.quantity).to eq 1
new_invoice = order.invoices.first # first invoice is the latest
expect(new_invoice.cancelled).to eq false
expect(new_invoice.number).to eq 2
expect(new_invoice.presenter.sorted_line_items.first.quantity).to eq 2
end
end
end
end
describe 'listing invoices' do
let(:date){ Time.current.to_date }