mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge pull request #11345 from abdellani/support-enabling-invoices-to-individual-users
Support enabling invoices to individual users
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user