shoppe 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/app/assets/javascripts/shoppe/application.coffee +57 -1
  2. data/app/assets/javascripts/shoppe/mousetrap.js +9 -0
  3. data/app/assets/stylesheets/shoppe/application.scss +70 -59
  4. data/app/assets/stylesheets/shoppe/dialog.scss +10 -0
  5. data/app/assets/stylesheets/shoppe/sub.scss +15 -0
  6. data/app/controllers/shoppe/application_controller.rb +13 -1
  7. data/app/controllers/shoppe/attachments_controller.rb +10 -8
  8. data/app/controllers/shoppe/dashboard_controller.rb +6 -4
  9. data/app/controllers/shoppe/delivery_service_prices_controller.rb +33 -31
  10. data/app/controllers/shoppe/delivery_services_controller.rb +34 -32
  11. data/app/controllers/shoppe/orders_controller.rb +40 -38
  12. data/app/controllers/shoppe/product_categories_controller.rb +34 -32
  13. data/app/controllers/shoppe/products_controller.rb +32 -44
  14. data/app/controllers/shoppe/sessions_controller.rb +24 -22
  15. data/app/controllers/shoppe/stock_level_adjustments_controller.rb +40 -0
  16. data/app/controllers/shoppe/tax_rates_controller.rb +35 -33
  17. data/app/controllers/shoppe/users_controller.rb +40 -33
  18. data/app/controllers/shoppe/variants_controller.rb +50 -0
  19. data/app/helpers/shoppe/shoppe_helper.rb +2 -2
  20. data/app/mailers/shoppe/order_mailer.rb +20 -18
  21. data/app/models/shoppe/country.rb +1 -1
  22. data/app/models/shoppe/delivery_service.rb +17 -15
  23. data/app/models/shoppe/delivery_service_price.rb +18 -16
  24. data/app/models/shoppe/order.rb +293 -290
  25. data/app/models/shoppe/order_item.rb +115 -113
  26. data/app/models/shoppe/product.rb +76 -54
  27. data/app/models/shoppe/product/product_attributes.rb +12 -10
  28. data/app/models/shoppe/product/variants.rb +26 -0
  29. data/app/models/shoppe/product_attribute.rb +40 -38
  30. data/app/models/shoppe/product_category.rb +16 -14
  31. data/app/models/shoppe/stock_level_adjustment.rb +1 -2
  32. data/app/models/shoppe/tax_rate.rb +2 -2
  33. data/app/models/shoppe/user.rb +34 -32
  34. data/app/views/shoppe/orders/index.html.haml +3 -4
  35. data/app/views/shoppe/orders/show.html.haml +5 -5
  36. data/app/views/shoppe/products/_form.html.haml +28 -27
  37. data/app/views/shoppe/products/_table.html.haml +42 -0
  38. data/app/views/shoppe/products/edit.html.haml +2 -1
  39. data/app/views/shoppe/products/index.html.haml +1 -24
  40. data/app/views/shoppe/shared/error.html.haml +4 -0
  41. data/app/views/shoppe/{products/stock_levels.html.haml → stock_level_adjustments/index.html.haml} +12 -6
  42. data/app/views/shoppe/variants/form.html.haml +64 -0
  43. data/app/views/shoppe/variants/index.html.haml +33 -0
  44. data/config/routes.rb +2 -1
  45. data/config/shoppe.example.yml +16 -2
  46. data/db/migrate/20131022090919_refactor_order_items_to_allow_any_product.rb +6 -0
  47. data/db/migrate/20131022092904_rename_product_title_to_name.rb +5 -0
  48. data/db/migrate/20131022093538_stock_level_adjustments_should_be_polymorphic.rb +6 -0
  49. data/db/migrate/20131022135331_add_parent_id_to_products.rb +5 -0
  50. data/db/migrate/20131022145653_cost_price_should_be_default_to_zero.rb +9 -0
  51. data/db/seeds.rb +20 -20
  52. data/lib/shoppe.rb +2 -0
  53. data/lib/shoppe/errors/not_enough_stock.rb +1 -1
  54. data/lib/shoppe/errors/unorderable_item.rb +11 -0
  55. data/lib/shoppe/orderable_item.rb +39 -0
  56. data/lib/shoppe/version.rb +1 -1
  57. data/test/dummy/db/schema.rb +14 -11
  58. data/test/dummy/log/development.log +75 -0
  59. metadata +37 -5
