From 7f65f43fd33832077b49c5e29e57a909d16c8076 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Fri, 27 Oct 2023 10:13:45 +0200 Subject: [PATCH] Backport promotion code batch fix from Solidus Backport Solidus PR 5383 with PR description: When a new promotion with 2.5m new promo codes has created, it just generated about 250k promo codes and then stopped. The PromotionBatch screen this error: Errored: # This PR rescues the exception raised by the Spree::PromotionCode creation and jumps to the next code to save, avoiding stopping the process completely. The PR also adds the ability to restart the PromotionCodeBatch from the latest PromotionCodes created. Co-Authored-By: Daniele Palombo --- .../promotion_code/batch_builder.rb | 11 ++++--- .../promotion_code/batch_builder_spec.rb | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/friendly_promotions/app/models/solidus_friendly_promotions/promotion_code/batch_builder.rb b/friendly_promotions/app/models/solidus_friendly_promotions/promotion_code/batch_builder.rb index f40dcd43..3d913cdc 100644 --- a/friendly_promotions/app/models/solidus_friendly_promotions/promotion_code/batch_builder.rb +++ b/friendly_promotions/app/models/solidus_friendly_promotions/promotion_code/batch_builder.rb @@ -33,7 +33,8 @@ def build_promotion_codes private def generate_random_codes - created_codes = 0 + created_codes = promotion_code_batch.promotion_codes.count + batch_size = @options[:batch_size] while created_codes < number_of_codes @@ -42,13 +43,15 @@ def generate_random_codes new_codes = Array.new(max_codes_to_generate) { generate_random_code }.uniq codes_for_current_batch = get_unique_codes(new_codes) - codes_for_current_batch.each do |value| - PromotionCode.create!( + codes_for_current_batch = codes_for_current_batch.map do |value| + SolidusFriendlyPromotions::PromotionCode.create!( value: value, promotion: promotion, promotion_code_batch: promotion_code_batch ) - end + rescue ActiveRecord::RecordInvalid + nil + end.compact created_codes += codes_for_current_batch.size end end diff --git a/friendly_promotions/spec/models/solidus_friendly_promotions/promotion_code/batch_builder_spec.rb b/friendly_promotions/spec/models/solidus_friendly_promotions/promotion_code/batch_builder_spec.rb index cea4f8a7..0eda9ed9 100644 --- a/friendly_promotions/spec/models/solidus_friendly_promotions/promotion_code/batch_builder_spec.rb +++ b/friendly_promotions/spec/models/solidus_friendly_promotions/promotion_code/batch_builder_spec.rb @@ -104,4 +104,34 @@ end end end + + context "when promotion_code creation returns an error" do + before do + @raise_exception = true + allow(SolidusFriendlyPromotions::PromotionCode).to receive(:create!) do + if @raise_exception + @raise_exception = false + raise(ActiveRecord::RecordInvalid) + else + create(:friendly_promotion_code, promotion: promotion) + end + end + end + + it "creates the correct number of codes anyway" do + subject.build_promotion_codes + expect(promotion.codes.size).to eq(number_of_codes) + end + end + + context "when same promotion_codes are already present" do + let(:number_of_codes) { 50 } + before do + create_list(:friendly_promotion_code, 11, promotion: promotion, promotion_code_batch: code_batch) + end + + it "creates only the missing promotion_codes" do + expect { subject.build_promotion_codes }.to change { promotion.codes.size }.by(39) + end + end end