Extract balance-related methods into module

This model concerns helps us put together this related methods. Although
it doesn't provide any encapsulation yet, it makes a bit easier to
consider them all next time we need to change this implementation
somehow. It's a bit of an illusion but it feels like we are making this
God object model a bit smaller.

It also gives more room for documentation that will aid future devs.
This commit is contained in:
Pau Perez
2021-02-16 16:44:37 +01:00
parent d1fde07535
commit cd60cea5de
4 changed files with 38 additions and 19 deletions

View File

@@ -0,0 +1,32 @@
# frozen_string_literal: true
require 'active_support/concern'
# Contains the methods to compute an order balance form the point of view of the enterprise and not
# the individual shopper.
module Balance
FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze
# Returns the order balance by considering the total as money owed to the order distributor aka.
# the shop, and as a positive balance of said enterprise. If the customer pays it all, they
# distributor and customer are even.
#
# Note however, this is meant to be used only in the context of a single order object. When
# working with a collection of orders, such an index controller action, please consider using
# `app/queries/oustanding_balance.rb` instead so we avoid potential N+1s.
def outstanding_balance
if state.in?(FINALIZED_NON_SUCCESSFUL_STATES)
-payment_total
else
total - payment_total
end
end
def outstanding_balance?
!outstanding_balance.zero?
end
def display_outstanding_balance
Spree::Money.new(outstanding_balance, currency: currency)
end
end

View File

@@ -9,7 +9,9 @@ require 'concerns/order_shipment'
module Spree
class Order < ActiveRecord::Base
prepend OrderShipment
include Checkout
include Balance
checkout_flow do
go_to_state :address
@@ -136,7 +138,6 @@ module Spree
# All the states an order can be in after completing the checkout
FINALIZED_STATES = %w(complete canceled resumed awaiting_return returned).freeze
FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze
scope :finalized, -> { where(state: FINALIZED_STATES) }
@@ -173,10 +174,6 @@ module Spree
self[:currency] || Spree::Config[:currency]
end
def display_outstanding_balance
Spree::Money.new(outstanding_balance, currency: currency)
end
def display_item_total
Spree::Money.new(item_total, currency: currency)
end
@@ -394,18 +391,6 @@ module Spree
Spree::TaxRate.adjust(self)
end
def outstanding_balance
if state.in?(FINALIZED_NON_SUCCESSFUL_STATES)
-payment_total
else
total - payment_total
end
end
def outstanding_balance?
outstanding_balance != 0
end
def name
address = bill_address || ship_address
return unless address

View File

@@ -8,6 +8,9 @@
# cases.
#
# See CompleteOrdersWithBalance or CustomersWithBalance as examples.
#
# Note this query object and `app/models/concerns/balance.rb` should implement the same behavior
# until we find a better way. If you change one, please, change the other too.
class OutstandingBalance
# All the states of a finished order but that shouldn't count towards the balance (the customer
# didn't get the order for whatever reason). Note it does not include complete

View File

@@ -1,7 +1,6 @@
require 'spec_helper'
describe Spree::Order do
describe Balance do
context "#outstanding_balance" do
context 'when orders are in cart state' do
let(:order) { build(:order, total: 100, payment_total: 10, state: 'cart') }