@@ -1,41 +1,43 @@
1
- class Shoppe::OrdersController < Shoppe::ApplicationController
1
+ module Shoppe
2
+ class OrdersController < Shoppe::ApplicationController
3
+
4
+ before_filter { @active_nav = :orders }
5
+ before_filter { params[:id] && @order = Shoppe::Order.find(params[:id])}
6
+
7
+ def index
8
+ @query = Shoppe::Order.ordered.received.includes(:order_items => :ordered_item).page(params[:page]).search(params[:q])
9
+ @orders = @query.result
10
+ end
11
+
12
+ def update
13
+ @order.update_attributes!(params[:order].permit(:notes))
14
+ redirect_to @order, :notice => "Order has been saved successfully"
15
+ end
16
+
17
+ def search
18
+ index
19
+ render :action => "index"
20
+ end
21
+
22
+ def accept
23
+ @order.accept!(current_user)
24
+ redirect_to @order, :notice => "Order has been accepted successfully"
25
+ end
26
+
27
+ def reject
28
+ @order.reject!(current_user)
29
+ redirect_to @order, :notice => "Order has been rejected successfully"
30
+ end
31
+
32
+ def ship
33
+ @order.ship!(current_user, params[:consignment_number])
34
+ redirect_to @order, :notice => "Order has been shipped successfully"
35
+ end
36
+
37
+ def pay
38
+ @order.pay!(params[:payment_reference], params[:payment_method].blank? ? 'Unknown' : params[:payment_method])
39
+ redirect_to @order, :notice => "Order has been marked as paid successfully"
40
+ end
2
41
 
3
- before_filter { @active_nav = :orders }
4
- before_filter { params[:id] && @order = Shoppe::Order.find(params[:id])}
5
-
6
- def index
7
- @query = Shoppe::Order.ordered.received.includes(:order_items => :product).page(params[:page]).search(params[:q])
8
- @orders = @query.result
9
- end
10
-
11
- def update
12
- @order.update_attributes!(params[:order].permit(:notes))
13
- redirect_to @order, :notice => "Order has been saved successfully"
14
- end
15
-
16
- def search
17
- index
18
- render :action => "index"
19
- end
20
-
21
- def accept
22
- @order.accept!(current_user)
23
- redirect_to @order, :notice => "Order has been accepted successfully"
24
42
  end
25
-
26
- def reject
27
- @order.reject!(current_user)
28
- redirect_to @order, :notice => "Order has been rejected successfully"
29
- end
30
-
31
- def ship
32
- @order.ship!(current_user, params[:consignment_number])
33
- redirect_to @order, :notice => "Order has been shipped successfully"
34
- end
35
-
36
- def pay
37
- @order.pay!(params[:payment_reference], params[:payment_method].blank? ? 'Unknown' : params[:payment_method])
38
- redirect_to @order, :notice => "Order has been marked as paid successfully"
39
- end
40
-
41
43
  end
@@ -1,45 +1,47 @@
1
- class Shoppe::ProductCategoriesController < Shoppe::ApplicationController
1
+ module Shoppe
2
+ class ProductCategoriesController < Shoppe::ApplicationController
2
3
 
3
- before_filter { @active_nav = :product_categories }
4
- before_filter { params[:id] && @product_category = Shoppe::ProductCategory.find(params[:id]) }
4
+ before_filter { @active_nav = :product_categories }
5
+ before_filter { params[:id] && @product_category = Shoppe::ProductCategory.find(params[:id]) }
5
6
 
