refinerycms-products 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/app/controllers/addresses_controller.rb +22 -0
  2. data/app/controllers/admin/carts_controller.rb +7 -0
  3. data/app/controllers/admin/categories_controller.rb +50 -0
  4. data/app/controllers/admin/customers_controller.rb +12 -0
  5. data/app/controllers/admin/line_items_controller.rb +7 -0
  6. data/app/controllers/admin/products_controller.rb +23 -0
  7. data/app/controllers/carts_controller.rb +110 -0
  8. data/app/controllers/categories_controller.rb +32 -0
  9. data/app/controllers/customers_controller.rb +33 -0
  10. data/app/controllers/line_items_controller.rb +8 -0
  11. data/app/controllers/products_controller.rb +61 -0
  12. data/app/controllers/profiles_controller.rb +37 -0
  13. data/app/helpers/address_helper.rb +20 -0
  14. data/app/helpers/products_helper.rb +34 -0
  15. data/app/models/address.rb +18 -0
  16. data/app/models/cart.rb +54 -0
  17. data/app/models/category.rb +28 -0
  18. data/app/models/customer.rb +32 -0
  19. data/app/models/line_item.rb +28 -0
  20. data/app/models/product.rb +46 -0
  21. data/app/views/addresses/edit.html.erb +42 -0
  22. data/app/views/admin/carts/_actions.html.erb +28 -0
  23. data/app/views/admin/carts/_cart.html.erb +18 -0
  24. data/app/views/admin/carts/_carts.html.erb +2 -0
  25. data/app/views/admin/carts/_form.html.erb +24 -0
  26. data/app/views/admin/carts/_records.html.erb +18 -0
  27. data/app/views/admin/carts/_sortable_list.html.erb +7 -0
  28. data/app/views/admin/carts/edit.html.erb +1 -0
  29. data/app/views/admin/carts/index.html.erb +10 -0
  30. data/app/views/admin/carts/new.html.erb +1 -0
  31. data/app/views/admin/categories/_actions.html.erb +28 -0
  32. data/app/views/admin/categories/_categories.html.erb +2 -0
  33. data/app/views/admin/categories/_category.html.erb +25 -0
  34. data/app/views/admin/categories/_form.html.erb +49 -0
  35. data/app/views/admin/categories/_records.html.erb +18 -0
  36. data/app/views/admin/categories/_sortable_list.html.erb +10 -0
  37. data/app/views/admin/categories/edit.html.erb +1 -0
  38. data/app/views/admin/categories/index.html.erb +12 -0
  39. data/app/views/admin/categories/new.html.erb +1 -0
  40. data/app/views/admin/customers/_actions.html.erb +28 -0
  41. data/app/views/admin/customers/_customer.html.erb +18 -0
  42. data/app/views/admin/customers/_customers.html.erb +2 -0
  43. data/app/views/admin/customers/_form.html.erb +40 -0
  44. data/app/views/admin/customers/_records.html.erb +18 -0
  45. data/app/views/admin/customers/_sortable_list.html.erb +7 -0
  46. data/app/views/admin/customers/edit.html.erb +1 -0
  47. data/app/views/admin/customers/index.html.erb +10 -0
  48. data/app/views/admin/customers/new.html.erb +1 -0
  49. data/app/views/admin/customers/show.html.erb +60 -0
  50. data/app/views/admin/line_items/_actions.html.erb +28 -0
  51. data/app/views/admin/line_items/_form.html.erb +29 -0
  52. data/app/views/admin/line_items/_line_item.html.erb +18 -0
  53. data/app/views/admin/line_items/_line_items.html.erb +2 -0
  54. data/app/views/admin/line_items/_records.html.erb +18 -0
  55. data/app/views/admin/line_items/_sortable_list.html.erb +7 -0
  56. data/app/views/admin/line_items/edit.html.erb +1 -0
  57. data/app/views/admin/line_items/index.html.erb +10 -0
  58. data/app/views/admin/line_items/new.html.erb +1 -0
  59. data/app/views/admin/products/_actions.html.erb +43 -0
  60. data/app/views/admin/products/_form.html.erb +120 -0
  61. data/app/views/admin/products/_product.html.erb +24 -0
  62. data/app/views/admin/products/_products.html.erb +2 -0
  63. data/app/views/admin/products/_records.html.erb +18 -0
  64. data/app/views/admin/products/_sortable_list.html.erb +13 -0
  65. data/app/views/admin/products/edit.html.erb +1 -0
  66. data/app/views/admin/products/index.html.erb +12 -0
  67. data/app/views/admin/products/new.html.erb +1 -0
  68. data/app/views/carts/show.html.erb +56 -0
  69. data/app/views/categories/index.html.erb +11 -0
  70. data/app/views/categories/show.html.erb +33 -0
  71. data/app/views/customers/index.html.erb +11 -0
  72. data/app/views/customers/show.html.erb +52 -0
  73. data/app/views/line_items/index.html.erb +11 -0
  74. data/app/views/line_items/show.html.erb +39 -0
  75. data/app/views/products/index.html.erb +33 -0
  76. data/app/views/products/show.html.erb +65 -0
  77. data/app/views/profiles/_order_history.html.erb +24 -0
  78. data/app/views/profiles/_show_address.html.erb +4 -0
  79. data/app/views/profiles/account_details.html.erb +32 -0
  80. data/app/views/profiles/address_details.html.erb +10 -0
  81. data/app/views/profiles/index.html.erb +75 -0
  82. data/app/views/profiles/order_history.html.erb +1 -0
  83. data/app/views/profiles/order_history_details.html.erb +39 -0
  84. data/config/locales/en.yml +97 -0
  85. data/config/locales/fr.yml +25 -0
  86. data/config/locales/lolcat.yml +25 -0
  87. data/config/locales/nb.yml +21 -0
  88. data/config/locales/nl.yml +21 -0
  89. data/config/routes.rb +58 -0
  90. data/lib/generators/refinerycms_products_generator.rb +6 -0
  91. data/lib/refinerycms-carts.rb +32 -0
  92. data/lib/refinerycms-categories.rb +30 -0
  93. data/lib/refinerycms-customers.rb +34 -0
  94. data/lib/refinerycms-line_items.rb +30 -0
  95. data/lib/refinerycms-products.rb +65 -0
  96. data/lib/tasks/products.rake +13 -0
  97. metadata +160 -0
