WIP: Move Supplier, Distributor, DistributorSet and ProductDistribution models out of Spree namespace

This commit is contained in:
Rohan Mitchell
2012-10-18 15:46:09 +11:00
parent aa336d9b9f
commit c46019d68c
25 changed files with 147 additions and 159 deletions

View File

@@ -11,8 +11,8 @@ class ApplicationController < ActionController::Base
def load_data_for_sidebar
@suppliers = Spree::Supplier.all
@distributors = Spree::Distributor.with_active_products_on_hand.by_name
@suppliers = Supplier.all
@distributors = Distributor.with_active_products_on_hand.by_name
end
end

View File

@@ -15,7 +15,7 @@ module Spree
private
def load_distributor_set
@distributor_set = Spree::DistributorSet.new :distributors => collection
@distributor_set = DistributorSet.new :distributors => collection
end
def load_countries

View File

@@ -53,7 +53,7 @@ Spree::Admin::ReportsController.class_eval do
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
@distributors = Spree::Distributor.all
@distributors = Distributor.all
@report = OpenFoodWeb::GroupBuyReport.new orders
unless params[:csv]
@@ -67,4 +67,4 @@ Spree::Admin::ReportsController.class_eval do
end
end
end
end

View File

@@ -3,7 +3,7 @@ Spree::OrdersController.class_eval do
after_filter :populate_variant_attributes, :only => :populate
def populate_order_distributor
@distributor = params[:distributor_id].present? ? Spree::Distributor.find(params[:distributor_id]) : nil
@distributor = params[:distributor_id].present? ? Distributor.find(params[:distributor_id]) : nil
if populate_valid? @distributor
order = current_order(true)

31
app/models/distributor.rb Normal file
View File

@@ -0,0 +1,31 @@
class Distributor < ActiveRecord::Base
belongs_to :pickup_address, :foreign_key => 'pickup_address_id', :class_name => 'Spree::Address'
has_many :orders, :class_name => 'Spree::Order'
has_many :product_distributions, :dependent => :destroy
has_many :products, :through => :product_distributions
accepts_nested_attributes_for :pickup_address
validates_presence_of :name, :pickup_address
validates_associated :pickup_address
scope :by_name, order('name')
scope :with_active_products_on_hand, lambda { joins(:products).where('spree_products.deleted_at IS NULL AND spree_products.available_on <= ? AND spree_products.count_on_hand > 0', Time.now).select('distinct(distributors.*)') }
after_initialize :initialize_country
before_validation :set_unused_address_fields
def initialize_country
self.pickup_address ||= Spree::Address.new
self.pickup_address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id]) if self.pickup_address.new_record?
end
def set_unused_address_fields
pickup_address.firstname = pickup_address.lastname = pickup_address.phone = 'unused' if pickup_address.present?
end
def to_param
"#{id}-#{name.parameterize}"
end
end

View File

@@ -0,0 +1,34 @@
# Tableless model to handle updating multiple distributors at once from a
# single form. Used to update next_collection_at field for all distributors in
# admin backend.
class DistributorSet
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :distributors
def initialize(attributes={})
@distributors = Distributor.all
attributes.each do |name, value|
send("#{name}=", value)
end
end
def distributors_attributes=(attributes)
attributes.each do |k, attributes|
# attributes == {:id => 123, :next_collection_at => '...'}
d = @distributors.detect { |d| d.id.to_s == attributes[:id].to_s }
d.assign_attributes(attributes.except(:id))
end
end
def save
distributors.all?(&:save)
end
def persisted?
false
end
end

View File

@@ -0,0 +1,9 @@
class ProductDistribution < ActiveRecord::Base
belongs_to :product, :class_name => 'Spree::Product'
belongs_to :distributor
belongs_to :shipping_method, :class_name => 'Spree::ShippingMethod'
validates_presence_of :product_id, :on => :update
validates_presence_of :distributor_id, :shipping_method_id
validates_uniqueness_of :product_id, :scope => :distributor_id
end

View File

