implement OrderInvoiceGenerator service

This commit is contained in:
Mohamed ABDELLANI
2023-07-11 10:42:31 +01:00
parent f24af3feb0
commit 4f6ab69add
3 changed files with 95 additions and 20 deletions

View File

@@ -23,20 +23,7 @@ module Spree
def generate
@order = Order.find_by(number: params[:order_id])
authorize! :invoice, @order
@comparator = OrderInvoiceComparator.new(@order)
if @comparator.can_generate_new_invoice?
@order.invoices.create!(
date: Time.zone.today,
number: @order.invoices.count + 1,
data: invoice_data
)
elsif @comparator.can_update_latest_invoice?
@order.invoices.last.update!(
date: Time.zone.today,
data: invoice_data
)
end
OrderInvoiceGenerator.new(@order).generate_or_update_latest_invoice
redirect_back(fallback_location: spree.admin_dashboard_path)
end
@@ -56,12 +43,6 @@ module Spree
render json: { created: false }, status: :unprocessable_entity
end
end
protected
def invoice_data
@invoice_data ||= InvoiceDataGenerator.new(@order).generate
end
end
end
end

View File

@@ -0,0 +1,34 @@
# frozen_string_literal: true
class OrderInvoiceGenerator
def initialize(order)
@order = order
end
def generate_or_update_latest_invoice
if comparator.can_generate_new_invoice?
order.invoices.create!(
date: Time.zone.today,
number: order.invoices.count + 1,
data: invoice_data
)
elsif comparator.can_update_latest_invoice?
order.invoices.last.update!(
date: Time.zone.today,
data: invoice_data
)
end
end
private
attr_reader :order
def comparator
@comparator ||= OrderInvoiceComparator.new(order)
end
def invoice_data
@invoice_data ||= InvoiceDataGenerator.new(order).generate
end
end

View File

@@ -0,0 +1,60 @@
# frozen_string_literal: true
require 'spec_helper'
describe OrderInvoiceGenerator do
let!(:order) { create(:completed_order_with_fees) }
let!(:invoice_data_generator){ InvoiceDataGenerator.new(order) }
let!(:latest_invoice){
create(:invoice,
order:,
data: invoice_data_generator.serialize_for_invoice)
}
let(:instance) { described_class.new(order) }
let(:comparator){ double("OrderInvoiceComparator") }
before do
allow(instance).to receive(:comparator).and_return(comparator)
end
describe "#generate_or_update_latest_invoice" do
let(:subject) { instance.generate_or_update_latest_invoice }
context "when can generate new invoice" do
before do
expect(comparator).to receive(:can_generate_new_invoice?).and_return(true)
end
it "should create a new invoice" do
expect(instance).to receive(:invoice_data)
expect{ subject }.to change{ order.invoices.count }.by(1)
expect(order.invoices.order('created_at desc').first.number).to eq(2)
end
end
context "can update latest invoice" do
before do
allow(comparator).to receive(:can_generate_new_invoice?).and_return(false)
allow(comparator).to receive(:can_update_latest_invoice?).and_return(true)
order.update!(note: "This is an updated note")
end
it "should update the latest invoice" do
expect{ subject }.to change{ latest_invoice.reload.data }
.and change{ order.invoices.count }.by(0)
end
end
context "when can't generate new invoice or update latest invoice" do
before do
allow(comparator).to receive(:can_generate_new_invoice?).and_return(false)
allow(comparator).to receive(:can_update_latest_invoice?).and_return(false)
end
it "should not create or update invoices" do
expect(instance).not_to receive(:invoice_data)
expect{ subject }.to change{ order.invoices.count }.by(0)
end
end
end
end