6
- def index
7
- @product_categories = Shoppe::ProductCategory.ordered.all
8
- end
7
+ def index
8
+ @product_categories = Shoppe::ProductCategory.ordered.all
9
+ end
9
10
 
10
- def new
11
- @product_category = Shoppe::ProductCategory.new
12
- end
11
+ def new
12
+ @product_category = Shoppe::ProductCategory.new
13
+ end
13
14
 
14
- def create
15
- @product_category = Shoppe::ProductCategory.new(safe_params)
16
- if @product_category.save
17
- redirect_to :product_categories, :flash => {:notice => "Category has been created successfully"}
18
- else
19
- render :action => "new"
15
+ def create
16
+ @product_category = Shoppe::ProductCategory.new(safe_params)
17
+ if @product_category.save
18
+ redirect_to :product_categories, :flash => {:notice => "Category has been created successfully"}
19
+ else
20
+ render :action => "new"
21
+ end
20
22
  end
21
- end
22
23
 
23
- def edit
24
- end
24
+ def edit
25
+ end
25
26
 
26
- def update
27
- if @product_category.update(safe_params)
28
- redirect_to [:edit, @product_category], :flash => {:notice => "Category has been updated successfully"}
29
- else
30
- render :action => "edit"
27
+ def update
28
+ if @product_category.update(safe_params)
29
+ redirect_to [:edit, @product_category], :flash => {:notice => "Category has been updated successfully"}
30
+ else
31
+ render :action => "edit"
32
+ end
31
33
  end
32
- end
33
34
 
34
- def destroy
35
- @product_category.destroy
36
- redirect_to :product_categories, :flash => {:notice => "Category has been removed successfully"}
37
- end
35
+ def destroy
36
+ @product_category.destroy
37
+ redirect_to :product_categories, :flash => {:notice => "Category has been removed successfully"}
38
+ end
38
39
 
39
- private
40
+ private
40
41
 
41
- def safe_params
42
- params[:product_category].permit(:name, :permalink, :description, :image_file)
43
- end
42
+ def safe_params
43
+ params[:product_category].permit(:name, :permalink, :description, :image_file)
44
+ end
44
45
 
46
+ end
45
47
  end
@@ -1,59 +1,47 @@
1
- class Shoppe::ProductsController < Shoppe::ApplicationController
1
+ module Shoppe
2
+ class ProductsController < Shoppe::ApplicationController
2
3
 
3
- before_filter { @active_nav = :products }
4
- before_filter { params[:id] && @product = Shoppe::Product.find(params[:id]) }
4
+ before_filter { @active_nav = :products }
5
+ before_filter { params[:id] && @product = Shoppe::Product.root.find(params[:id]) }
5
6
 
6
- def index
7
- @products = Shoppe::Product.includes(:stock_level_adjustments, :default_image, :product_category).order(:title).group_by(&:product_category).sort_by { |cat,pro| cat.name }
8
- end
9
-
10
- def new
11
- @product = Shoppe::Product.new
12
- end
13
-
14
- def create
15
- @product = Shoppe::Product.new(safe_params)
16
- if @product.save
17
- redirect_to :products, :flash => {:notice => "Product has been created successfully"}
18
- else
19
- render :action => "new"
7
+ def index
8
+ @products = Shoppe::Product.root.includes(:stock_level_adjustments, :default_image, :product_category, :variants).order(:name).group_by(&:product_category).sort_by { |cat,pro| cat.name }
20
9
  end
21
- end
22
10
 
23
- def edit
24
- end
11
+ def new
12
+ @product = Shoppe::Product.new
13
+ end
25
14
 
26
- def update
27
- if @product.update(safe_params)
28
- redirect_to [:edit, @product], :flash => {:notice => "Product has been updated successfully"}
29
- else
30
- render :action => "edit"
15
+ def create
16
+ @product = Shoppe::Product.new(safe_params)
17
+ if @product.save
18
+ redirect_to :products, :flash => {:notice => "Product has been created successfully"}
19
+ else
20
+ render :action => "new"
21
+ end
31
22
  end