@@ -1,34 +0,0 @@
module Spree
class Distributor < ActiveRecord::Base
self.table_name = 'distributors'
belongs_to :pickup_address, :foreign_key => 'pickup_address_id', :class_name => 'Spree::Address'
has_many :orders
has_many :product_distributions, :dependent => :destroy
has_many :products, :through => :product_distributions
accepts_nested_attributes_for :pickup_address
validates_presence_of :name, :pickup_address
validates_associated :pickup_address
scope :by_name, order('name')
scope :with_active_products_on_hand, lambda { joins(:products).where('spree_products.deleted_at IS NULL AND spree_products.available_on <= ? AND spree_products.count_on_hand > 0', Time.now).select('distinct(distributors.*)') }
after_initialize :initialize_country
before_validation :set_unused_address_fields
def initialize_country
self.pickup_address ||= Address.new
self.pickup_address.country = Country.find_by_id(Spree::Config[:default_country_id]) if self.pickup_address.new_record?
end
def set_unused_address_fields
pickup_address.firstname = pickup_address.lastname = pickup_address.phone = 'unused' if pickup_address.present?
end
def to_param
"#{id}-#{name.parameterize}"
end
end
end

View File

@@ -1,36 +0,0 @@
# Tableless model to handle updating multiple distributors at once from a
# single form. Used to update next_collection_at field for all distributors in
# admin backend.
module Spree
class DistributorSet
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :distributors
def initialize(attributes={})
@distributors = Spree::Distributor.all
attributes.each do |name, value|
send("#{name}=", value)
end
end
def distributors_attributes=(attributes)
attributes.each do |k, attributes|
# attributes == {:id => 123, :next_collection_at => '...'}
d = @distributors.detect { |d| d.id.to_s == attributes[:id].to_s }
d.assign_attributes(attributes.except(:id))
end
end
def save
distributors.all?(&:save)
end
def persisted?
false
end
end
end

View File

@@ -23,7 +23,7 @@ Spree::Product.class_eval do
# Build a product distribution for each distributor
def build_product_distributions
Spree::Distributor.all.each do |distributor|
Distributor.all.each do |distributor|
unless self.product_distributions.find_by_distributor_id distributor.id
self.product_distributions.build(:distributor => distributor)
end

View File

@@ -1,13 +0,0 @@
module Spree
class ProductDistribution < ActiveRecord::Base
self.table_name = 'product_distributions'
belongs_to :product
belongs_to :distributor
belongs_to :shipping_method
validates_presence_of :product_id, :on => :update
validates_presence_of :distributor_id, :shipping_method_id
validates_uniqueness_of :product_id, :scope => :distributor_id
end
end

View File

@@ -1,36 +0,0 @@
module Spree
class Supplier < ActiveRecord::Base
self.table_name = 'suppliers'
has_many :products
belongs_to :address
accepts_nested_attributes_for :address
validates_presence_of :name, :address
validates_associated :address
after_initialize :initialize_country
before_validation :set_unused_address_fields
def has_products_on_hand?
self.products.where('count_on_hand > 0').present?
end
def to_param
"#{id}-#{name.parameterize}"
end
private
def initialize_country
self.address ||= Address.new
self.address.country = Country.find_by_id(Spree::Config[:default_country_id]) if self.address.new_record?
end
def set_unused_address_fields
address.firstname = address.lastname = address.phone = 'unused' if address.present?
end
end
end

33
app/models/supplier.rb Normal file
View File

@@ -0,0 +1,33 @@
class Supplier < ActiveRecord::Base
has_many :products, :class_name => 'Spree::Product'
belongs_to :address, :class_name => 'Spree::Address'
accepts_nested_attributes_for :address
validates_presence_of :name, :address
validates_associated :address
after_initialize :initialize_country
before_validation :set_unused_address_fields
def has_products_on_hand?
self.products.where('count_on_hand > 0').present?
end
def to_param
"#{id}-#{name.parameterize}"
end
private
def initialize_country
self.address ||= Spree::Address.new
self.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id]) if self.address.new_record?
end
def set_unused_address_fields
address.firstname = address.lastname = address.phone = 'unused' if address.present?
end
end

View File

@@ -1,5 +1,5 @@
= f.field_container :supplier do
= f.label :supplier
%br
= f.collection_select(:supplier_id, Spree::Supplier.all, :id, :name, :include_blank => true)
= f.error_message_on :supplier
= f.collection_select(:supplier_id, Supplier.all, :id, :name, :include_blank => true)
= f.error_message_on :supplier

View File

