spree_wholesale 0.40.0.beta4.1 → 0.40.0.beta4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/README.md +4 -4
  2. data/Rakefile +81 -17
  3. data/app/controllers/admin/base_controller_decorator.rb +11 -0
  4. data/app/controllers/admin/wholesalers_controller.rb +70 -0
  5. data/app/controllers/checkout_controller_decorator.rb +15 -0
  6. data/app/controllers/wholesalers_controller.rb +5 -0
  7. data/app/models/ability.rb +71 -0
  8. data/app/models/{application_controller_decorator.rb → application_helper_decorator.rb} +1 -2
  9. data/app/models/country_decorator.rb +3 -0
  10. data/app/models/order_decorator.rb +0 -2
  11. data/app/models/spree_current_order_decorator.rb +0 -13
  12. data/app/models/user_decorator.rb +5 -0
  13. data/app/models/wholesaler.rb +45 -0
  14. data/app/views/admin/hooks/_wholesale_tab.html.erb +1 -0
  15. data/app/views/admin/wholesalers/_form.html.erb +129 -0
  16. data/app/views/admin/wholesalers/_user_options.html.erb +6 -0
  17. data/app/views/admin/wholesalers/edit.html.erb +13 -0
  18. data/app/views/admin/wholesalers/index.html.erb +88 -0
  19. data/app/views/admin/wholesalers/new.html.erb +13 -0
  20. data/app/views/admin/wholesalers/show.html.erb +68 -0
  21. data/app/views/hooks/_wholesale_static_content.html.erb +3 -0
  22. data/app/views/shared/_address_form.html.erb +77 -0
  23. data/app/views/shared/_store_menu.html.erb +4 -0
  24. data/app/views/wholesalers/_fields.html.erb +91 -0
  25. data/app/views/wholesalers/index.html.erb +21 -0
  26. data/app/views/wholesalers/new.html.erb +8 -0
  27. data/config/locales/en.yml +45 -1
  28. data/config/routes.rb +11 -0
  29. data/db/migrate/install_spree_wholesale.rb +36 -0
  30. data/lib/spree_wholesale/wholesaler_controller.rb +122 -0
  31. data/lib/spree_wholesale_hooks.rb +4 -0
  32. data/lib/tasks/install.rake +0 -14
  33. data/lib/tasks/spree_wholesale.rake +11 -2
  34. data/public/stylesheets/admin/wholesalers.css +14 -0
  35. metadata +28 -6
  36. data/db/migrate/add_wholesale_price_to_variants.rb +0 -9
  37. data/db/migrate/add_wholesale_to_orders.rb +0 -9
data/README.md CHANGED
@@ -19,7 +19,7 @@ Install from the source:
19
19
  Or install the (beta) gem:
20
20
 
21
21
  gem install spree_wholesale --pre
22
- echo "gem 'spree_wholesale', '0.40.0.beta4'" >> Gemfile
22
+ echo "gem 'spree_wholesale', '0.40.0.beta4.1'" >> Gemfile
23
23
 
24
24
  rake spree_wholesale:install
25
25
  rake db:migrate
@@ -51,7 +51,7 @@ To create a demo of SpreeWholesaleExample
51
51
  cd spree_wholesale_example
52
52
 
53
53
  echo "gem 'spree', '0.40.0'" >> Gemfile
54
- echo "gem 'spree_wholesale', '0.40.0.beta4'" >> Gemfile
54
+ echo "gem 'spree_wholesale', '0.40.0.beta4.1'" >> Gemfile
55
55
  rm public/index.html
56
56
 
57
57
  bundle install
@@ -65,7 +65,7 @@ To create a demo of SpreeWholesaleExample
65
65
 
66
66
  or shorthand:
67
67
 
68
- rails new spree_wholesale_example; cd spree_wholesale_example; echo "gem 'spree', '0.40.0'" >> Gemfile; echo "gem 'spree_wholesale', '0.40.0.beta4'" >> Gemfile; rm public/index.html
68
+ rails new spree_wholesale_example; cd spree_wholesale_example; echo "gem 'spree', '0.40.0'" >> Gemfile; echo "gem 'spree_wholesale', '0.40.0.beta4.1'" >> Gemfile; rm public/index.html
69
69
  rake spree:install spree_wholesale:install db:migrate db:seed spree_wholesale:create_role