32
- end
33
23
 
34
- def destroy
35
- @product.destroy
36
- redirect_to :products, :flash => {:notice => "Product has been removed successfully"}
37
- end
24
+ def edit
25
+ end
38
26
 
39
- def stock_levels
40
- @stock_level_adjustments = @product.stock_level_adjustments.ordered.page(params[:page])
41
- if request.post?
42
- @new_sla = @product.stock_level_adjustments.build(params[:stock_level_adjustment].permit(:description, :adjustment))
43
- if @new_sla.save
44
- redirect_to [:stock_levels, @product], :notice => "Stock level adjustment has been recorded"
27
+ def update
28
+ if @product.update(safe_params)
29
+ redirect_to [:edit, @product], :flash => {:notice => "Product has been updated successfully"}
45
30
  else
46
- flash.now[:alert] = @new_sla.errors.full_messages.to_sentence
31
+ render :action => "edit"
47
32
  end
48
- else
49
- @new_sla = @product.stock_level_adjustments.build
50
33
  end
51
- end
52
34
 
53
- private
35
+ def destroy
36
+ @product.destroy
37
+ redirect_to :products, :flash => {:notice => "Product has been removed successfully"}
38
+ end
39
+
40
+ private
54
41
 
55
- def safe_params
56
- params[:product].permit(:product_category_id, :title, :sku, :permalink, :description, :short_description, :weight, :price, :cost_price, :tax_rate_id, :stock_control, :default_image_file, :data_sheet_file, :active, :featured, :in_the_box, :product_attributes_array => [:key, :value, :searchable, :public])
57
- end
42
+ def safe_params
43
+ params[:product].permit(:product_category_id, :name, :sku, :permalink, :description, :short_description, :weight, :price, :cost_price, :tax_rate_id, :stock_control, :default_image_file, :data_sheet_file, :active, :featured, :in_the_box, :product_attributes_array => [:key, :value, :searchable, :public])
44
+ end
58
45
 
46
+ end
59
47
  end
@@ -1,30 +1,32 @@
1
- class Shoppe::SessionsController < Shoppe::ApplicationController
2
- layout 'shoppe/sub'
3
- skip_before_filter :login_required, :only => [:new, :create, :reset]
1
+ module Shoppe
2
+ class SessionsController < Shoppe::ApplicationController
3
+ layout 'shoppe/sub'
4
+ skip_before_filter :login_required, :only => [:new, :create, :reset]
4
5
 
5
- def create
6
- if user = Shoppe::User.authenticate(params[:email_address], params[:password])
7
- session[:shoppe_user_id] = user.id
8
- redirect_to :orders
9
- else
10
- flash.now[:alert] = "The email address and/or password you have entered is invalid. Please check and try again."
11
- render :action => "new"
6
+ def create
7
+ if user = Shoppe::User.authenticate(params[:email_address], params[:password])
8
+ session[:shoppe_user_id] = user.id
9
+ redirect_to :orders
10
+ else
11
+ flash.now[:alert] = "The email address and/or password you have entered is invalid. Please check and try again."
12
+ render :action => "new"
13
+ end
12
14
  end
13
- end
14
15
 
15
- def destroy
16
- session[:shoppe_user_id] = nil
17
- redirect_to :login
18
- end
16
+ def destroy
17
+ session[:shoppe_user_id] = nil
18
+ redirect_to :login
19
+ end
19
20
 
20
- def reset
21
+ def reset
21
22
 
22
- if request.post?
23
- if user = Shoppe::User.find_by_email_address(params[:email_address])
24
- user.reset_password!
25
- redirect_to login_path(:email_address => params[:email_address]), :notice => "An e-mail has been sent to #{user.email_address} with a new password"
26
- else
27
- flash.now[:alert] = "No user was found matching the e-mail address"
23
+ if request.post?
24
+ if user = Shoppe::User.find_by_email_address(params[:email_address])
25
+ user.reset_password!
26
+ redirect_to login_path(:email_address => params[:email_address]), :notice => "An e-mail has been sent to #{user.email_address} with a new password"
27
+ else
28
+ flash.now[:alert] = "No user was found matching the e-mail address"
29
+ end
28
30
  end
