diff --git a/core/app/models/spree/promotion.rb b/core/app/models/spree/promotion.rb index 507e792d4b6..37caef331f1 100644 --- a/core/app/models/spree/promotion.rb +++ b/core/app/models/spree/promotion.rb @@ -205,11 +205,19 @@ def usage_limit_exceeded?(excluded_orders: []) # @param excluded_orders [Array] Orders to exclude from usage count # @return [Integer] usage count def usage_count(excluded_orders: []) - Spree::Adjustment.promotion. - eligible. - in_completed_orders(excluded_orders: excluded_orders, exclude_canceled: true). - where(source_id: actions). - count(:order_id) + if Spree::Config.promotion_system == :adjustments + Spree::Adjustment.promotion. + eligible. + in_completed_orders(excluded_orders: excluded_orders, exclude_canceled: true). + where(source_id: actions). + count(:order_id) + else + discounted_orders. + complete. + where.not(id: [excluded_orders.map(&:id)]). + where.not(spree_orders: { state: :canceled }). + count + end end def line_item_actionable?(order, line_item, promotion_code: nil) diff --git a/core/spec/models/spree/promotion_spec.rb b/core/spec/models/spree/promotion_spec.rb index 9c16ef0168c..938d1eab7a3 100644 --- a/core/spec/models/spree/promotion_spec.rb +++ b/core/spec/models/spree/promotion_spec.rb @@ -357,39 +357,90 @@ end describe "#usage_count" do - let(:promotion) do - FactoryBot.create( - :promotion, - :with_order_adjustment, - code: "discount" - ) - end + context "with legacy promotion system" do + let(:promotion) do + FactoryBot.create( + :promotion, + :with_order_adjustment, + code: "discount" + ) + end - subject { promotion.usage_count } + subject { promotion.usage_count } - context "when the code is applied to a non-complete order" do - let(:order) { FactoryBot.create(:order_with_line_items) } - before { promotion.activate(order: order, promotion_code: promotion.codes.first) } - it { is_expected.to eq 0 } + context "when the code is applied to a non-complete order" do + let(:order) { FactoryBot.create(:order_with_line_items) } + before { promotion.activate(order: order, promotion_code: promotion.codes.first) } + it { is_expected.to eq 0 } + end + context "when the code is applied to a complete order" do + let!(:order) do + FactoryBot.create( + :completed_order_with_promotion, + promotion: promotion + ) + end + context "and the promo is eligible" do + it { is_expected.to eq 1 } + end + context "and the promo is ineligible" do + before { order.adjustments.promotion.update_all(eligible: false) } + it { is_expected.to eq 0 } + end + context "and the order is canceled" do + before { order.cancel! } + it { is_expected.to eq 0 } + it { expect(order.state).to eq 'canceled' } + end + end end - context "when the code is applied to a complete order" do - let!(:order) do + + context "with discount system" do + around do |example| + with_unfrozen_spree_preference_store do + Spree::Config.promotion_system = :discounts + example.run + Spree::Config.promotion_system = :adjustments + end + end + + let(:promotion) do FactoryBot.create( - :completed_order_with_promotion, - promotion: promotion + :promotion, + :with_line_item_adjustment, ) end - context "and the promo is eligible" do - it { is_expected.to eq 1 } - end - context "and the promo is ineligible" do - before { order.adjustments.promotion.update_all(eligible: false) } + + subject { promotion.usage_count } + + context "when the code is applied to a non-complete order" do + let(:order) { FactoryBot.create(:order_with_line_items) } + before do + order.order_promotions << Spree::OrderPromotion.new(promotion_code: promotion.codes.first, promotion: promotion) + order.recalculate + end + it { is_expected.to eq 0 } end - context "and the order is canceled" do - before { order.cancel! } - it { is_expected.to eq 0 } - it { expect(order.state).to eq 'canceled' } + + context "when the code is applied to a complete order" do + let!(:order) { FactoryBot.create(:order_ready_to_complete) } + + before do + order.order_promotions << Spree::OrderPromotion.new(promotion_code: promotion.codes.first, promotion: promotion) + order.recalculate + order.complete! + end + + context "and the promo is eligible" do + it { is_expected.to eq 1 } + end + + context "and the order is canceled" do + before { order.cancel! } + it { is_expected.to eq 0 } + it { expect(order.state).to eq 'canceled' } + end end end end