70
70
 
71
71
  If you want sample data:
@@ -90,7 +90,7 @@ Then finish by booting up the rails server:
90
90
 
91
91
  All in one swoop:
92
92
 
93
- rails new spree_wholesale_example; cd spree_wholesale_example; echo "gem 'spree', '0.40.0'" >> Gemfile; echo "gem 'spree_wholesale', '0.40.0.beta4'" >> Gemfile; rm public/index.html; bundle install; rake spree:install spree_wholesale:install db:migrate db:seed spree_wholesale:create_role spree_sample:install db:sample spree_wholesale:assume_wholesale_prices; echo "@import url('wholesale.css');"|cat - public/stylesheets/screen.css > /tmp/out && mv /tmp/out public/stylesheets/screen.css; rails s
93
+ rails new spree_wholesale_example; cd spree_wholesale_example; echo "gem 'spree', '0.40.0'" >> Gemfile; echo "gem 'spree_wholesale', '0.40.0.beta4.1'" >> Gemfile; rm public/index.html; bundle install; rake spree:install spree_wholesale:install db:migrate db:seed spree_wholesale:create_role spree_sample:install db:sample spree_wholesale:assume_wholesale_prices; echo "@import url('wholesale.css');"|cat - public/stylesheets/screen.css > /tmp/out && mv /tmp/out public/stylesheets/screen.css; rails s
94
94
 
95
95
 
96
96
  To do the same as above but install from the source instead, run:
data/Rakefile CHANGED
@@ -5,33 +5,97 @@ require 'rake/packagetask'
5
5
  require 'rake/gempackagetask'
6
6
 
7
7
 
8
+ root = ENV["RAILS_ROOT"] || File.expand_path('../spec/test_app', __FILE__)
9
+
10
+ env = File.join(root, 'config', 'environment.rb')
11
+
12
+ puts "(Rails Root: #{root})"
13
+
14
+
8
15
  spec = eval(File.read('spree_wholesale.gemspec'))
9
- env = File.expand_path('../../config/environment', __FILE__)
10
16
 
11
17
  Rake::GemPackageTask.new(spec) do |p|
12
18
  p.gem_spec = spec
13
19
  end
14
20
 
15
21
 
16
- desc "Test Spree Wholesale Extension"
17
- task :test_extension do
18
-
19
- require env
20
- require File.expand_path('../test/test_helper', __FILE__)
22
+ namespace :spree_wholesale do
23
+ desc "Test Spree Wholesale Extension"
24
+ task :test do
25
+
26
+ require env
27
+ require File.expand_path('../test/test_helper', __FILE__)
28
+
29
+ Dir["test/**/*.rb"].reject{|file| file.match(/test_helper/) != nil }.each do |file|
30
+ puts "Loading #{file}"
31
+ load file
32
+ end
21
33
 
22
- Dir["test/**/*.rb"].reject{|file| file.match(/test_helper/) != nil }.each do |file|
23
- puts "Loading #{file}"
24
- load file
25
34
  end
26
-
27
35
  end
28
36
 
37
+ #
38
+ #
39
+ #if File.exists?(env)
40
+ # desc "Default Task"
41
+ # task :default => [ :test_extension ]
42
+ #else
43
+ # desc "Default Task"
44
+ # task :default => []
45
+ # puts "environment.rb not found! Try modifying the path to your rails application."
46
+ #end
47
+
48
+ desc "Default Task"
49
+ task :default => [ :test_extension ]
50
+
51
+
52
+
53
+
54
+ # TODO: pull in the spree/core/Rakefile bits that set up for testing
55
+ desc "Regenerates a Rails 3 app for testing"
56
+ task :test_app do
57
+ # TODO - this path requires a certain directory structure -- need
58
+ # to think about how to refactor
59
+ require '../spree/lib/generators/spree/test_app_generator'
60
+ class WishlistTestAppGenerator < Spree::Generators::TestAppGenerator
61
+ def tweak_gemfile
62
+ append_file "Gemfile" ,
63
+ <<-gems
29
64
 