29
31
  end
30
32
  end
@@ -0,0 +1,40 @@
1
+ module Shoppe
2
+ class StockLevelAdjustmentsController < ApplicationController
3
+
4
+ SUITABLE_OBJECTS = ['Shoppe::Product']
5
+ before_filter do
6
+ raise Shoppe::Error, "Invalid item_type (must be one of #{SUITABLE_OBJECTS.to_sentence})" unless SUITABLE_OBJECTS.include?(params[:item_type])
7
+ @item = params[:item_type].constantize.find(params[:item_id].to_i)
8
+ end
9
+ before_filter { params[:id] && @sla = @item.stock_level_adjustments.find(params[:id].to_i) }
10
+
11
+ def index
12
+ @stock_level_adjustments = @item.stock_level_adjustments.ordered.page(params[:page]).per(10)
13
+ @new_sla = @item.stock_level_adjustments.build if @new_sla.nil?
14
+ if request.xhr?
15
+ render :action => 'index', :layout => false
16
+ end
17
+ end
18
+
19
+ def create
20
+ @new_sla = @item.stock_level_adjustments.build(params[:stock_level_adjustment].permit(:description, :adjustment))
21
+ if @new_sla.save
22
+ if request.xhr?
23
+ @new_sla = @item.stock_level_adjustments.build
24
+ index
25
+ else
26
+ redirect_to stock_level_adjustments_path(:item_id => params[:item_id], :item_type => params[:item_type]), :notice => "Adjustment has been added successfully"
27
+ end
28
+ else
29
+ if request.xhr?
30
+ render :text => @new_sla.errors.full_messages.to_sentence, :status => 422
31
+ else
32
+ index
33
+ flash.now[:alert] = @new_sla.errors.full_messages.to_sentence
34
+ render :action => "index"
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -1,47 +1,49 @@
1
- class Shoppe::TaxRatesController < Shoppe::ApplicationController
1
+ module Shoppe
2
+ class TaxRatesController < Shoppe::ApplicationController
2
3
 
3
- before_filter { @active_nav = :tax_rates }
4
- before_filter { params[:id] && @tax_rate = Shoppe::TaxRate.find(params[:id]) }
4
+ before_filter { @active_nav = :tax_rates }
5
+ before_filter { params[:id] && @tax_rate = Shoppe::TaxRate.find(params[:id]) }
5
6
 
6
- def index
7
- @tax_rates = Shoppe::TaxRate.ordered.all
8
- end
9
-
10
- def new
11
- @tax_rate = Shoppe::TaxRate.new
12
- render :action => "form"
13
- end
7
+ def index
8
+ @tax_rates = Shoppe::TaxRate.ordered.all
9
+ end
14
10
 
15
- def create
16
- @tax_rate = Shoppe::TaxRate.new(safe_params)
17
- if @tax_rate.save
18
- redirect_to :tax_rates, :flash => {:notice => "Tax rate has been created successfully"}
19
- else
11
+ def new
12
+ @tax_rate = Shoppe::TaxRate.new
20
13
  render :action => "form"
21
14
  end
22
- end
23
15
 
24
- def edit
25
- render :action => "form"
26
- end
16
+ def create
17
+ @tax_rate = Shoppe::TaxRate.new(safe_params)
18
+ if @tax_rate.save
19
+ redirect_to :tax_rates, :flash => {:notice => "Tax rate has been created successfully"}
20
+ else
21
+ render :action => "form"
22
+ end
23
+ end
27
24
 
28
- def update
29
- if @tax_rate.update(safe_params)
30
- redirect_to [:edit, @tax_rate], :flash => {:notice => "Tax rate has been updated successfully"}
31
- else
25
+ def edit
32
26
  render :action => "form"
