diff --git a/lib/open_food_network/proxy_order_syncer.rb b/lib/open_food_network/proxy_order_syncer.rb index 04b2c81c5c..8558defeb8 100644 --- a/lib/open_food_network/proxy_order_syncer.rb +++ b/lib/open_food_network/proxy_order_syncer.rb @@ -17,7 +17,8 @@ module OpenFoodNetwork def sync! return sync_all! if @standing_orders - initialise_proxy_orders! + return initialise_proxy_orders! unless @standing_order.id + create_proxy_orders! remove_obsolete_proxy_orders! end @@ -26,7 +27,7 @@ module OpenFoodNetwork def sync_all! @standing_orders.each do |standing_order| @standing_order = standing_order - initialise_proxy_orders! + create_proxy_orders! remove_obsolete_proxy_orders! end end @@ -37,6 +38,15 @@ module OpenFoodNetwork end end + def create_proxy_orders! + return unless not_closed_in_range_order_cycles.any? + query = "INSERT INTO proxy_orders (standing_order_id, order_cycle_id, updated_at, created_at)" + query << " VALUES #{insert_values}" + query << " ON CONFLICT DO NOTHING" + + ActiveRecord::Base.connection.exec_query(query) + end + def uninitialised_order_cycle_ids not_closed_in_range_order_cycles.pluck(:id) - proxy_orders.map(&:order_cycle_id) end @@ -51,6 +61,13 @@ module OpenFoodNetwork proxy_orders.where('order_cycle_id NOT IN (?)', in_range_order_cycle_ids) end + def insert_values + now = Time.now.utc.iso8601 + not_closed_in_range_order_cycles + .map{ |oc| "(#{standing_order.id},#{oc.id},'#{now}','#{now}')" } + .join(",") + end + def not_closed_in_range_order_cycles in_range_order_cycles.merge(OrderCycle.not_closed) end diff --git a/spec/lib/open_food_network/proxy_order_syncer_spec.rb b/spec/lib/open_food_network/proxy_order_syncer_spec.rb index ac0d3b9913..5729dd367d 100644 --- a/spec/lib/open_food_network/proxy_order_syncer_spec.rb +++ b/spec/lib/open_food_network/proxy_order_syncer_spec.rb @@ -6,8 +6,8 @@ module OpenFoodNetwork let!(:standing_order) { create(:standing_order) } it "raises an error when initialized with an object that is not a StandingOrder or an ActiveRecord::Relation" do - expect{ProxyOrderSyncer.new(standing_order)}.to_not raise_error RuntimeError - expect{ProxyOrderSyncer.new(StandingOrder.where(id: standing_order.id))}.to_not raise_error RuntimeError + expect{ProxyOrderSyncer.new(standing_order)}.to_not raise_error + expect{ProxyOrderSyncer.new(StandingOrder.where(id: standing_order.id))}.to_not raise_error expect{ProxyOrderSyncer.new("something")}.to raise_error RuntimeError end end @@ -31,8 +31,8 @@ module OpenFoodNetwork let!(:po2) { create(:proxy_order, standing_order: standing_order, order_cycle: oc7) } let!(:po3) { create(:proxy_order, standing_order: standing_order, order_cycle: oc8) } - it "performs both initialise and remove actions to rectify proxy orders" do - expect(syncer).to receive(:initialise_proxy_orders!).and_call_original + it "performs both create and remove actions to rectify proxy orders" do + expect(syncer).to receive(:create_proxy_orders!).and_call_original expect(syncer).to receive(:remove_obsolete_proxy_orders!).and_call_original syncer.sync! standing_order.reload @@ -44,9 +44,19 @@ module OpenFoodNetwork end describe "#initialise_proxy_orders!" do - it "adds proxy orders for in-range order cycles that are not already closed" do + let(:new_standing_order) { build(:standing_order, schedule: schedule, begins_at: now + 1.minute, ends_at: now + 2.minutes) } + it "builds proxy orders for in-range order cycles that are not already closed" do + allow(syncer).to receive(:standing_order) { new_standing_order } + expect{syncer.send(:initialise_proxy_orders!)}.to_not change(ProxyOrder, :count).from(0) + expect{new_standing_order.save!}.to change(ProxyOrder, :count).from(0).to(2) + expect(new_standing_order.proxy_orders.map(&:order_cycle_id)).to include oc3.id, oc4.id + end + end + + describe "#create_proxy_orders!" do + it "creates proxy orders for in-range order cycles that are not already closed" do allow(syncer).to receive(:standing_order) { standing_order } - expect{syncer.send(:initialise_proxy_orders!)}.to change(ProxyOrder, :count).from(0).to(2) + expect{syncer.send(:create_proxy_orders!)}.to change(ProxyOrder, :count).from(0).to(2) expect(standing_order.proxy_orders.map(&:order_cycle)).to include oc3, oc4 end end