30
- if File.exists?(env)
31
- desc "Default Task"
32
- task :default => [ :test_extension ]
33
- else
34
- desc "Default Task"
35
- task :default => []
36
- puts "environment.rb not found! Try modifying the path to your rails application."
65
+ gem 'spree_core', '>=0.40.0'
66
+ gem 'spree_auth', '>=0.40.0'
67
+ gem 'spree_wholesale', :path => "#{File.dirname(__FILE__)}"
68
+
69
+ gems
70
+ end
71
+
72
+ def install_spree_gems
73
+ inside "test_app" do
74
+ run 'rake spree_core:install'
75
+ run 'rake spree_auth:install'
76
+ run 'rake spree_wholesale:install'
77
+ end
78
+ end
79
+
80
+ # def install_spree_auth
81
+ # inside "test_app" do
82
+ # run 'rake spree_auth:install'
83
+ # end
84
+ # ends
85
+
86
+ def migrate_db
87
+ run_migrations
88
+ end
89
+ end
90
+ WishlistTestAppGenerator.start
37
91
  end
92
+
93
+ namespace :test_app do
94
+ desc 'Rebuild test database'
95
+ task :rebuild_db do
96
+ system("cd spec/test_app && rake db:drop db:migrate RAILS_ENV=test")
97
+ end
98
+ end
99
+
100
+
101
+
@@ -0,0 +1,11 @@
1
+ [Spree::BaseController, Admin::BaseController].each do |controller|
2
+
3
+ controller.class_eval do
4
+
5
+ def default_country
6
+ Country.find Spree::Config[:default_country_id]
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,70 @@
1
+ class Admin::WholesalersController < Admin::BaseController
2
+
3
+ resource_controller
4
+
5
+ include SpreeWholesale::WholesalerController
6
+
7
+ before_filter :check_json_authenticity, :only => :index
8
+
9
+ index.response do |wants|
10
+ wants.html { render :action => :index }
11
+ wants.json { render :json => json_data }
12
+ end
13
+
14
+ destroy.success.wants.js { render_js_for_destroy }
15
+
16
+
17
+ before_filter :approval_setup, :only => [ :approve, :reject ]
18
+
19
+
20
+ def approve
21
+ return redirect_to request.referer, :flash => { :error => "Wholesaler is already active." } if @wholesaler.active?
22
+ @wholesaler.activate!
23
+ redirect_to request.referer, :flash => { :notice => "Wholesaler was successfully approved." }
24
+ end
25
+
26
+ def reject
27
+ return redirect_to request.referer, :flash => { :error => "Wholesaler is already rejected." } unless @wholesaler.active?
28
+ @wholesaler.deactivate!
29
+ redirect_to request.referer, :flash => { :notice => "Wholesaler was successfully rejected." }
30
+ end
31
+
32
+ def approval_setup
33
+ @wholesaler = Wholesaler.find(params[:id])
34
+ @role = Role.find_by_name("wholesaler")
35
+ end
36
+
37
+
38
+ private
39
+
40
+ # Allow different formats of json data to suit different ajax calls
41
+ def json_data
42
+ json_format = params[:json_format] or 'default'
43
+ case json_format
44
+ when 'basic'
45
+ collection.map {|u| {'id' => u.id, 'name' => u.email}}.to_json
46
+ else
47
+ collection.to_json(:include =>
48
+ {:bill_address => {:include => [:state, :country]},
49
+ :ship_address => {:include => [:state, :country]}})
50
+ end
51
+ end
52
+
53
+ def collection
54
+ return @collection if @collection.present?
55
+ unless request.xhr?
56
+ @search = Wholesaler.searchlogic(params[:search])
57
+
58
+ #set order by to default or form result
59
+ @search.order ||= "ascend_by_email"
60
+
61
+ @collection = @search.do_search.includes(:user => [:roles]).paginate(:per_page => Spree::Config[:admin_products_per_page], :page => params[:page])
62
+
63
+ #scope = scope.conditions "lower(email) = ?", @filter.email.downcase unless @filter.email.blank?
64
+ else
65
+ @collection = Wholesaler.includes(:user => [:roles], :bill_address => [:state, :country],
66
+ :ship_address => [:state, :country]).where("wholesalers.company like :search",
67
+ {:search => "#{params[:q].strip}%"}).limit(params[:limit] || 100)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,15 @@
1
+ CheckoutController.instance_eval do
2
+
3
+ before_filter :get_addresses
4
+
5
+ end
6
+
7
+ CheckoutController.class_eval do
8
+
9
+ def get_addresses
10
+ return unless current_user.has_role?("wholesaler") && !current_user.wholesaler.nil?
11
+ @order.bill_address = current_user.wholesaler.bill_address
12
+ @order.ship_address = current_user.wholesaler.ship_address
13
+ end
14
+
15
+ end
@@ -0,0 +1,5 @@
1
+ class WholesalersController < Spree::BaseController
2
+
3
+ include SpreeWholesale::WholesalerController
4
+
5
+ end
@@ -0,0 +1,71 @@
1
+ # Implementation class for Cancan gem. Instead of overriding this class, consider adding new permissions
2
+ # using the special +register_ability+ method which allows extensions to add their own abilities.
3
+ #
4
+ # See http://github.com/ryanb/cancan for more details on cancan.
5
+ class Ability
6
+ include CanCan::Ability
7
+
8
+ class_attribute :abilities
9
+ self.abilities = Set.new
10
+
11
+ # Allows us to go beyond the standard cancan initialize method which makes it difficult for engines to
12
+ # modify the default +Ability+ of an application. The +ability+ argument must be a class that includes
13
+ # the +CanCan::Ability+ module. The registered ability should behave properly as a stand-alone class
14
+ # and therefore should be easy to test in isolation.
15
+ def self.register_ability(ability)
16
+ self.abilities.add(ability)
17
+ end
18
+
19
+ def initialize(user)
20
+ self.clear_aliased_actions
21
+
22
+ # override cancan default aliasing (we don't want to differentiate between read and index)
23
+ alias_action :edit, :to => :update
24
+ alias_action :new, :to => :create
25
+ alias_action :new_action, :to => :create
26
+ alias_action :show, :to => :read
27
+
28
+ user ||= User.new
29
+ if user.has_role? 'admin'
30
+ can :manage, :all
31
+ else
32
+ #############################
33
+ can :read, User do |resource|
34
+ resource == user
35
+ end
36
+ can :update, User do |resource|
37
+ resource == user
38
+ end
39
+ can :create, User
40
+ #############################
41
+ can :read, Order do |order, token|
42
+ order.user == user || order.token && token == order.token
43
+ end
44
+ can :update, Order do |order, token|
45
+ order.user == user || order.token && token == order.token
46
+ end
47
+ can :create, Order
48
+ #############################
49
+ can :read, Product
50
+ can :index, Product
51
+ #############################
52
+ can :read, Taxon
53
+ can :index, Taxon
54
+ #############################
55
+ can :index, Wholesaler
56
+ can :new, Wholesaler
57
+ can :create, Wholesaler
58
+ can :read, Wholesaler do |resource|
59
+ resource.user == user
60
+ end
61
+ #############################
62
+ end
63
+
64
+ #include any abilities registered by extensions, etc.
65
+ Ability.abilities.each do |clazz|
66
+ ability = clazz.send(:new, user)
67
+ @can_definitions = abilities + ability.send(:abilities)
68
+ end
69
+
70
+ end
71
+ end
@@ -2,7 +2,6 @@ ApplicationHelper.module_eval do
2
2
 
