diff --git a/core/app/models/spree/order.rb b/core/app/models/spree/order.rb index 85c8621c533..d33a6ab3358 100644 --- a/core/app/models/spree/order.rb +++ b/core/app/models/spree/order.rb @@ -450,7 +450,7 @@ def empty! line_items.destroy_all adjustments.destroy_all shipments.destroy_all - order_promotions.destroy_all + Spree::Bus.publish :order_emptied, order: self recalculate end diff --git a/core/lib/spree/core/engine.rb b/core/lib/spree/core/engine.rb index 58525660adf..b6aa20b36cd 100644 --- a/core/lib/spree/core/engine.rb +++ b/core/lib/spree/core/engine.rb @@ -56,6 +56,7 @@ class Engine < ::Rails::Engine Spree::Bus.clear %i[ + order_emptied order_finalized order_recalculated reimbursement_reimbursed diff --git a/core/spec/models/spree/order_spec.rb b/core/spec/models/spree/order_spec.rb index 7d8d65bb80a..a53ece6279f 100644 --- a/core/spec/models/spree/order_spec.rb +++ b/core/spec/models/spree/order_spec.rb @@ -6,14 +6,6 @@ let(:store) { create(:store) } let(:user) { create(:user, email: "solidus@example.com") } let(:order) { create(:order, user: user, store: store) } - let(:promotion) do - FactoryBot.create( - :promotion, - :with_order_adjustment, - code: "discount" - ) - end - let(:code) { promotion.codes.first } context '#store' do it { is_expected.to respond_to(:store) } @@ -249,15 +241,13 @@ before do create(:line_item, order: order) create(:shipment, order: order) - create(:adjustment, adjustable: order, order: order) - promotion.activate(order: order, promotion_code: code) + create(:adjustment, source: nil, adjustable: order, order: order) order.recalculate # Make sure we are asserting changes expect(order.line_items).not_to be_empty expect(order.shipments).not_to be_empty expect(order.adjustments).not_to be_empty - expect(order.promotions).not_to be_empty expect(order.item_total).not_to eq 0 expect(order.item_count).not_to eq 0 expect(order.shipment_total).not_to eq 0 @@ -269,7 +259,6 @@ expect(order.line_items).to be_empty expect(order.shipments).to be_empty expect(order.adjustments).to be_empty - expect(order.promotions).to be_empty expect(order.item_total).to eq 0 expect(order.item_count).to eq 0 expect(order.shipment_total).to eq 0 diff --git a/legacy_promotions/app/subscribers/spree/order_promotion_subscriber.rb b/legacy_promotions/app/subscribers/spree/order_promotion_subscriber.rb new file mode 100644 index 00000000000..56156a74bb7 --- /dev/null +++ b/legacy_promotions/app/subscribers/spree/order_promotion_subscriber.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Spree + # Clears promotions from an emptied order + class OrderPromotionSubscriber + include Omnes::Subscriber + + handle :order_emptied, + with: :clear_order_promotions, + id: :spree_order_promotion_clear_order_promotions + + # Clears all promotions from the order + # + # @param event [Omnes::UnstructuredEvent] + def clear_order_promotions(event) + order = event[:order] + order.order_promotions.destroy_all + end + end +end diff --git a/legacy_promotions/lib/solidus_legacy_promotions/engine.rb b/legacy_promotions/lib/solidus_legacy_promotions/engine.rb index b643b94d718..2dc0aeb1bf3 100644 --- a/legacy_promotions/lib/solidus_legacy_promotions/engine.rb +++ b/legacy_promotions/lib/solidus_legacy_promotions/engine.rb @@ -42,6 +42,12 @@ class Engine < ::Rails::Engine end end + initializer 'solidus_legacy_promotions.core.pub_sub', after: 'spree.core.pub_sub' do |app| + app.reloader.to_prepare do + Spree::OrderPromotionSubscriber.new.subscribe_to(Spree::Bus) + end + end + initializer "solidus_legacy_promotions.assets" do |app| app.config.assets.precompile << "solidus_legacy_promotions/manifest.js" end diff --git a/legacy_promotions/spec/models/spree/order_spec.rb b/legacy_promotions/spec/models/spree/order_spec.rb index f4f1c1dfb5b..2b24c6a0889 100644 --- a/legacy_promotions/spec/models/spree/order_spec.rb +++ b/legacy_promotions/spec/models/spree/order_spec.rb @@ -3,9 +3,13 @@ require "rails_helper" RSpec.describe Spree::Order do - let(:order) { create(:order) } + subject { described_class.new } + it { is_expected.to respond_to(:order_promotions) } + it { is_expected.to respond_to(:promotions) } context "#apply_shipping_promotions" do + let(:order) { build(:order) } + it "calls out to the Shipping promotion handler" do expect_any_instance_of(Spree::PromotionHandler::Shipping).to( receive(:activate) @@ -16,4 +20,60 @@ order.apply_shipping_promotions end end + + context "empty!" do + let!(:order) { create(:order) } + let(:promotion) do + FactoryBot.create( + :promotion, + :with_order_adjustment, + code: "discount" + ) + end + let(:code) { promotion.codes.first } + + before do + create(:line_item, order: order) + create(:shipment, order: order) + create(:adjustment, adjustable: order, order: order) + promotion.activate(order: order, promotion_code: code) + order.recalculate + + # Make sure we are asserting changes + expect(order.line_items).not_to be_empty + expect(order.shipments).not_to be_empty + expect(order.adjustments).not_to be_empty + expect(order.promotions).not_to be_empty + expect(order.item_total).not_to eq 0 + expect(order.item_count).not_to eq 0 + expect(order.shipment_total).not_to eq 0 + expect(order.adjustment_total).not_to eq 0 + end + + it "clears out line items, adjustments and update totals" do + order.empty! + expect(order.line_items).to be_empty + expect(order.shipments).to be_empty + expect(order.adjustments).to be_empty + expect(order.promotions).to be_empty + expect(order.item_total).to eq 0 + expect(order.item_count).to eq 0 + expect(order.shipment_total).to eq 0 + expect(order.adjustment_total).to eq 0 + end + end + + describe "order deletion" do + let(:order) { create(:order) } + let(:promotion) { create(:promotion) } + + subject { order.destroy } + before do + order.promotions << promotion + end + + it "deletes join table entries when deleting an order" do + expect { subject }.to change { Spree::OrderPromotion.count }.from(1).to(0) + end + end end diff --git a/legacy_promotions/spec/subscribers/spree/order_promotion_subscriber_spec.rb b/legacy_promotions/spec/subscribers/spree/order_promotion_subscriber_spec.rb new file mode 100644 index 00000000000..131b83a6bd7 --- /dev/null +++ b/legacy_promotions/spec/subscribers/spree/order_promotion_subscriber_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Spree::OrderPromotionSubscriber do + let(:bus) { Omnes::Bus.new } + + before do + bus.register(:order_emptied) + + described_class.new.subscribe_to(bus) + end + + describe 'on :order_emptied' do + it 'clears connected promotions' do + promotion = create(:promotion) + order = create(:order) + order.promotions << promotion + expect(order.order_promotions).not_to be_empty + + bus.publish(:order_emptied, order: order) + expect(order.order_promotions).to be_empty + end + end +end