@@ -0,0 +1,22 @@
1
+ class AddressesController < ApplicationController
2
+
3
+ def edit
4
+
5
+ @address = Address.find(params[:id])
6
+
7
+ end
8
+
9
+ def update
10
+
11
+ @address = Address.find(params[:id])
12
+
13
+ if @address.update_attributes(params[:address])
14
+ flash[:success] = 'Address was successfully updated.'
15
+ redirect_to profiles_path
16
+ else
17
+ render :action => "edit"
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,7 @@
1
+ module Admin
2
+ class CartsController < Admin::BaseController
3
+
4
+ crudify :cart, :xhr_paging => true
5
+
6
+ end
7
+ end
@@ -0,0 +1,50 @@
1
+ module Admin
2
+ class CategoriesController < Admin::BaseController
3
+
4
+ crudify :category,
5
+ :conditions => nil,
6
+ :include => [:parent],
7
+ :title_attribute => 'name', :xhr_paging => true
8
+
9
+ def create
10
+ # if the position field exists, set this object as last object, given the conditions of this class.
11
+ if Category.column_names.include?("position")
12
+ params[:category].merge!({
13
+ :position => ((Category.maximum(:position)||-1) + 1)
14
+ })
15
+ end
16
+
17
+ if (@category = Category.create(params[:category])).valid?
18
+
19
+ flash[:notice] = t('refinery.crudify.created', :what => @category.name)
20
+
21
+ if @category.parent.present?
22
+ if @category.parent.products.present?
23
+ flash[:notice] += " Please be aware that the '#{@category.parent.name}' category has products attached to it. Please re-assign these."
24
+ end
25
+ end
26
+
27
+ redirect_to admin_categories_path
28
+
29
+ else
30
+ render :action => 'new'
31
+ end
32
+ end
33
+
34
+ def update
35
+
36
+ if @category.update_attributes(params[:category])
37
+
38
+ if @category.parent.present?
39
+ if @category.parent.products.present?
40
+ flash[:notice] = "Please be aware that the '#{@category.parent.name}' category has products attached to it. Please re-assign these."
41
+ end
42
+ end
43
+
44
+ redirect_to admin_categories_path
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ module Admin
2
+ class CustomersController < Admin::BaseController
3
+
4
+ crudify :customer,
5
+ :title_attribute => 'name', :xhr_paging => true
6
+
7
+ def show
8
+ @customer = Customer.find(params[:id])
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ module Admin
2
+ class LineItemsController < Admin::BaseController
3
+
4
+ crudify :line_item, :xhr_paging => true
5
+
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ module Admin
2
+ class ProductsController < Admin::BaseController
3
+
4
+ crudify :product,
5
+ :title_attribute => 'name', :xhr_paging => true
6
+
7
+ def index
8
+ if params[:category_id].present?
9
+ @category = Category.find(params[:category_id])
10
+ @products = Product.by_category(@category.id).order('position ASC').paginate(:page => params[:page])
11
+ else
12
+ paginate_all_products
13
+ end
14
+ end
15
+
16
+ def update_prices
17
+ Product.update(params[:products].keys, params[:products].values)
18
+ flash[:notice] = 'Prices were successfully updated.'
19
+ redirect_to :action => "index"
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,110 @@
1
+ class CartsController < ApplicationController
2
+
3
+ before_filter :initialize_cart
4
+
5
+ def add_to_cart
6
+ check_quantity_then_update_cart
7
+
8
+ # redirect_to_products("Product added to Cart")
9
+ redirect_to show_cart_path
10
+ end
11
+
12
+ # Here for backwards compatibility
13
+ def show_cart
14
+ render :action => 'show'
15
+ end
16
+
17
+ def show
18
+
19
+ end
20
+
21
+ def check_quantity_then_update_cart
22
+
23
+ #logger.info("****************** the variant = #{params[:variant][:id]}")
24
+
25
+ if params[:quantity].present?
26
+ if params[:variant].present?
27
+ @current_cart.add_to_the_cart(params[:product_id], params[:quantity], params[:variant][:id])
28
+ else
29
+ @current_cart.add_to_the_cart(params[:product_id], params[:quantity])
30
+ end
31
+ else
32
+ if params[:variant].present?
33
+ @current_cart.add_to_the_cart(params[:product_id], 1, params[:variant][:id])
34
+ else
35
+ @current_cart.add_to_the_cart(params[:product_id])
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ def increment_cart
42
+ check_quantity_then_update_cart
43
+
44
+ redirect_to show_cart_path
45
+ end
46
+
47
+ private
48
+
49
+ def redirect_to_products(msg)
50
+ flash[:notice] = msg
51
+
52
+ if params[:category_id].present?
53
+ if params[:category_id] == "0"
54
+ redirect_to "/"
55
+ else
56
+ redirect_to category_products_path(params[:category_id])
57
+ end
58
+ else
59
+ redirect_to product_path(params[:product_id])
60
+ end
61
+ end
62
+
63
+ def initialize_cart
64
+ @current_cart = get_cart
65
+ end
66
+
67
+ # Get the current customer's cart
68
+ def get_cart
69
+ if customer_signed_in?
70
+
71
+ if session[:cart_id].present?
72
+ cart = Cart.find(session[:cart_id])
73
+ if cart.customer_id.blank?
74
+ cart.customer_id = current_customer.id
75
+ cart.is_current = true
76
+ cart.save
77
+ end
78
+ return cart
79
+ else
80
+ cart = Cart.where(:is_current => true, :customer_id => current_customer.id).first
81
+ if cart.blank?
82
+ cart = Cart.create(:is_current => true, :customer_id => current_customer.id)
83
+ end
84
+
85
+ session[:cart_id] = cart.id
86
+ return cart
87
+ end
88
+
89
+ else
90
+ if session[:cart_id].present?
91
+ # logger.info("*************** signed OUT and session was present")
92
+ cart = Cart.find_by_id(session[:cart_id])
93
+ if cart.blank?
94
+ cart = Cart.create(:is_current => true)
95
+ session[:cart_id] = cart.id
96
+ return cart
97
+ else
98
+ cart.is_current = true
99
+ cart.save
100
+ return cart
101
+ end
102
+ else
103
+ # logger.info("*************** signed OUT and session was NOT present")
104
+ cart = Cart.create(:is_current => true)
105
+ session[:cart_id] = cart.id
106
+ return cart
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,32 @@
1
+ class CategoriesController < ApplicationController
2
+
3
+ before_filter :find_all_categories
4
+ before_filter :find_page
5
+
6
+ def index
7
+ # you can use meta fields from your model instead (e.g. browser_title)
8
+ # by swapping @page for @category in the line below:
9
+ present(@page)
10
+ end
11
+
12
+ def show
13
+ @category = Category.find(params[:id])
14
+
15
+ # redirect_to category_products_path(@category)
16
+
17
+ # you can use meta fields from your model instead (e.g. browser_title)
18
+ # by swapping @page for @category in the line below:
19
+ present(@page)
20
+ end
21
+
22
+ protected
23
+
24
+ def find_all_categories
25
+ @categories = Category.order('position ASC')
26
+ end
27
+
28
+ def find_page
29
+ @page = Page.where(:link_url => "/categories").first
30
+ end
31
+
32
+ end
@@ -0,0 +1,33 @@
1
+ class CustomersController < ApplicationController
2
+
3
+ #before_filter :find_all_customers
4
+ before_filter :find_page
5
+ helper :all
6
+
7
+
8
+
9
+ #def index
10
+ # # you can use meta fields from your model instead (e.g. browser_title)
11
+ # # by swapping @page for @customer in the line below:
12
+ # present(@page)
13
+ #end
14
+
15
+ def show
16
+ @customer = Customer.find(params[:id])
17
+
18
+ # you can use meta fields from your model instead (e.g. browser_title)
19
+ # by swapping @page for @customer in the line below:
20
+ present(@page)
21
+ end
22
+
23
+ protected
24
+
25
+ #def find_all_customers
26
+ # @customers = Customer.order('surname ASC')
27
+ #end
28
+
29
+ def find_page
30
+ @page = Page.where(:link_url => "/customers").first
31
+ end
32
+
33
+ end
@@ -0,0 +1,8 @@
1
+ class LineItemsController < ApplicationController
2
+
3
+ def destroy
4
+ LineItem.destroy(params[:id])
5
+ redirect_to show_cart_path
6
+ end
7
+
8
+ end
@@ -0,0 +1,61 @@
1
+ class ProductsController < ApplicationController
2
+ include ActionView::Helpers::NumberHelper
3
+ before_filter :find_all_products, :only => :index
4
+ before_filter :find_page
5
+
6
+ def index
7
+ # you can use meta fields from your model instead (e.g. browser_title)
8
+ # by swapping @page for @product in the line below:
9
+ present(@page)
10
+ end
11
+
12
+ def show
13
+ @product = Product.find(params[:id])
14
+
15
+
16
+ @tagged_products = Product.tagged_with(@product.tag_list, :any => :true).order('position ASC')
17
+
18
+ # you can use meta fields from your model instead (e.g. browser_title)
19
+ # by swapping @page for @product in the line below:
20
+ present(@page)
21
+ end
22
+
23
+ def get_variant_image
24
+ if params[:variant_id].present?
25
+ variant_url = Variant.find(params[:variant_id]).image.url
26
+ end
27
+ render :text => variant_url
28
+ end
29
+
30
+ def get_variant_price
31
+ if params[:variant_id].present?
32
+ variant_price = Variant.find(params[:variant_id]).price
33
+ end
34
+ render :text => number_to_currency(variant_price, :unit => 'R')
35
+ end
36
+
37
+ protected
38
+
39
+ def find_all_products
40
+
41
+ if params[:category_id].present?
42
+ @category = Category.find(params[:category_id])
43
+ @products = Product.by_category(@category.id).order('position ASC')
44
+ @page_title = @category.name
45
+ elsif params[:upper].present? and params[:lower].present?
46
+ @products = Product.greater_than(params[:lower]).less_than(params[:upper])
47
+ @page_title = "By Price"
48
+ elsif params[:tag].present?
49
+ @products = Product.tagged_with(params[:tag]).order('position ASC')
50
+ @page_title = params[:tag].capitalize
51
+ else
52
+ @products = Product.all
53
+ @page_title = "All Products"
54
+ end
55
+ end
56
+
57
+ def find_page
58
+ @page = Page.where(:link_url => "/products").first
59
+ end
60
+
61
+ end
@@ -0,0 +1,37 @@
1
+ class ProfilesController < ApplicationController
2
+ before_filter :authenticate_customer!
3
+
4
+ def index
5
+ @current_customer = current_customer
6
+ if @current_customer.present?
7
+ @delivery_addresses = Address.where(:customer_id => current_customer.id).all
8
+ end
9
+ if @current_customer.present?
10
+ @orders = Order.where(:customer_id => current_customer.id).limit(5)
11
+ end
12
+ end
13
+
14
+ def account_details
15
+ @current_customer = current_customer
16
+ end
17
+
18
+ def address_details
19
+ if current_customer.present?
20
+ @delivery_addresses = Address.where(:customer_id => current_customer.id).all
21
+ end
22
+ end
23
+
24
+ if defined?(OrdersController)
25
+ def order_history
26
+ if current_customer.present?
27
+ @orders = Order.where(:customer_id => current_customer.id).all
28
+ end
29
+ end
30
+
31
+ def order_history_details
32
+ @current_order = Order.where(:order_number => params[:order_number]).first
33
+ end
34
+ end
35
+
36
+
37
+ end
@@ -0,0 +1,20 @@
1
+ module AddressHelper
2
+
3
+ def address_html(address)
4
+ if address.present?
5
+ items = []
6
+ items << address.address_line_1 if address.address_line_1.present?
7
+ items << address.address_line_2 if address.address_line_2.present?
8
+ items << address.suburb if address.suburb.present?
9
+ items << address.city if address.city.present?
10
+ items << address.postal_code if address.postal_code.present?
11
+
12
+ items.join("<br />")
13
+ else
14
+ nil
15
+ end
16
+ end
17
+
18
+
19
+
20
+ end
@@ -0,0 +1,34 @@
1
+ require 'acts-as-taggable-on'
2
+
3
+ module ProductsHelper
4
+ include ActsAsTaggableOn::TagsHelper
5
+
6
+ def rands(amount)
7
+ number_to_currency(amount, :unit => 'R')
8
+ end
9
+
10
+ def rands_nocents(amount)
11
+ number_to_currency(amount, :unit => 'R', :precision => 0)
12
+ end
13
+
14
+ def product_or_variant_name(cart_item)
15
+ if variant_exists?(cart_item)
16
+ "#{cart_item.product.name}: #{cart_item.variant.name}"
17
+ else
18
+ cart_item.product.name
19
+ end
20
+ end
21
+
22
+ def product_or_variant_price(cart_item)
23
+ if variant_exists?(cart_item)
24
+ rands(cart_item.variant.price)
25
+ else
26
+ rands(cart_item.product.price)
27
+ end
28
+ end
29
+
30
+ def variant_exists?(cart_item)
31
+ cart_item.variant_id.present? and defined?(Variant)
32
+ end
33
+
34
+ end
@@ -0,0 +1,18 @@
1
+ class Address < ActiveRecord::Base
2
+ belongs_to :customer
3
+
4
+ validates_presence_of :address_line_1, :suburb, :city, :postal_code, :customer
5
+
6
+ scope :is_default, where(:default => true)
7
+
8
+ def set_as_default
9
+ self.update_attribute(:default, true)
10
+
11
+ other_addresses = Address.where(:customer_id => self.customer_id)
12
+ other_addresses.each do |address|
13
+ if self.id != address.id
14
+ address.update_attribute(:default, false)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,54 @@
1
+ class Cart < ActiveRecord::Base
2
+ before_save :check_is_current_for_sibling_carts
3
+
4
+ belongs_to :customer
5
+ has_many :line_items
6
+ has_many :products, :through => :line_items
7
+
8
+ # def title was created automatically because you didn't specify a string field
9
+ # when you ran the refinery_engine generator. Love, Refinery CMS.
10
+ def title
11
+ "Override def title in vendor/engines/carts/app/models/cart.rb"
12
+ end
13
+
14
+ def grand_total
15
+ total = 0
16
+ line_items.each do |li|
17
+ total += li.total_price
18
+ end
19
+ total
20
+ end
21
+
22
+
23
+ def add_to_the_cart(product_id, quantity = 1, variant_id = nil)
24
+ if variant_id.blank?
25
+ li = self.line_items.where(:product_id => product_id).first
26
+ else
27
+ li = self.line_items.where(:product_id => product_id, :variant_id => variant_id).first
28
+ end
29
+
30
+ #logger.info("****************** the variant id = #{variant_id}")
31
+
32
+ if li.present?
33
+ li.quantity += quantity.to_i
34
+ li.save
35
+ else
36
+ if variant_id.blank?
37
+ self.line_items.create(:product_id => product_id, :quantity => quantity)
38
+ else
39
+ self.line_items.create(:product_id => product_id, :quantity => quantity, :variant_id => variant_id)
40
+ end
41
+
42
+ end
43
+ end
44
+
45
+ def check_is_current_for_sibling_carts
46
+ if is_current.present? and is_current == true and customer_id.present?
47
+ other_carts = Cart.where(:customer_id => self.customer_id)
48
+ other_carts.each do |cart|
49
+ cart.update_attributes(:is_current => false) if cart.id != self.id
50
+ end
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,28 @@
1
+ class Category < ActiveRecord::Base
2
+
3
+ include Rails.application.routes.url_helpers
4
+ #default_url_options[:host] = request.host_with_port
5
+
6
+
7
+ acts_as_indexed :fields => [:name]
8
+
9
+ validates :name, :presence => true, :uniqueness => true
10
+
11
+
12
+ belongs_to :parent, :class_name => "Category", :foreign_key => "parent_id"
13
+ has_many :children, :class_name => "Category", :foreign_key => "parent_id"
14
+
15
+ has_and_belongs_to_many :products
16
+ has_and_belongs_to_many :banners
17
+
18
+ # Docs for acts_as_nested_set https://github.com/collectiveidea/awesome_nested_set
19
+ acts_as_nested_set :dependent => :destroy # rather than :delete_all
20
+
21
+ def title
22
+ name
23
+ end
24
+
25
+ def url
26
+ category_products_path(id)
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ class Customer < ActiveRecord::Base
2
+
3
+ # Include default devise modules. Others available are:
4
+ # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
5
+ devise :database_authenticatable, :registerable,
6
+ :recoverable, :rememberable, :trackable
7
+
8
+ # Setup accessible (or protected) attributes for your model
9
+ attr_accessible :name, :surname, :contact_number, :email, :password, :password_confirmation #, :remember_me
10
+
11
+ acts_as_indexed :fields => [:name, :surname, :contact_number, :email, :encrypted_password]
12
+
13
+ validates :email, :presence => true, :uniqueness => true
14
+
15
+ has_many :carts
16
+ has_many :addresses
17
+
18
+ if defined?(Order)
19
+ has_many :orders
20
+ end
21
+
22
+ def self.update_customer(id, name, surname, contact_number, email)
23
+ logger.info("********************** params = #{name}")
24
+ this_customer = self.find(id)
25
+ this_customer.update_attributes(:name => name, :surname => surname, :contact_number => contact_number, :email => email)
26
+ this_customer.save!
27
+ end
28
+
29
+ def delivery_address
30
+ addresses.is_default.first
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ class LineItem < ActiveRecord::Base
2
+
3
+ belongs_to :cart
4
+ belongs_to :product
5
+
6
+ # def title was created automatically because you didn't specify a string field
7
+ # when you ran the refinery_engine generator. Love, Refinery CMS.
8
+ def title
9
+ "line item for #{product.name}"
10
+ end
11
+
12
+ def total_price
13
+ if variant_id.present? and defined?(Variant)
14
+ variant.price * quantity
15
+ else
16
+ product.price * quantity
17
+ end
18
+ end
19
+
20
+ def grand_total
21
+ total = 0
22
+ line_items.each do |li|
23
+ total += li.total_price
24
+ end
25
+ total
26
+ end
27
+
28
+ end
@@ -0,0 +1,46 @@
1
+ require 'acts-as-taggable-on'
2
+
3
+ class Product < ActiveRecord::Base
4
+
5
+ acts_as_indexed :fields => [:name, :description, :summary]
6
+
7
+ if defined?(ActsAsTaggableOn)
8
+ acts_as_taggable_on :tags
9
+ end
10
+
11
+ validates :name, :presence => true, :uniqueness => true
12
+ validate :validate_category
13
+
14
+ scope :less_than, lambda { |price| where("price < ?", price) }
15
+ scope :greater_than, lambda { |price| where("price > ?", price) }
16
+
17
+ scope :best_sellers, where(:best_seller => true)
18
+ scope :featured, where(:featured => true)
19
+ scope :new_products, where(:new_product => true)
20
+
21
+ scope :by_category, lambda { |category_id|
22
+ ids = []
23
+ Category.find(category_id).children.each do |child|
24
+ ids << child.id
25
+ end
26
+ ids << category_id
27
+
28
+ joins(:categories).where("categories.id" => ids)
29
+ }
30
+
31
+ belongs_to :image
32
+ has_and_belongs_to_many :categories
33
+ has_many :line_items
34
+
35
+ def title
36
+ name
37
+ end
38
+
39
+ def validate_category
40
+ categories.each do |category|
41
+ if category.children.present?
42
+ errors.add_to_base("Cannot assign product to a category that has sub-categories")
43
+ end
44
+ end
45
+ end
46
+ end