3
3
  def wholesaler_signed_in?
4
4
  current_user && current_user.has_role?("wholesaler")
5
- end
6
-
5
+ end
7
6
 
8
7
  end
@@ -0,0 +1,3 @@
1
+ Country.instance_eval do
2
+ has_many :states, :order => "name ASC"
3
+ end
@@ -12,7 +12,6 @@ Order.class_eval do
12
12
  end
13
13
 
14
14
  def to_fullsale!
15
- puts "TO FULLSALE"
16
15
  self.wholesale = false
17
16
  set_line_item_prices(:price)
18
17
  update!
@@ -20,7 +19,6 @@ Order.class_eval do
20
19
  end
21
20
 
22
21
  def to_wholesale!
23
- puts "TO WHOLESALE"
24
22
  self.wholesale = true
25
23
  set_line_item_prices(:wholesale_price)
26
24
  update!
@@ -1,16 +1,3 @@
1
- #Spree::CurrentOrder.module_eval do
2
- #
3
- # def before_save_new_order
4
- #
5
- # if current_user
6
- # @current_order.user ||= current_user
7
- # @current_order.wholesale = current_user.has_role?("wholesaler")
8
- # end
9
- #
10
- # end
11
- #
12
- #end
13
-
14
1
  module Spree
15
2
  module CurrentOrder
