mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Refresh products cache when exchange is changed or destroyed
This commit is contained in:
@@ -13,6 +13,9 @@ class Exchange < ActiveRecord::Base
|
||||
validates_presence_of :order_cycle, :sender, :receiver
|
||||
validates_uniqueness_of :sender_id, :scope => [:order_cycle_id, :receiver_id, :incoming]
|
||||
|
||||
after_save :refresh_products_cache
|
||||
after_destroy :refresh_products_cache_from_destroy
|
||||
|
||||
accepts_nested_attributes_for :variants
|
||||
|
||||
scope :in_order_cycle, lambda { |order_cycle| where(order_cycle_id: order_cycle) }
|
||||
@@ -75,4 +78,11 @@ class Exchange < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def refresh_products_cache
|
||||
OpenFoodNetwork::ProductsCache.exchange_changed self
|
||||
end
|
||||
|
||||
def refresh_products_cache_from_destroy
|
||||
OpenFoodNetwork::ProductsCache.exchange_destroyed self
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,6 +50,20 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
|
||||
def self.exchange_changed(exchange)
|
||||
if exchange.incoming
|
||||
refresh_incoming_exchanges(Exchange.where(id: exchange))
|
||||
else
|
||||
refresh_outgoing_exchange(exchange)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.exchange_destroyed(exchange)
|
||||
exchange_changed exchange
|
||||
end
|
||||
|
||||
|
||||
def self.enterprise_fee_changed(enterprise_fee)
|
||||
refresh_supplier_fee enterprise_fee
|
||||
refresh_coordinator_fee enterprise_fee
|
||||
@@ -73,19 +87,27 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
|
||||
def self.refresh_supplier_fee(enterprise_fee)
|
||||
outgoing_exchanges = Set.new
|
||||
|
||||
incoming_exchanges(enterprise_fee.exchanges).each do |exchange|
|
||||
outgoing_exchanges.merge outgoing_exchanges_with_variants(exchange.order_cycle, exchange.variant_ids)
|
||||
end
|
||||
|
||||
outgoing_exchanges.each do |exchange|
|
||||
def self.refresh_incoming_exchanges(exchanges)
|
||||
incoming_exchanges(exchanges).map do |exchange|
|
||||
outgoing_exchanges_with_variants(exchange.order_cycle, exchange.variant_ids)
|
||||
end.flatten.uniq.each do |exchange|
|
||||
refresh_cache exchange.receiver, exchange.order_cycle
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.refresh_outgoing_exchange(exchange)
|
||||
if exchange.order_cycle.dated? && !exchange.order_cycle.closed?
|
||||
refresh_cache exchange.receiver, exchange.order_cycle
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.refresh_supplier_fee(enterprise_fee)
|
||||
refresh_incoming_exchanges(enterprise_fee.exchanges)
|
||||
end
|
||||
|
||||
|
||||
def self.refresh_coordinator_fee(enterprise_fee)
|
||||
enterprise_fee.order_cycles.each do |order_cycle|
|
||||
order_cycle_changed order_cycle
|
||||
|
||||
@@ -164,6 +164,71 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
|
||||
describe "when an exchange is changed" do
|
||||
let(:s) { create(:supplier_enterprise) }
|
||||
let(:c) { create(:distributor_enterprise) }
|
||||
let(:d1) { create(:distributor_enterprise) }
|
||||
let(:d2) { create(:distributor_enterprise) }
|
||||
let(:v) { create(:variant) }
|
||||
let(:oc) { create(:open_order_cycle, coordinator: c) }
|
||||
|
||||
describe "incoming exchanges" do
|
||||
let!(:ex1) { create(:exchange, order_cycle: oc, sender: s, receiver: c, incoming: true, variants: [v]) }
|
||||
let!(:ex2) { create(:exchange, order_cycle: oc, sender: c, receiver: d1, incoming: false, variants: [v]) }
|
||||
let!(:ex3) { create(:exchange, order_cycle: oc, sender: c, receiver: d2, incoming: false, variants: []) }
|
||||
|
||||
before { oc.reload }
|
||||
|
||||
it "updates distributions that include one of the supplier's variants" do
|
||||
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).once
|
||||
ProductsCache.exchange_changed ex1
|
||||
end
|
||||
|
||||
it "doesn't update distributions that don't include any of the supplier's variants" do
|
||||
expect(ProductsCache).to receive(:refresh_cache).with(d2, oc).never
|
||||
ProductsCache.exchange_changed ex1
|
||||
end
|
||||
end
|
||||
|
||||
describe "outgoing exchanges" do
|
||||
let!(:ex) { create(:exchange, order_cycle: oc, sender: c, receiver: d1, incoming: false) }
|
||||
|
||||
it "does not update for undated order cycles" do
|
||||
oc.update_attributes! orders_open_at: nil, orders_close_at: nil
|
||||
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).never
|
||||
ProductsCache.exchange_changed ex
|
||||
end
|
||||
|
||||
it "updates for upcoming order cycles" do
|
||||
oc.update_attributes! orders_open_at: 1.week.from_now, orders_close_at: 2.weeks.from_now
|
||||
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).once
|
||||
ProductsCache.exchange_changed ex
|
||||
end
|
||||
|
||||
it "updates for open order cycles" do
|
||||
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).once
|
||||
ProductsCache.exchange_changed ex
|
||||
end
|
||||
|
||||
it "does not update for closed order cycles" do
|
||||
oc.update_attributes! orders_open_at: 2.weeks.ago, orders_close_at: 1.week.ago
|
||||
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).never
|
||||
ProductsCache.exchange_changed ex
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "when an exchange is destroyed" do
|
||||
let(:exchange) { double(:exchange) }
|
||||
|
||||
it "triggers the same update as a change to the exchange" do
|
||||
expect(ProductsCache).to receive(:exchange_changed).with(exchange)
|
||||
ProductsCache.exchange_destroyed exchange
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "when an enterprise fee is changed" do
|
||||
let(:s) { create(:supplier_enterprise) }
|
||||
let(:c) { create(:distributor_enterprise) }
|
||||
|
||||
@@ -91,6 +91,21 @@ describe Exchange do
|
||||
end
|
||||
end
|
||||
|
||||
describe "products caching" do
|
||||
let!(:exchange) { create(:exchange) }
|
||||
|
||||
it "refreshes the products cache on change" do
|
||||
expect(OpenFoodNetwork::ProductsCache).to receive(:exchange_changed).with(exchange)
|
||||
exchange.pickup_time = 'asdf'
|
||||
exchange.save
|
||||
end
|
||||
|
||||
it "refreshes the products cache on destruction" do
|
||||
expect(OpenFoodNetwork::ProductsCache).to receive(:exchange_destroyed).with(exchange)
|
||||
exchange.destroy
|
||||
end
|
||||
end
|
||||
|
||||
describe "scopes" do
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:coordinator) { create(:distributor_enterprise, is_primary_producer: true) }
|
||||
|
||||
Reference in New Issue
Block a user