mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Model#scoped is now deprecated. Model#where(nil) in Rails 4 returns the same result as Model#scoped in Rails 3
85 lines
2.3 KiB
Ruby
85 lines
2.3 KiB
Ruby
# This class allows orders with eager-loaded adjustment objects to calculate various adjustment
|
|
# types without triggering additional queries.
|
|
#
|
|
# For example; `order.adjustments.shipping.sum(&:amount)` would normally trigger a new query
|
|
# regardless of whether or not adjustments have been preloaded, as `#shipping` is an adjustment
|
|
# scope, eg; `scope :shipping, where(originator_type: 'Spree::ShippingMethod')`.
|
|
#
|
|
# Here the adjustment scopes are moved to a shared module, and `adjustments.loaded?` is used to
|
|
# check if the objects have already been fetched and initialized. If they have, `order.adjustments`
|
|
# will be an Array, and we can select the required objects without hitting the database. If not, it
|
|
# will fetch the adjustments via their scopes as normal.
|
|
|
|
class OrderAdjustmentsFetcher
|
|
include AdjustmentScopes
|
|
|
|
def initialize(order)
|
|
@order = order
|
|
end
|
|
|
|
def admin_and_handling_total
|
|
admin_and_handling_fees.map(&:amount).sum
|
|
end
|
|
|
|
def payment_fee
|
|
sum_adjustments "payment_fee"
|
|
end
|
|
|
|
def ship_total
|
|
sum_adjustments "shipping"
|
|
end
|
|
|
|
def line_item_adjustments(line_item)
|
|
if adjustments_eager_loaded?
|
|
adjustments.select{ |adjustment| adjustment.source_id == line_item.id }
|
|
else
|
|
adjustments.where(source_id: line_item.id)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :order
|
|
|
|
def adjustments
|
|
order.adjustments
|
|
end
|
|
|
|
def adjustments_eager_loaded?
|
|
adjustments.loaded?
|
|
end
|
|
|
|
def sum_adjustments(scope)
|
|
collect_adjustments(scope).map(&:amount).sum
|
|
end
|
|
|
|
def collect_adjustments(scope)
|
|
if adjustments_eager_loaded?
|
|
adjustment_scope = public_send("#{scope}_scope")
|
|
|
|
adjustments.select do |adjustment|
|
|
match_by_scope(adjustment, adjustment_scope)
|
|
end
|
|
else
|
|
adjustments.where(nil).public_send scope
|
|
end
|
|
end
|
|
|
|
def admin_and_handling_fees
|
|
if adjustments_eager_loaded?
|
|
adjustments.select do |adjustment|
|
|
match_by_scope(adjustment, eligible_scope) &&
|
|
adjustment.originator_type == 'EnterpriseFee' &&
|
|
adjustment.source_type != 'Spree::LineItem'
|
|
end
|
|
else
|
|
adjustments.eligible.
|
|
where("originator_type = ? AND source_type != ?", 'EnterpriseFee', 'Spree::LineItem')
|
|
end
|
|
end
|
|
|
|
def match_by_scope(adjustment, scope)
|
|
adjustment.public_send(scope.keys.first) == scope.values.first
|
|
end
|
|
end
|