16
3
 
@@ -0,0 +1,5 @@
1
+ User.instance_eval do
2
+
3
+ has_one :wholesaler
4
+
5
+ end
@@ -0,0 +1,45 @@
1
+ class Wholesaler < ActiveRecord::Base
2
+
3
+ belongs_to :user
4
+
5
+ belongs_to :ship_address, :foreign_key => "shipping_address_id", :class_name => "Address"
6
+ belongs_to :bill_address, :foreign_key => "billing_address_id", :class_name => "Address"
7
+
8
+ validates_presence_of [ :company, :buyer_contact, :manager_contact, :phone, :taxid ]
9
+
10
+ validates_each :user_id, :billing_address_id, :shipping_address_id do |record,attr,value|
11
+ record.errors.add attr, 'must not contain any errors.' if value.to_i == 0
12
+ end
13
+
14
+ delegate_belongs_to :user, :roles
15
+ delegate_belongs_to :user, :email
16
+
17
+ def self.term_options
18
+ %(Net 10, Net 15, Net 30, COD, Credit Card).split(", ")
19
+ end
20
+
21
+ def activate!
22
+ get_wholesale_role
23
+ return false if user.roles.include?(@role)
24
+ user.roles << @role
25
+ user.save
26
+ end
27
+
28
+ def deactivate!
29
+ get_wholesale_role
30
+ return false unless user.roles.include?(@role)
31
+ user.roles.delete(@role)
32
+ user.save
33
+ end
34
+
35
+ def active?
36
+ user.has_role? "wholesaler"
37
+ end
38
+
39
+ private
40
+
41
+ def get_wholesale_role
42
+ @role = Role.find_by_name("wholesaler")
43
+ end
44
+
45
+ end
@@ -0,0 +1 @@
1
+ <%= tab :wholesalers %>
@@ -0,0 +1,129 @@
1
+ <%- locals = {:f => f} %>
2
+
3
+ <div class="leftie">
4
+ <%= hook :admin_wholesaler_form_fields, locals do %>
5
+
6
+ <%= render "shared/error_messages", :target => @wholesaler %>
7
+
8
+ <fieldset>
9
+ <legend>Wholesaler Details:</legend>
10
+
11
+ <%= f.field_container :company do %>
12
+ <%= f.label :company, t(".company") %><br />
13
+ <%= f.text_field :company %>
14
+ <%= error_message_on :wholesaler, :company %>
15
+ <% end %>
16
+
17
+ <%= f.field_container :buyer_contact do %>
18
+ <%= f.label :buyer_contact, t(".buyer_contact") %><br />
19
+ <%= f.text_field :buyer_contact %>
20
+ <%= error_message_on :wholesaler, :buyer_contact %>
21
+ <% end %>
22
+
23
+ <%= f.field_container :manager_contact do %>
24
+ <%= f.label :manager_contact, t(".manager_contact") %><br />
25
+ <%= f.text_field :manager_contact %>
26
+ <%= error_message_on :wholesaler, :manager_contact %>
27
+ <% end %>
28
+
29
+ <%= f.field_container :phone do %>
30
+ <%= f.label :phone, t(".phone") %><br />
31
+ <%= f.text_field :phone %>
32
+ <%= error_message_on :wholesaler, :phone %>
33
+ <% end %>
34
+
35
+ <%= f.field_container :fax do %>
36
+ <%= f.label :fax, t(".fax") %><br />
37
+ <%= f.text_field :fax %>
38
+ <%= error_message_on :wholesaler, :fax %>
39
+ <% end %>
40
+
41
+ <%= f.field_container :resale_number do %>
42
+ <%= f.label :resale_number, t(".resale_number") %><br />
43
+ <%= f.text_field :resale_number %>
44
+ <%= error_message_on :wholesaler, :resale_number %>
45
+ <% end %>
46
+
47
+ <%= f.field_container :taxid do %>
48
+ <%= f.label :taxid, t(".taxid") %><br />
49
+ <%= f.text_field :taxid %>
50
+ <%= error_message_on :wholesaler, :taxid %>
51
+ <% end %>
52
+
53
+ <%= f.field_container :web_address do %>
54
+ <%= f.label :web_address, t(".web_address") %><br />
55
+ <%= f.text_field :web_address %>
56
+ <%= error_message_on :wholesaler, :web_address %>
57
+ <% end %>
58
+
59
+ <%= f.field_container :terms do %>
60
+ <%= f.label :terms, t(".terms") %><br />
61
+ <%= f.text_field :terms %>
62
+ <%= error_message_on :wholesaler, :terms %>
63
+ <% end %>
64
+
65
+ <%= f.field_container :notes do %>
66
+ <%= f.label :notes, t(".notes") %><br />
67
+ <%= f.text_area :notes %>
68
+ <%= error_message_on :wholesaler, :notes %>
69
+ <% end %>
70
+
71
+ </fieldset>
72
+ <% end %>
73
+
74
+
75
+ <fieldset>
76
+ <legend>User Details:</legend>
77
+ <% if @user.new_record? %>
78
+ <%= fields_for :user, @user do |uf| %>
79
+ <%= render "shared/error_messages", :target => @user %>
80
+ <%= render 'admin/users/form', :f => uf %>
81
+ <% end %>
82
+ <% else %>
83
+ <p>
84
+ <b>User Id:</b>
85
+ <%= link_to @user.id, admin_user_path(@user) %>
86
+ <br/>
87
+ <%= link_to "view user", admin_user_path(@user) %> /
88
+ <%= link_to "edit user", edit_admin_user_path(@user) %> /
89
+ <%= render "user_options" %>
90
+ </p>
91
+ <% end %>
92
+ </fieldset>
93
+
94
+
95
+ </div>
96
+
97
+ <div class="rightie">
98
+
99
+ <fieldset>
100
+ <legend>Billing Address Details:</legend>
101
+ <%= fields_for :bill_address, @bill_address do |af| %>
102
+ <%= render "shared/error_messages", :target => @bill_address %>
103
+ <%= render 'shared/address_form', :form => af, :address => @bill_address, :billing => true %>
104
+ <% end %>
105
+ </fieldset>
106
+
107
+
108
+ <fieldset id="fields_ship_address">
109
+ <legend>Shipping Address Details:</legend>
110
+ <%= fields_for :ship_address, @ship_address do |af| %>
111
+ <%= render "shared/error_messages", :target => @ship_address %>
112
+ <%= render 'shared/address_form', :form => af, :address => @ship_address %>
113
+ <% end %>
114
+ </fieldset>
115
+
116
+ </div>
117
+ <script type="text/javascript">
118
+ //<![CDATA[
119
+
120
+ $('#wholesaler_use_billing').change(function(evt) {
121
+ $('#fields_ship_address').css('display', $(this).is(':checked') ? 'none' : 'block');
122
+ }).change();
123
+
124
+ <% unless @ship_address.new_record? || @bill_address != @ship_address %>
125
+ $('#wholesaler_use_billing').attr('checked', true);
126
+ <% end %>
127
+
128
+ //]]>
129
+ </script>