33
27
  end
34
- end
35
28
 
36
- def destroy
37
- @tax_rate.destroy
38
- redirect_to :tax_rates, :flash => {:notice => "Tax rate has been removed successfully"}
39
- end
29
+ def update
30
+ if @tax_rate.update(safe_params)
31
+ redirect_to [:edit, @tax_rate], :flash => {:notice => "Tax rate has been updated successfully"}
32
+ else
33
+ render :action => "form"
34
+ end
35
+ end
40
36
 
41
- private
37
+ def destroy
38
+ @tax_rate.destroy
39
+ redirect_to :tax_rates, :flash => {:notice => "Tax rate has been removed successfully"}
40
+ end
42
41
 
43
- def safe_params
44
- params[:tax_rate].permit(:name, :rate, :country_ids => [])
45
- end
42
+ private
46
43
 
44
+ def safe_params
45
+ params[:tax_rate].permit(:name, :rate, :country_ids => [])
46
+ end
47
+
48
+ end
47
49
  end
@@ -1,46 +1,53 @@
1
- class Shoppe::UsersController < Shoppe::ApplicationController
1
+ module Shoppe
2
+ class UsersController < Shoppe::ApplicationController
3
+
4
+ before_filter { @active_nav = :users }
5
+ before_filter { params[:id] && @user = Shoppe::User.find(params[:id]) }
6
+ if Shoppe.config[:demo_mode]
7
+ before_filter(:only => [:create, :update, :destroy]) do
8
+ raise Shoppe::Error, "You cannot make changes to user in demo mode. Sorry about that."
9
+ end
10
+ end
2
11
 
3
- before_filter { @active_nav = :users }
4
- before_filter { params[:id] && @user = Shoppe::User.find(params[:id]) }
12
+ def index
13
+ @users = Shoppe::User.all
14
+ end
5
15
 
6
- def index
7
- @users = Shoppe::User.all
8
- end
16
+ def new
17
+ @user = Shoppe::User.new
18
+ end
9
19
 
10
- def new
11
- @user = Shoppe::User.new
12
- end
20
+ def create
21
+ @user = Shoppe::User.new(safe_params)
22
+ if @user.save
23
+ redirect_to :users, :flash => {:notice => "User has been created successfully"}
24
+ else
25
+ render :action => "new"
26
+ end
27
+ end
13
28
 
14
- def create
15
- @user = Shoppe::User.new(safe_params)
16
- if @user.save
17
- redirect_to :users, :flash => {:notice => "User has been created successfully"}
18
- else
19
- render :action => "new"
29
+ def edit
20
30
  end
21
- end
22
31
 
23
- def edit
24
- end
32
+ def update
33
+ if @user.update(safe_params)
34
+ redirect_to [:edit, @user], :flash => {:notice => "User has been updated successfully"}
35
+ else
36
+ render :action => "edit"
37
+ end
38
+ end
25
39
 
26
- def update
27
- if @user.update(safe_params)
28
- redirect_to [:edit, @user], :flash => {:notice => "User has been updated successfully"}
29
- else
30
- render :action => "edit"
40
+ def destroy
41
+ raise Shoppe::Error, "You cannot remove yourself" if @user == current_user
42
+ @user.destroy
43
+ redirect_to :users, :flash => {:notice => "User has been removed successfully"}
31
44
  end
32
- end
33
45
 
34
- def destroy
35
- raise Shoppe::Error, "You cannot remove yourself" if @user == current_user
36
- @user.destroy
37
- redirect_to :users, :flash => {:notice => "User has been removed successfully"}
38
- end
46
+ private
39
47
 
40
- private
48
+ def safe_params
49
+ params[:user].permit(:first_name, :last_name, :email_address, :password, :password_confirmation)
50
+ end
41
51
 
42
- def safe_params
43
- params[:user].permit(:first_name, :last_name, :email_address, :password, :password_confirmation)
44
52
  end
45
-
46
53
  end