@@ -17,7 +17,7 @@
- order = current_order(false)
- if order.nil? || order.can_change_distributor?
%p Distributor
= select_tag "distributor_id", options_from_collection_for_select([Spree::Distributor.new]+@product.distributors, "id", "name", current_distributor.andand.id)
= select_tag "distributor_id", options_from_collection_for_select([Distributor.new]+@product.distributors, "id", "name", current_distributor.andand.id)
- else
= hidden_field_tag "distributor_id", order.distributor.id
.distributor-fixed= "Your distributor for this order is #{order.distributor.name}"

View File

@@ -8,7 +8,7 @@ class MoveDistributorFromOrderToProduct < ActiveRecord::Migration
end
# Associate all products with the first distributor
distributor = Spree::Distributor.first
distributor = Distributor.first
if distributor
Spree::Product.all.each do |product|
product.distributors << distributor

View File

@@ -2,9 +2,9 @@ class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migrati
def up
# -- Distributors
add_column :distributors, :pickup_address_id, :integer
Spree::Distributor.reset_column_information
Distributor.reset_column_information
Spree::Distributor.all.each do |distributor|
Distributor.all.each do |distributor|
pickup_address = Spree::Address.create!(:firstname => 'unused',
:lastname => 'unused',
:phone => 'unused',
@@ -24,9 +24,9 @@ class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migrati
# -- Suppliers
add_column :suppliers, :address_id, :integer
Spree::Supplier.reset_column_information
Supplier.reset_column_information
Spree::Supplier.all.each do |supplier|
Supplier.all.each do |supplier|
address = Spree::Address.create!(:firstname => 'unused',
:lastname => 'unused',
:phone => 'unused',
@@ -51,9 +51,9 @@ class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migrati
add_column :distributors, :post_code, :string
add_column :distributors, :state_id, :integer
add_column :distributors, :country_id, :integer
Spree::Distributor.reset_column_information
Distributor.reset_column_information
Spree::Distributor.all.each do |distributor|
Distributor.all.each do |distributor|
distributor[:pickup_address] = distributor.pickup_address.address1
distributor.city = distributor.pickup_address.city
distributor.post_code = distributor.pickup_address.zipcode
@@ -71,9 +71,9 @@ class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migrati
add_column :suppliers, :postcode, :string
add_column :suppliers, :state_id, :integer
add_column :suppliers, :country_id, :integer
Spree::Supplier.reset_column_information
Supplier.reset_column_information
Spree::Supplier.all.each do |supplier|
Supplier.all.each do |supplier|
supplier[:address] = supplier.address.address1
supplier.city = supplier.address.city
supplier.post_code = supplier.address.zipcode

View File

@@ -10,7 +10,7 @@ class RenameDistributorsProductsToProductDistributions < ActiveRecord::Migration
# Set default shipping method on all product distributions
sm = Spree::ShippingMethod.first
Spree::ProductDistribution.update_all(:shipping_method_id => sm.id) if sm
ProductDistribution.update_all(:shipping_method_id => sm.id) if sm
end
def down

View File

@@ -60,7 +60,7 @@ end
# -- Suppliers and distributors
unless Spree::Supplier.count > 0
unless Supplier.count > 0
puts "[db:seed] Seeding suppliers and distributors"
3.times { FactoryGirl.create(:supplier) }
@@ -74,19 +74,19 @@ unless Spree::Product.count > 0
FactoryGirl.create(:product,
:name => 'Garlic', :price => 20.00,
:supplier => Spree::Supplier.all[0],
:distributors => [Spree::Distributor.all[0]],
:supplier => Supplier.all[0],
:distributors => [Distributor.all[0]],
:taxons => [Spree::Taxon.find_by_name('Vegetables')])
FactoryGirl.create(:product,
:name => 'Fuji Apple', :price => 5.00,
:supplier => Spree::Supplier.all[1],
:distributors => Spree::Distributor.all,
:supplier => Supplier.all[1],
:distributors => Distributor.all,
:taxons => [Spree::Taxon.find_by_name('Fruit')])
FactoryGirl.create(:product,
:name => 'Beef - 5kg Trays', :price => 50.00,
:supplier => Spree::Supplier.all[2],
:distributors => [Spree::Distributor.all[2]],
:supplier => Supplier.all[2],
:distributors => [Distributor.all[2]],
:taxons => [Spree::Taxon.find_by_name('Meat and Fish')])
end

View File

@@ -1,6 +1,6 @@
module Spree
module ProductFilters
if Spree::Distributor.table_exists?
if Distributor.table_exists?
Spree::Product.scope :distributor_any,
lambda {|*opts|
conds = opts.map {|o| ProductFilters.distributor_filter[:conds][o]}.reject {|c| c.nil?}
@@ -8,8 +8,8 @@ module Spree
}
def ProductFilters.distributor_filter
distributors = Spree::Distributor.all.map(&:name).compact.uniq
conds = Hash[*distributors.map { |d| [d, "#{Spree::Distributor.table_name}.name = '#{d}'"] }.flatten]
distributors = Distributor.all.map(&:name).compact.uniq
conds = Hash[*distributors.map { |d| [d, "#{Distributor.table_name}.name = '#{d}'"] }.flatten]
{ :name => "Group",
:scope => :distributor_any,
:conds => conds,

View File

@@ -2,7 +2,7 @@ require 'faker'
require 'spree/core/testing_support/factories'
FactoryGirl.define do
factory :supplier, :class => Spree::Supplier do
factory :supplier, :class => Supplier do
sequence(:name) { |n| "Supplier #{n}" }
description 'supplier'
long_description '<p>Hello, world!</p><p>This is a paragraph.</p>'
@@ -10,7 +10,7 @@ FactoryGirl.define do
address { Spree::Address.first || FactoryGirl.create(:address) }
end
factory :distributor, :class => Spree::Distributor do
factory :distributor, :class => Distributor do
sequence(:name) { |n| "Distributor #{n}" }
contact 'Mr Turing'
phone '1000100100'
@@ -23,9 +23,9 @@ FactoryGirl.define do
pickup_address { Spree::Address.first || FactoryGirl.create(:address) }
end
factory :product_distribution, :class => Spree::ProductDistribution do
product { |pd| Spree::Product.first || FactoryGirl.create(:product) }
distributor { |pd| Spree::Distributor.first || FactoryGirl.create(:distributor) }
factory :product_distribution, :class => ProductDistribution do
product { |pd| Spree::Product.first || FactoryGirl.create(:product) }
distributor { |pd| Distributor.first || FactoryGirl.create(:distributor) }
shipping_method { |pd| Spree::ShippingMethod.where("name != 'Delivery'").first || FactoryGirl.create(:shipping_method) }
end
@@ -46,7 +46,7 @@ FactoryGirl.modify do
# When this fix has been merged into a version of Spree that we're using, this line can be removed.
sequence(:name) { |n| "Product ##{n} - #{Kernel.rand(9999)}" }
supplier { Spree::Supplier.first || FactoryGirl.create(:supplier) }
supplier { Supplier.first || FactoryGirl.create(:supplier) }
on_hand 3
# before(:create) do |product, evaluator|

View File

@@ -4,7 +4,7 @@ describe Spree::ProductFilters do
context "distributor filter" do
it "provides filtering for all distributors" do
3.times { create(:distributor) }
Spree::ProductFilters.distributor_filter[:labels].should == Spree::Distributor.all.map { |d| [d.name, d.name] }
Spree::ProductFilters.distributor_filter[:labels].should == Distributor.all.map { |d| [d.name, d.name] }
end
end
end

View File

@@ -1,6 +1,6 @@
require 'spec_helper'
describe Spree::ProductDistribution do
describe ProductDistribution do
it "is unique for scope [product, distributor]" do
pd1 = create(:product_distribution)
pd1.should be_valid

View File

@@ -74,7 +74,7 @@ feature %q{
# Then my times should have been saved
flash_message.should == 'Distributor collection times updated.'
Spree::Distributor.all.map { |d| d.next_collection_at }.should == %w(One Two Three)
Distributor.all.map { |d| d.next_collection_at }.should == %w(One Two Three)
end
end

View File

@@ -1,7 +1,7 @@
# Initialise shipping method when created without one, like this:
# create(:product, :distributors => [...])
# In this case, we don't care what the shipping method is, but we need one for validations to pass.
Spree::ProductDistribution.class_eval do
ProductDistribution.class_eval do
before_validation :init_shipping_method
def init_shipping_method