diff --git a/promotions/lib/solidus_promotions/promotion_migrator.rb b/promotions/lib/solidus_promotions/promotion_migrator.rb index b7b22c691b..f3e9313aa5 100644 --- a/promotions/lib/solidus_promotions/promotion_migrator.rb +++ b/promotions/lib/solidus_promotions/promotion_migrator.rb @@ -61,7 +61,10 @@ def copy_promotion_codes(new_promotion) SELECT solidus_promotions_promotions.id AS promotion_id, solidus_promotions_promotion_code_batches.id AS promotion_code_batch_id, value, spree_promotion_codes.created_at, spree_promotion_codes.updated_at FROM spree_promotion_codes LEFT OUTER JOIN spree_promotion_code_batches ON spree_promotion_code_batches.id = spree_promotion_codes.promotion_code_batch_id - LEFT OUTER JOIN solidus_promotions_promotion_code_batches ON solidus_promotions_promotion_code_batches.base_code = spree_promotion_code_batches.base_code + LEFT OUTER JOIN solidus_promotions_promotion_code_batches + ON solidus_promotions_promotion_code_batches.base_code = spree_promotion_code_batches.base_code + AND solidus_promotions_promotion_code_batches.promotion_id = #{new_promotion.id} + AND solidus_promotions_promotion_code_batches.created_at = spree_promotion_code_batches.created_at INNER JOIN spree_promotions ON spree_promotion_codes.promotion_id = spree_promotions.id INNER JOIN solidus_promotions_promotions ON spree_promotions.id = solidus_promotions_promotions.original_promotion_id WHERE spree_promotion_codes.promotion_id = #{new_promotion.original_promotion_id}; diff --git a/promotions/spec/lib/solidus_promotions/promotion_migrator_spec.rb b/promotions/spec/lib/solidus_promotions/promotion_migrator_spec.rb index 85b9a8e5cb..031586030a 100644 --- a/promotions/spec/lib/solidus_promotions/promotion_migrator_spec.rb +++ b/promotions/spec/lib/solidus_promotions/promotion_migrator_spec.rb @@ -52,6 +52,55 @@ end end + context "when multiple promotions have batches with the same base_code" do + let(:shared_base_code) { "SUVIE" } + let(:shared_time) { Time.current.change(usec: 0) } + let!(:spree_promotion) { create(:promotion) } + let!(:another_spree_promotion) { create(:promotion) } + let!(:first_batch) do + Spree::PromotionCodeBatch.create!( + promotion: spree_promotion, + base_code: shared_base_code, + number_of_codes: 1, + created_at: shared_time, + updated_at: shared_time + ) + end + let!(:second_batch) do + Spree::PromotionCodeBatch.create!( + promotion: another_spree_promotion, + base_code: shared_base_code, + number_of_codes: 1, + created_at: shared_time, + updated_at: shared_time + ) + end + let!(:first_code) do + create( + :promotion_code, + promotion: spree_promotion, + promotion_code_batch: first_batch, + value: "suvie-lgm4gw" + ) + end + let!(:second_code) do + create( + :promotion_code, + promotion: another_spree_promotion, + promotion_code_batch: second_batch, + value: "suvie-abc123" + ) + end + + it "copies each code exactly once without raising a duplicate value error" do + expect { subject }.not_to raise_error + expect(SolidusPromotions::PromotionCode.where(value: [first_code.value, second_code.value]).count).to eq(2) + expect( + SolidusPromotions::PromotionCode.where(value: [first_code.value, second_code.value]).group(:value).count.values + ).to all(eq(1)) + end + end + context "if our rules and actions are missing from the promotion map" do let(:promotion_map) do {