mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Add incoming boolean field to Exchange, determine exchange direction from this field rather than sender/receiver roles
This commit is contained in:
@@ -15,10 +15,11 @@ class Exchange < ActiveRecord::Base
|
||||
|
||||
accepts_nested_attributes_for :variants
|
||||
|
||||
scope :incoming, joins(:order_cycle).where('exchanges.receiver_id = order_cycles.coordinator_id')
|
||||
scope :outgoing, joins(:order_cycle).where('exchanges.sender_id = order_cycles.coordinator_id')
|
||||
scope :incoming, where(incoming: true)
|
||||
scope :outgoing, where(incoming: false)
|
||||
scope :from_enterprises, lambda { |enterprises| where('exchanges.sender_id IN (?)', enterprises) }
|
||||
scope :to_enterprises, lambda { |enterprises| where('exchanges.receiver_id IN (?)', enterprises) }
|
||||
scope :supplying_to, lambda { |distributor| where('exchanges.incoming OR exchanges.receiver_id = ?', distributor) }
|
||||
scope :with_variant, lambda { |variant| joins(:exchange_variants).where('exchange_variants.variant_id = ?', variant) }
|
||||
scope :with_any_variant, lambda { |variants| joins(:exchange_variants).where('exchange_variants.variant_id IN (?)', variants).select('DISTINCT exchanges.*') }
|
||||
scope :with_product, lambda { |product| joins(:exchange_variants).where('exchange_variants.variant_id IN (?)', product.variants_including_master) }
|
||||
@@ -32,10 +33,6 @@ class Exchange < ActiveRecord::Base
|
||||
exchange
|
||||
end
|
||||
|
||||
def incoming?
|
||||
receiver == order_cycle.coordinator
|
||||
end
|
||||
|
||||
def role
|
||||
incoming? ? 'supplier' : 'distributor'
|
||||
end
|
||||
|
||||
@@ -78,11 +78,11 @@ class OrderCycle < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def suppliers
|
||||
self.exchanges.where(:receiver_id => self.coordinator).map(&:sender).uniq
|
||||
self.exchanges.incoming.map(&:sender).uniq
|
||||
end
|
||||
|
||||
def distributors
|
||||
self.exchanges.where(:sender_id => self.coordinator).map(&:receiver).uniq
|
||||
self.exchanges.outgoing.map(&:receiver).uniq
|
||||
end
|
||||
|
||||
def variants
|
||||
@@ -90,7 +90,7 @@ class OrderCycle < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def distributed_variants
|
||||
self.exchanges.where(:sender_id => self.coordinator).map(&:variants).flatten.uniq
|
||||
self.exchanges.outgoing.map(&:variants).flatten.uniq
|
||||
end
|
||||
|
||||
def variants_distributed_by(distributor)
|
||||
@@ -239,11 +239,10 @@ class OrderCycle < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def exchanges_carrying(variant, distributor)
|
||||
exchanges.to_enterprises([coordinator, distributor]).with_variant(variant)
|
||||
exchanges.supplying_to(distributor).with_variant(variant)
|
||||
end
|
||||
|
||||
def exchanges_supplying(order)
|
||||
variants = order.line_items.map(&:variant)
|
||||
exchanges.to_enterprises([coordinator, order.distributor]).with_any_variant(variants)
|
||||
exchanges.supplying_to(order.distributor).with_any_variant(order.variants)
|
||||
end
|
||||
end
|
||||
|
||||
25
db/migrate/20140324025840_add_incoming_to_exchanges.rb
Normal file
25
db/migrate/20140324025840_add_incoming_to_exchanges.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
class AddIncomingToExchanges < ActiveRecord::Migration
|
||||
class Exchange < ActiveRecord::Base
|
||||
belongs_to :order_cycle
|
||||
belongs_to :receiver, :class_name => 'Enterprise'
|
||||
|
||||
def incoming?
|
||||
receiver == order_cycle.coordinator
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def up
|
||||
add_column :exchanges, :incoming, :boolean, null: false, default: false
|
||||
|
||||
# Initialise based on whether the exchange is going to or coming
|
||||
# from the order cycle coordinator
|
||||
Exchange.all.each do |exchange|
|
||||
exchange.update_attribute :incoming, exchange.incoming?
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :exchanges, :incoming
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20140213003443) do
|
||||
ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
|
||||
create_table "adjustment_metadata", :force => true do |t|
|
||||
t.integer "adjustment_id"
|
||||
@@ -236,8 +236,9 @@ ActiveRecord::Schema.define(:version => 20140213003443) do
|
||||
t.integer "payment_enterprise_id"
|
||||
t.string "pickup_time"
|
||||
t.string "pickup_instructions"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.boolean "incoming", :default => false, :null => false
|
||||
end
|
||||
|
||||
create_table "landing_page_images", :force => true do |t|
|
||||
|
||||
@@ -49,9 +49,8 @@ describe Exchange do
|
||||
let(:coordinator) { create(:distributor_enterprise) }
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:oc) { create(:simple_order_cycle, coordinator: coordinator) }
|
||||
|
||||
let(:incoming_exchange) { oc.exchanges.create! sender: supplier, receiver: coordinator }
|
||||
let(:outgoing_exchange) { oc.exchanges.create! sender: coordinator, receiver: distributor }
|
||||
let(:incoming_exchange) { oc.exchanges.create! sender: supplier, receiver: coordinator, incoming: true }
|
||||
let(:outgoing_exchange) { oc.exchanges.create! sender: coordinator, receiver: distributor, incoming: false }
|
||||
|
||||
it "returns true for incoming exchanges" do
|
||||
incoming_exchange.should be_incoming
|
||||
@@ -78,29 +77,62 @@ describe Exchange do
|
||||
|
||||
describe "scopes" do
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:coordinator) { create(:distributor_enterprise) }
|
||||
let(:coordinator) { create(:distributor_enterprise, is_primary_producer: true) }
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:oc) { create(:simple_order_cycle, coordinator: coordinator) }
|
||||
|
||||
let!(:incoming_exchange) { oc.exchanges.create! sender: supplier, receiver: coordinator }
|
||||
let!(:outgoing_exchange) { oc.exchanges.create! sender: coordinator, receiver: distributor }
|
||||
describe "finding exchanges by direction" do
|
||||
let!(:incoming_exchange) { oc.exchanges.create! sender: supplier, receiver: coordinator, incoming: true }
|
||||
let!(:outgoing_exchange) { oc.exchanges.create! sender: coordinator, receiver: distributor, incoming: false }
|
||||
|
||||
it "finds incoming exchanges" do
|
||||
Exchange.incoming.should == [incoming_exchange]
|
||||
it "finds incoming exchanges" do
|
||||
Exchange.incoming.should == [incoming_exchange]
|
||||
end
|
||||
|
||||
it "finds outgoing exchanges" do
|
||||
Exchange.outgoing.should == [outgoing_exchange]
|
||||
end
|
||||
|
||||
it "correctly determines direction of exchanges between the same enterprise" do
|
||||
incoming_exchange.update_attributes sender: coordinator, incoming: true
|
||||
outgoing_exchange.update_attributes receiver: coordinator, incoming: false
|
||||
Exchange.incoming.should == [incoming_exchange]
|
||||
Exchange.outgoing.should == [outgoing_exchange]
|
||||
end
|
||||
|
||||
it "finds exchanges going to any of a number of enterprises" do
|
||||
Exchange.to_enterprises([coordinator]).should == [incoming_exchange]
|
||||
Exchange.to_enterprises([coordinator, distributor]).sort.should == [incoming_exchange, outgoing_exchange].sort
|
||||
end
|
||||
|
||||
it "finds exchanges coming from any of a number of enterprises" do
|
||||
Exchange.from_enterprises([coordinator]).should == [outgoing_exchange]
|
||||
Exchange.from_enterprises([supplier, coordinator]).sort.should == [incoming_exchange, outgoing_exchange].sort
|
||||
end
|
||||
end
|
||||
|
||||
it "finds outgoing exchanges" do
|
||||
Exchange.outgoing.should == [outgoing_exchange]
|
||||
end
|
||||
describe "finding exchanges supplying to a distributor" do
|
||||
it "returns incoming exchanges" do
|
||||
d = create(:distributor_enterprise)
|
||||
ex = create(:exchange, order_cycle: oc, incoming: true)
|
||||
|
||||
it "finds exchanges going to any of a number of enterprises" do
|
||||
Exchange.to_enterprises([coordinator]).should == [incoming_exchange]
|
||||
Exchange.to_enterprises([coordinator, distributor]).sort.should == [incoming_exchange, outgoing_exchange].sort
|
||||
end
|
||||
oc.exchanges.supplying_to(d).should == [ex]
|
||||
end
|
||||
|
||||
it "finds exchanges coming from any of a number of enterprises" do
|
||||
Exchange.from_enterprises([coordinator]).should == [outgoing_exchange]
|
||||
Exchange.from_enterprises([supplier, coordinator]).sort.should == [incoming_exchange, outgoing_exchange].sort
|
||||
it "returns outgoing exchanges to the distributor" do
|
||||
d = create(:distributor_enterprise)
|
||||
ex = create(:exchange, order_cycle: oc, receiver: d, incoming: false)
|
||||
|
||||
oc.exchanges.supplying_to(d).should == [ex]
|
||||
end
|
||||
|
||||
it "does not return outgoing exchanges to a different distributor" do
|
||||
d1 = create(:distributor_enterprise)
|
||||
d2 = create(:distributor_enterprise)
|
||||
ex = create(:exchange, order_cycle: oc, receiver: d1, incoming: false)
|
||||
|
||||
oc.exchanges.supplying_to(d2).should be_empty
|
||||
end
|
||||
end
|
||||
|
||||
it "finds exchanges with a particular variant" do
|
||||
@@ -167,6 +199,7 @@ describe Exchange do
|
||||
exchange.to_h.should ==
|
||||
{'id' => exchange.id, 'order_cycle_id' => oc.id,
|
||||
'sender_id' => exchange.sender_id, 'receiver_id' => exchange.receiver_id,
|
||||
'incoming' => exchange.incoming,
|
||||
'payment_enterprise_id' => exchange.payment_enterprise_id, 'variant_ids' => exchange.variant_ids.sort,
|
||||
'enterprise_fee_ids' => exchange.enterprise_fee_ids.sort,
|
||||
'pickup_time' => exchange.pickup_time, 'pickup_instructions' => exchange.pickup_instructions,
|
||||
@@ -176,6 +209,7 @@ describe Exchange do
|
||||
it "converts to a hash of core attributes only" do
|
||||
exchange.to_h(true).should ==
|
||||
{'sender_id' => exchange.sender_id, 'receiver_id' => exchange.receiver_id,
|
||||
'incoming' => exchange.incoming,
|
||||
'payment_enterprise_id' => exchange.payment_enterprise_id, 'variant_ids' => exchange.variant_ids.sort,
|
||||
'enterprise_fee_ids' => exchange.enterprise_fee_ids.sort,
|
||||
'pickup_time' => exchange.pickup_time, 'pickup_instructions' => exchange.pickup_instructions}
|
||||
|
||||
@@ -82,7 +82,7 @@ describe OrderCycle do
|
||||
p = create(:product)
|
||||
s = create(:supplier_enterprise)
|
||||
oc = create(:simple_order_cycle)
|
||||
ex = create(:exchange, order_cycle: oc, sender: s, receiver: oc.coordinator)
|
||||
ex = create(:exchange, order_cycle: oc, sender: s, receiver: oc.coordinator, incoming: true)
|
||||
ex.variants << p.master
|
||||
p.reload
|
||||
|
||||
@@ -137,9 +137,9 @@ describe OrderCycle do
|
||||
it "reports its suppliers" do
|
||||
oc = create(:simple_order_cycle)
|
||||
|
||||
e1 = create(:exchange,
|
||||
e1 = create(:exchange, incoming: true,
|
||||
order_cycle: oc, receiver: oc.coordinator, sender: create(:enterprise))
|
||||
e2 = create(:exchange,
|
||||
e2 = create(:exchange, incoming: true,
|
||||
order_cycle: oc, receiver: oc.coordinator, sender: create(:enterprise))
|
||||
|
||||
oc.suppliers.sort.should == [e1.sender, e2.sender].sort
|
||||
@@ -148,9 +148,9 @@ describe OrderCycle do
|
||||
it "reports its distributors" do
|
||||
oc = create(:simple_order_cycle)
|
||||
|
||||
e1 = create(:exchange,
|
||||
e1 = create(:exchange, incoming: false,
|
||||
order_cycle: oc, sender: oc.coordinator, receiver: create(:enterprise))
|
||||
e2 = create(:exchange,
|
||||
e2 = create(:exchange, incoming: false,
|
||||
order_cycle: oc, sender: oc.coordinator, receiver: create(:enterprise))
|
||||
|
||||
oc.distributors.sort.should == [e1.receiver, e2.receiver].sort
|
||||
@@ -182,11 +182,11 @@ describe OrderCycle do
|
||||
@d1 = create(:enterprise)
|
||||
@d2 = create(:enterprise)
|
||||
|
||||
@e0 = create(:exchange,
|
||||
@e0 = create(:exchange, incoming: true,
|
||||
order_cycle: @oc, sender: create(:enterprise), receiver: @oc.coordinator)
|
||||
@e1 = create(:exchange,
|
||||
@e1 = create(:exchange, incoming: false,
|
||||
order_cycle: @oc, sender: @oc.coordinator, receiver: @d1)
|
||||
@e2 = create(:exchange,
|
||||
@e2 = create(:exchange, incoming: false,
|
||||
order_cycle: @oc, sender: @oc.coordinator, receiver: @d2)
|
||||
|
||||
@p0 = create(:simple_product)
|
||||
|
||||
Reference in New Issue
Block a user