From cf08777d9128d9b32a6139541ef48210cf4c7c21 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Thu, 9 Nov 2023 12:07:18 +0100 Subject: [PATCH] Refactor: Extract `Promotion#applicable_line_items` There are now three spots in this code base that need a method to collect the line items that pass all applicable rules for an order and can be discounted. Time to extract. --- .../actions/adjust_line_item_quantity_groups.rb | 10 +--------- .../calculators/distributed_amount.rb | 10 +--------- .../models/solidus_friendly_promotions/promotion.rb | 6 ++++++ .../rules/minimum_quantity.rb | 8 +------- 4 files changed, 9 insertions(+), 25 deletions(-) diff --git a/promotions/app/models/solidus_friendly_promotions/actions/adjust_line_item_quantity_groups.rb b/promotions/app/models/solidus_friendly_promotions/actions/adjust_line_item_quantity_groups.rb index 777bfd5e..095e25d6 100644 --- a/promotions/app/models/solidus_friendly_promotions/actions/adjust_line_item_quantity_groups.rb +++ b/promotions/app/models/solidus_friendly_promotions/actions/adjust_line_item_quantity_groups.rb @@ -58,7 +58,7 @@ def compute_amount(line_item) adjustment_amount = adjustment_amount.abs order = line_item.order - line_items = actionable_line_items(order) + line_items = promotion.applicable_line_items(order) item_units = line_items.sort_by do |line_item| [-line_item.quantity, line_item.id] @@ -78,14 +78,6 @@ def compute_amount(line_item) private - def actionable_line_items(order) - order.discountable_line_items.select do |item| - promotion.rules.select do |rule| - rule.applicable?(item) - end.all? { |rule| rule.eligible?(item) } - end - end - ## # Used specifically for PercentOnLineItem calculator. That calculator uses # `line_item.amount`, however we might not necessarily want to discount the diff --git a/promotions/app/models/solidus_friendly_promotions/calculators/distributed_amount.rb b/promotions/app/models/solidus_friendly_promotions/calculators/distributed_amount.rb index 15451ee2..9f6938bd 100644 --- a/promotions/app/models/solidus_friendly_promotions/calculators/distributed_amount.rb +++ b/promotions/app/models/solidus_friendly_promotions/calculators/distributed_amount.rb @@ -16,7 +16,7 @@ def compute_line_item(line_item) return 0 unless line_item return 0 unless preferred_currency.casecmp(line_item.currency).zero? - distributable_line_items = eligible_line_items(line_item.order) + distributable_line_items = calculable.promotion.applicable_line_items(line_item.order) return 0 unless line_item.in?(distributable_line_items) DistributedAmountsHandler.new( @@ -24,14 +24,6 @@ def compute_line_item(line_item) preferred_amount ).amount(line_item) end - - private - - def eligible_line_items(order) - order.discountable_line_items.select do |line_item| - calculable.promotion.eligible_by_applicable_rules?(line_item) - end - end end end end diff --git a/promotions/app/models/solidus_friendly_promotions/promotion.rb b/promotions/app/models/solidus_friendly_promotions/promotion.rb index 0a86043c..2583f17a 100644 --- a/promotions/app/models/solidus_friendly_promotions/promotion.rb +++ b/promotions/app/models/solidus_friendly_promotions/promotion.rb @@ -155,6 +155,12 @@ def eligible_by_applicable_rules?(promotable, dry_run: false) end.all? end + def applicable_line_items(order) + order.discountable_line_items.select do |line_item| + eligible_by_applicable_rules?(line_item) + end + end + private def apply_automatically_disallowed_with_paths diff --git a/promotions/app/models/solidus_friendly_promotions/rules/minimum_quantity.rb b/promotions/app/models/solidus_friendly_promotions/rules/minimum_quantity.rb index 819b0254..e199ae44 100644 --- a/promotions/app/models/solidus_friendly_promotions/rules/minimum_quantity.rb +++ b/promotions/app/models/solidus_friendly_promotions/rules/minimum_quantity.rb @@ -27,13 +27,7 @@ class MinimumQuantity < PromotionRule # @param order [Spree::Order] the order we want to check eligibility on # @return [Boolean] true if promotion is eligible, false otherwise def eligible?(order) - applicable_line_items = order.line_items.select do |line_item| - promotion.rules.select do |rule| - rule.applicable?(line_item) - end.all? { _1.eligible?(line_item) } - end - - if applicable_line_items.sum(&:quantity) < preferred_minimum_quantity + if promotion.applicable_line_items(order).sum(&:quantity) < preferred_minimum_quantity eligibility_errors.add( :base, eligibility_error_message(:quantity_less_than_minimum, count: preferred_minimum_quantity),