From 0ed75992671f097eae8ac51edae7fb156a217f0a Mon Sep 17 00:00:00 2001 From: Mohamed ABDELLANI Date: Tue, 9 May 2023 09:27:55 +0100 Subject: [PATCH] extract methods related to invoices from the order model to the OrderInvoiceComparator --- .../spree/admin/invoices_controller.rb | 5 ++- app/helpers/order_helper.rb | 9 ++++- app/models/spree/order.rb | 29 --------------- app/services/invoice_data_generator.rb | 6 ++- app/services/order_invoice_comparator.rb | 37 ++++++++++++++++++- spec/services/invoice_data_generator_spec.rb | 9 ++++- .../services/order_invoice_comparator_spec.rb | 20 +++++++--- 7 files changed, 71 insertions(+), 44 deletions(-) diff --git a/app/controllers/spree/admin/invoices_controller.rb b/app/controllers/spree/admin/invoices_controller.rb index f5b14e0000..1b86238906 100644 --- a/app/controllers/spree/admin/invoices_controller.rb +++ b/app/controllers/spree/admin/invoices_controller.rb @@ -19,13 +19,14 @@ module Spree def generate @order = Order.find_by(number: params[:order_id]) - if @order.can_generate_new_invoice? + @comparator = OrderInvoiceComparator.new(@order) + if @comparator.can_generate_new_invoice? @order.invoices.create!( date: Time.zone.today, number: @order.next_invoice_number, data: invoice_data ) - elsif @order.can_update_latest_invoice? + elsif @comparator.can_update_latest_invoice? @order.invoices.last.update!( date: Time.zone.today, data: invoice_data diff --git a/app/helpers/order_helper.rb b/app/helpers/order_helper.rb index 467292907c..cdafb9f55b 100644 --- a/app/helpers/order_helper.rb +++ b/app/helpers/order_helper.rb @@ -10,7 +10,12 @@ module OrderHelper end def show_generate_invoice_button?(order) - order.can_generate_new_invoice? || - order.can_update_latest_invoice? + comparator = order_comparator(order) + comparator.can_generate_new_invoice? || + comparator.can_update_latest_invoice? + end + + def order_comparator(order) + OrderInvoiceComparator.new(order) end end diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb index 5ec94ba9cd..87f2562a9d 100644 --- a/app/models/spree/order.rb +++ b/app/models/spree/order.rb @@ -575,39 +575,10 @@ module Spree end end - def can_generate_new_invoice? - return true if invoices.empty? - - invoice_comparator.can_generate_new_invoice? current_state_invoice, invoices.last - end - - def can_update_latest_invoice? - return false if invoices.empty? - - invoice_comparator.can_update_latest_invoice? current_state_invoice, invoices.last - end - def next_invoice_number invoices.count + 1 end - def invoice_comparator - @invoice_comparator ||= OrderInvoiceComparator.new - end - - def current_state_invoice - Invoice.new( - order: self, - data: serialize_for_invoice, - date: Time.zone.today, - number: invoices.count + 1 - ) - end - - def serialize_for_invoice - Invoice::OrderSerializer.new(self).serializable_hash - end - private def deliver_order_confirmation_email diff --git a/app/services/invoice_data_generator.rb b/app/services/invoice_data_generator.rb index 74a485d951..a9bc14cab6 100644 --- a/app/services/invoice_data_generator.rb +++ b/app/services/invoice_data_generator.rb @@ -22,6 +22,10 @@ class InvoiceDataGenerator new_data end + def serialize_for_invoice + Invoice::OrderSerializer.new(order).serializable_hash + end + private def update_order_attributes @@ -57,7 +61,7 @@ class InvoiceDataGenerator end def new_data - @new_data ||= order.serialize_for_invoice + @new_data ||= serialize_for_invoice end def old_data diff --git a/app/services/order_invoice_comparator.rb b/app/services/order_invoice_comparator.rb index e2cb976260..e6ec6cf38e 100644 --- a/app/services/order_invoice_comparator.rb +++ b/app/services/order_invoice_comparator.rb @@ -1,7 +1,15 @@ # frozen_string_literal: true class OrderInvoiceComparator - def can_generate_new_invoice?(current_state_invoice, latest_invoice) + attr :order + + def initialize(order) + @order = order + end + + def can_generate_new_invoice? + return true if invoices.empty? + # We'll use a recursive BFS algorithm to find if the invoice is outdated # the root will be the order # On each node, we'll a list of relevant attributes that will be used on the comparison @@ -9,7 +17,9 @@ class OrderInvoiceComparator invoice_generation_selector) end - def can_update_latest_invoice?(current_state_invoice, latest_invoice) + def can_update_latest_invoice? + return false if invoices.empty? + different?(current_state_invoice.presenter, latest_invoice.presenter, invoice_update_selector) end @@ -51,4 +61,27 @@ class OrderInvoiceComparator end end end + + private + + def current_state_invoice + Invoice.new( + order: order, + data: serialize_for_invoice, + date: Time.zone.today, + number: invoices.count + 1 + ) + end + + def invoices + order.invoices + end + + def latest_invoice + invoices.last + end + + def serialize_for_invoice + InvoiceDataGenerator.new(order).serialize_for_invoice + end end diff --git a/spec/services/invoice_data_generator_spec.rb b/spec/services/invoice_data_generator_spec.rb index 71e2abb391..bedbcb7c93 100644 --- a/spec/services/invoice_data_generator_spec.rb +++ b/spec/services/invoice_data_generator_spec.rb @@ -5,7 +5,12 @@ require 'spec_helper' describe InvoiceDataGenerator do describe '#generate' do let!(:order) { create(:completed_order_with_fees) } - let!(:latest_invoice){ create(:invoice, order: order, data: order.serialize_for_invoice) } + let!(:invoice_data_generator){ InvoiceDataGenerator.new(order) } + let!(:latest_invoice){ + create(:invoice, + order: order, + data: invoice_data_generator.serialize_for_invoice) + } let(:new_invoice_data) { InvoiceDataGenerator.new(order).generate } @@ -74,7 +79,7 @@ describe InvoiceDataGenerator do } it "should generate a new invoice" do - expect(new_invoice_data).to eql order.serialize_for_invoice + expect(new_invoice_data).to eql InvoiceDataGenerator.new(order).serialize_for_invoice end end end diff --git a/spec/services/order_invoice_comparator_spec.rb b/spec/services/order_invoice_comparator_spec.rb index d381ab64dd..778bd769ae 100644 --- a/spec/services/order_invoice_comparator_spec.rb +++ b/spec/services/order_invoice_comparator_spec.rb @@ -5,10 +5,14 @@ require 'spec_helper' describe OrderInvoiceComparator do describe '#can_generate_new_invoice?' do let!(:order) { create(:completed_order_with_fees) } - let!(:invoice){ create(:invoice, order: order, data: order.serialize_for_invoice) } - let(:current_state_invoice){ order.current_state_invoice } + let!(:invoice_data_generator){ InvoiceDataGenerator.new(order) } + let!(:invoice){ + create(:invoice, + order: order, + data: invoice_data_generator.serialize_for_invoice) + } let(:subject) { - OrderInvoiceComparator.new.can_generate_new_invoice?(current_state_invoice, invoice) + OrderInvoiceComparator.new(order).can_generate_new_invoice? } context "changes on the order object" do @@ -47,10 +51,14 @@ describe OrderInvoiceComparator do describe '#can_update_latest_invoice?' do let!(:order) { create(:completed_order_with_fees) } - let!(:invoice){ create(:invoice, order: order, data: order.serialize_for_invoice) } - let(:current_state_invoice){ order.current_state_invoice } + let!(:invoice_data_generator){ InvoiceDataGenerator.new(order) } + let!(:invoice){ + create(:invoice, + order: order, + data: invoice_data_generator.serialize_for_invoice) + } let(:subject) { - OrderInvoiceComparator.new.can_update_latest_invoice?(current_state_invoice, invoice) + OrderInvoiceComparator.new(order).can_update_latest_invoice? } context "changes on the order object" do