comable-core 0.6.0 → 0.7.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/comable/application_controller.rb +4 -0
  3. data/app/helpers/comable/application_helper.rb +23 -8
  4. data/app/helpers/comable/products_helper.rb +0 -63
  5. data/app/models/comable/image.rb +1 -1
  6. data/app/models/comable/navigation.rb +12 -0
  7. data/app/models/comable/navigation_item.rb +52 -0
  8. data/app/models/comable/option_type.rb +19 -0
  9. data/app/models/comable/option_value.rb +14 -0
  10. data/app/models/comable/order.rb +1 -0
  11. data/app/models/comable/order_item/csvable.rb +1 -1
  12. data/app/models/comable/order_item.rb +38 -7
  13. data/app/models/comable/page.rb +3 -1
  14. data/app/models/comable/payment.rb +1 -1
  15. data/app/models/comable/product/csvable.rb +1 -0
  16. data/app/models/comable/product.rb +68 -9
  17. data/app/models/comable/stock/csvable.rb +5 -6
  18. data/app/models/comable/stock.rb +45 -8
  19. data/app/models/comable/store.rb +0 -2
  20. data/app/models/comable/theme.rb +10 -0
  21. data/app/models/comable/variant.rb +46 -0
  22. data/app/models/concerns/comable/cart_owner.rb +6 -2
  23. data/app/models/concerns/comable/checkout.rb +2 -2
  24. data/app/models/concerns/comable/linkable.rb +46 -0
  25. data/app/models/concerns/comable/sku_choice.rb +1 -9
  26. data/app/uploaders/comable/image_uploader.rb +9 -0
  27. data/config/locales/en.yml +67 -2
  28. data/config/locales/ja.yml +66 -2
  29. data/db/migrate/20150701094210_create_comable_navigation.rb +8 -0
  30. data/db/migrate/20150706085056_create_comable_navigation_item.rb +15 -0
  31. data/db/migrate/20150805074914_add_published_at_to_comable_products.rb +9 -0
  32. data/db/migrate/20150823071425_create_comable_variants.rb +10 -0
  33. data/db/migrate/20150823072622_create_comable_option_types.rb +10 -0
  34. data/db/migrate/20150823072955_create_comable_option_values.rb +11 -0
  35. data/db/migrate/20150823073250_create_comable_variants_option_values.rb +8 -0
  36. data/db/migrate/20150823073809_change_comable_products_and_comable_stocks.rb +82 -0
  37. data/db/migrate/20150823102819_change_comable_order_items.rb +50 -0
  38. data/lib/comable/core.rb +1 -0
  39. data/lib/comable/deprecator.rb +1 -1
  40. data/lib/comable/errors.rb +7 -0
  41. metadata +74 -21
  42. data/app/uploaders/image_uploader.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c695838cc0b5b98cc5c786a0065e9d2e17d6f937
4
- data.tar.gz: c03b1988ad054478da5f280d9c0389017bebaf10
3
+ metadata.gz: bfeeb810107eafe21ff7ccc16a8796708892aa08
4
+ data.tar.gz: af72df7aebb8d185f96c36a9c53ad4ca3a7d769f
5
5
  SHA512:
6
- metadata.gz: c4ef62d68988158a6d985c432a1744ea1e31821eff13a45ebe881da8d9e2180fe9fdaa589ef77d7042e96fed15c1e8c8e9e23d8daa6492e29648cfd2fa04b4fa
7
- data.tar.gz: 2470403342475d734c7d7db9bec17b54d3dd503184525f11134ed6ccd487b17289bd3aa76addb71b915f6732f900f2482ad22c18bfa77e5050951120538d3a64
6
+ metadata.gz: 2b8ad2b68377430abf27f0113075d2ca0771d51b4377765e87663c6e52b63309f39a4b2ad2f59823a0dd23d513ad2763f307a5cc8401b581b7d2139ea4c4ea43
7
+ data.tar.gz: 909ec7862a42e7f29977abedc6eb1f9af4e99c22298469525c1ae95bac369b82d3e0462a65c01a01d2d51c259067f633200a71c457d4fc90fd65df154441d11c
@@ -0,0 +1,4 @@
1
+ module Comable
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -5,7 +5,9 @@ module Comable
5
5
  end
6
6
 
7
7
  def current_comable_user
8
- resource = current_admin_user || current_user || Comable::User.new
8
+ resource = current_admin_user if defined? Comable::Backend
9
+ resource ||= current_user if defined? Comable::Frontend
10
+ resource ||= Comable::User.new
9
11
  resource.with_cookies(cookies)
10
12
  end
11
13
 
@@ -17,6 +19,10 @@ module Comable
17
19
  @curent_trackers ||= (controller_name == 'orders' && action_name == 'create') ? Comable::Tracker.activated : Comable::Tracker.activated.with_place(:everywhere)
18
20
  end
19
21
 
22
+ def current_navigations
23
+ @current_navigations ||= Comable::Navigation.all
24
+ end
25
+
20
26
  def next_order_path
21
27
  comable.next_order_path(state: current_order.state)
22
28
  end
@@ -61,24 +67,33 @@ module Comable
61
67
 
62
68
  private
63
69
 
64
- def after_sign_in_path_for(_resource)
65
- session.delete(:user_return_to) || comable.root_path
70
+ def comable_root_path
71
+ case resource_name
72
+ when :admin_user
73
+ comable.admin_root_path
74
+ else
75
+ defined?(Comable::Frontend) ? comable.root_path : '/'
76
+ end
77
+ end
78
+
79
+ def after_sign_in_path_for(_resource_or_scope)
80
+ session.delete(:user_return_to) || comable_root_path
66
81
  end
67
82
 
68
- def after_sign_out_path_for(_resource)
69
- session.delete(:user_return_to) || comable.root_path
83
+ def after_sign_out_path_for(_scope)
84
+ session.delete(:user_return_to) || comable_root_path
70
85
  end
71
86
 
72
87
  def after_sign_up_path_for(resource)
73
- signed_in_root_path(resource) || comable.root_path
88
+ signed_in_root_path(resource) || comable_root_path
74
89
  end
75
90
 
76
91
  def after_update_path_for(resource)
77
- signed_in_root_path(resource) || comable.root_path
92
+ signed_in_root_path(resource) || comable_root_path
78
93
  end
79
94
 
80
95
  def after_resetting_password_path_for(resource)
81
- signed_in_root_path(resource) || comable.root_path
96
+ signed_in_root_path(resource) || comable_root_path
82
97
  end
83
98
  end
84
99
  end
@@ -15,68 +15,5 @@ module Comable
15
15
  category.name
16
16
  end
17
17
  end
18
-
19
- def sku_table(product, options = nil)
20
- stocks = product.stocks
21
- content_tag(:table, nil, options) do
22
- html = ''
23
- html << build_sku_v_table_header(product, stocks)
24
- html << build_sku_table_rows(product, stocks)
25
- html.html_safe
26
- end
27
- end
28
-
29
- private
30
-
31
- def build_sku_v_table_header(product, stocks)
32
- sku_item_name = product.sku_h_item_name
33
- sku_item_name += '/' + product.sku_v_item_name if product.sku_v?
34
-
35
- html = ''
36
- html << content_tag(:th, sku_item_name)
37
- stocks.group_by(&:sku_h_choice_name).keys.each do |sku_h_choice_name|
38
- html << content_tag(:th, sku_h_choice_name)
39
- end
40
- html.html_safe
41
- end
42
-
43
- def build_sku_table_rows(product, stocks)
44
- return content_tag(:tr, build_sku_table_row(stocks)) unless product.sku_v?
45
-
46
- html = ''
47
- stocks_groups_by_sku_v(stocks).each_pair do |sku_v_choice_name, sku_v_stocks|
48
- html << content_tag(:tr, build_sku_table_row(sku_v_stocks, sku_v_choice_name))
49
- end
50
- html.html_safe
51
- end
52
-
53
- def build_sku_table_row(stocks, sku_v_choice_name = nil)
54
- html = ''
55
- html << content_tag(:th, sku_v_choice_name)
56
- html << stocks.map { |stock| content_tag(:td, build_sku_product_label(stock)) }.join
57
- html.html_safe
58
- end
59
-
60
- def build_sku_product_label(stock)
61
- return unless stock
62
- content_tag(:div, class: 'radio') do
63
- content_tag(:label) do
64
- html = ''
65
- html << radio_button_tag(:stock_id, stock.id, false, disabled: stock.unstocked?)
66
- html << stock.code
67
- html.html_safe
68
- end
69
- end
70
- end
71
-
72
- def stocks_groups_by_sku_v(stocks)
73
- sku_h_choice_names = stocks.group_by(&:sku_h_choice_name).keys
74
-
75
- stocks.group_by(&:sku_v_choice_name).each_with_object({}) do |(sku_v_choice_name, sku_v_stocks), group|
76
- group[sku_v_choice_name] = sku_h_choice_names.map do |sku_h_choice_name|
77
- sku_v_stocks.find { |s| s.sku_h_choice_name == sku_h_choice_name }
78
- end
79
- end
80
- end
81
18
  end
82
19
  end
@@ -2,7 +2,7 @@ module Comable
2
2
  class Image < ActiveRecord::Base
3
3
  include Comable::Liquidable
4
4
 
5
- mount_uploader :file, ImageUploader
5
+ mount_uploader :file, Comable::ImageUploader
6
6
 
7
7
  belongs_to :product, class_name: Comable::Product.name
8
8
 
@@ -0,0 +1,12 @@
1
+ module Comable
2
+ class Navigation < ActiveRecord::Base
3
+ include Comable::Ransackable
4
+
5
+ has_many :navigation_items
6
+
7
+ accepts_nested_attributes_for :navigation_items, allow_destroy: true
8
+
9
+ validates :name, length: { maximum: 255 }, presence: true
10
+ validates :navigation_items, presence: true
11
+ end
12
+ end
@@ -0,0 +1,52 @@
1
+ module Comable
2
+ class NavigationItem < ActiveRecord::Base
3
+ belongs_to :navigation
4
+ belongs_to :linkable, polymorphic: true
5
+
6
+ acts_as_list scope: :navigation
7
+
8
+ validates :linkable, presence: true, if: :linkable_id?
9
+ validates :url, presence: true, unless: :linkable_type?
10
+ validates :url, length: { maximum: 255 }
11
+ validates :name, length: { maximum: 255 }, presence: true
12
+ validates :position, uniqueness: { scope: :navigation_id }
13
+
14
+ class << self
15
+ # TODO: Refactor methods and modules for linkable
16
+ def linkable_params_lists
17
+ [
18
+ web_address_linkable_params, # Web Address
19
+ product_linkable_params, # Product
20
+ page_linkable_params # Page
21
+ ].compact
22
+ end
23
+
24
+ def web_address_linkable_params
25
+ {
26
+ type: nil,
27
+ name: Comable.t('admin.nav.navigation_items.web_address')
28
+ }
29
+ end
30
+
31
+ def product_linkable_params
32
+ return unless Comable::Product.linkable_exists?
33
+ {
34
+ type: Comable::Product.to_s,
35
+ name: Comable.t('products')
36
+ }
37
+ end
38
+
39
+ def page_linkable_params
40
+ return unless Comable::Page.linkable_exists?
41
+ {
42
+ type: Comable::Page.to_s,
43
+ name: Comable.t('pages')
44
+ }
45
+ end
46
+ end
47
+
48
+ def linkable_class
49
+ linkable_type.constantize if linkable_type.present?
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,19 @@
1
+ module Comable
2
+ class OptionType < ActiveRecord::Base
3
+ include Comable::Ransackable
4
+
5
+ has_many :option_values, class_name: Comable::OptionValue.name
6
+
7
+ validates :name, presence: true, length: { maximum: 255 }
8
+
9
+ ransack_options ransackable_attributes: { only: :name }
10
+
11
+ def values
12
+ @values ? @values : option_values.map(&:name)
13
+ end
14
+
15
+ def values=(values)
16
+ @values = values.is_a?(String) ? values.split(' ') : values
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module Comable
2
+ class OptionValue < ActiveRecord::Base
3
+ include Comable::Ransackable
4
+
5
+ belongs_to :option_type, class_name: Comable::OptionType.name
6
+ has_and_belongs_to_many :variants, class_name: Comable::Variant.name, join_table: :comable_variants_option_values
7
+
8
+ accepts_nested_attributes_for :option_type
9
+
10
+ validates :name, presence: true, length: { maximum: 255 }
11
+
12
+ ransack_options ransackable_attributes: { only: :name }
13
+ end
14
+ end
@@ -23,6 +23,7 @@ module Comable
23
23
  delegate :full_name, to: :ship_address, allow_nil: true, prefix: :ship
24
24
  delegate :state, :human_state_name, to: :payment, allow_nil: true, prefix: true
25
25
  delegate :state, :human_state_name, to: :shipment, allow_nil: true, prefix: true
26
+ delegate :cancel!, :resume!, to: :payment, allow_nil: true, prefix: true
26
27
 
27
28
  def complete!
28
29
  ActiveRecord::Base.transaction do
@@ -18,7 +18,7 @@ module Comable
18
18
  __association__ order: { bill_address: :detail }
19
19
  __association__ order: { bill_address: :phone_number }
20
20
  name
21
- code
21
+ sku
22
22
  price
23
23
  sku_h_item_name
24
24
  sku_v_item_name
@@ -5,14 +5,16 @@ module Comable
5
5
  include Comable::Liquidable
6
6
  include Comable::OrderItem::Csvable
7
7
 
8
- belongs_to :stock, class_name: Comable::Stock.name, autosave: true
8
+ belongs_to :variant, class_name: Comable::Variant.name, autosave: true
9
9
  belongs_to :order, class_name: Comable::Order.name, inverse_of: :order_items
10
10
 
11
11
  validates :quantity, numericality: { greater_than: 0 }
12
+ validates :sku, length: { maximum: 255 }
12
13
  validate :valid_stock_quantity
13
14
 
14
15
  liquid_methods :name, :name_with_sku, :code, :quantity, :price, :subtotal_price
15
16
 
17
+ delegate :stock, to: :variant
16
18
  delegate :product, to: :stock
17
19
  delegate :image_url, to: :product
18
20
  delegate :guest_token, to: :order
@@ -58,6 +60,39 @@ module Comable
58
60
  end
59
61
  end
60
62
 
63
+ def sku_h_item_name
64
+ product.option_types.first.try(:name)
65
+ end
66
+
67
+ def sku_v_item_name
68
+ product.option_types.second.try(:name)
69
+ end
70
+
71
+ def sku_h_choice_name
72
+ variant.option_values.first.try(:name)
73
+ end
74
+
75
+ def sku_v_choice_name
76
+ variant.option_values.second.try(:name)
77
+ end
78
+
79
+ def stock=(stock)
80
+ if variant
81
+ variant.stock = stock
82
+ else
83
+ build_variant(stock: stock)
84
+ end
85
+ end
86
+
87
+ #
88
+ # Deprecated methods
89
+ #
90
+ deprecate :stock, deprecator: Comable::Deprecator.instance
91
+ deprecate :sku_h_item_name, deprecator: Comable::Deprecator.instance
92
+ deprecate :sku_v_item_name, deprecator: Comable::Deprecator.instance
93
+ deprecate :sku_h_choice_name, deprecator: Comable::Deprecator.instance
94
+ deprecate :sku_v_choice_name, deprecator: Comable::Deprecator.instance
95
+
61
96
  private
62
97
 
63
98
  def valid_stock_quantity
@@ -85,13 +120,9 @@ module Comable
85
120
 
86
121
  def current_attributes
87
122
  {
88
- name: product.name,
89
- code: stock.code,
123
+ name: stock.name,
90
124
  price: stock.price,
91
- sku_h_item_name: product.sku_h_item_name,
92
- sku_v_item_name: product.sku_v_item_name,
93
- sku_h_choice_name: stock.sku_h_choice_name,
94
- sku_v_choice_name: stock.sku_v_choice_name
125
+ sku: variant.sku
95
126
  }
96
127
  end
97
128
  end
@@ -1,8 +1,10 @@
1
1
  module Comable
2
2
  class Page < ActiveRecord::Base
3
3
  include Comable::Ransackable
4
-
4
+ include Comable::Linkable
5
5
  extend FriendlyId
6
+
7
+ linkable_columns_keys name: :title
6
8
  friendly_id :title, use: :slugged
7
9
 
8
10
  validates :title, length: { maximum: 255 }, presence: true
@@ -48,7 +48,7 @@ module Comable
48
48
  before_transition to: :ready, do: -> (s) { s.provider_authorize! }
49
49
  before_transition to: :completed, do: -> (s) { s.complete! }
50
50
  before_transition to: :canceled, do: -> (s) { s.provider_cancel! }
51
- before_transition to: :canceled, do: -> (s) { s.provider_resume! }
51
+ before_transition to: :resumed, do: -> (s) { s.provider_resume! }
52
52
  end
53
53
 
54
54
  class << self
@@ -11,6 +11,7 @@ module Comable
11
11
  code
12
12
  price
13
13
  caption
14
+ published_at
14
15
  sku_h_item_name
15
16
  sku_v_item_name
16
17
  end
@@ -5,22 +5,26 @@ module Comable
5
5
  include Comable::Liquidable
6
6
  include Comable::Product::Search
7
7
  include Comable::Product::Csvable
8
+ include Comable::Linkable
8
9
 
9
- has_many :stocks, class_name: Comable::Stock.name, dependent: :destroy
10
+ has_many :variants, class_name: Comable::Variant.name, inverse_of: :product, dependent: :destroy
10
11
  has_many :images, class_name: Comable::Image.name, dependent: :destroy
11
12
  has_and_belongs_to_many :categories, class_name: Comable::Category.name, join_table: :comable_products_categories
12
13
 
14
+ accepts_nested_attributes_for :variants, allow_destroy: true
13
15
  accepts_nested_attributes_for :images, allow_destroy: true
14
16
 
17
+ scope :published, -> (published_at = nil) { where('published_at <= ?', published_at || Time.now) }
18
+
15
19
  validates :name, presence: true, length: { maximum: 255 }
16
- validates :code, presence: true, length: { maximum: 255 }
17
- validates :price, presence: true, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
18
- validates :sku_h_item_name, length: { maximum: 255 }
19
- validates :sku_v_item_name, length: { maximum: 255 }
20
20
 
21
21
  liquid_methods :id, :code, :name, :price, :images, :image_url
22
22
 
23
- ransack_options attribute_select: { associations: :stocks }
23
+ ransack_options attribute_select: { associations: [:variants, :stocks, :option_types] }
24
+
25
+ linkable_columns_keys use_index: true
26
+
27
+ PREVIEW_SESSION_KEY = :preview_product
24
28
 
25
29
  # Add conditions for the images association.
26
30
  # Override method of the images association to support Rails 3.x.
@@ -42,14 +46,69 @@ module Comable
42
46
  !stocked?
43
47
  end
44
48
 
49
+ def published?
50
+ published_at.present? && published_at <= Time.now
51
+ end
52
+
45
53
  def category_path_names=(category_path_names, delimiter: Comable::Category::DEFAULT_PATH_NAME_DELIMITER)
46
54
  self.categories = Comable::Category.find_by_path_names(category_path_names, delimiter: delimiter)
47
55
  end
48
56
 
49
- private
57
+ def master?
58
+ option_types.empty?
59
+ end
60
+
61
+ def sku_h_item_name
62
+ option_types.first.try(:name)
63
+ end
64
+
65
+ def sku_v_item_name
66
+ option_types.second.try(:name)
67
+ end
68
+
69
+ def code
70
+ variants.first.try(:sku)
71
+ end
72
+
73
+ def code=(code)
74
+ variants.each { |v| v.sku = code }
75
+ end
76
+
77
+ def price
78
+ variants.first.try(:price)
79
+ end
50
80
 
51
- def create_stock
52
- stocks.create(code: code) unless stocks.exists?
81
+ def price=(price)
82
+ variants.each { |v| v.price = price }
53
83
  end
84
+
85
+ has_many :stocks, class_name: Comable::Stock.name, through: :variants
86
+
87
+ def stocks=(stocks)
88
+ stocks.map { |stock| variants.build(stock: stock) }
89
+ end
90
+
91
+ def build_option_type
92
+ Comable::OptionType.new
93
+ end
94
+
95
+ def option_types
96
+ option_types = variants.map { |variant| variant.option_values.map(&:option_type) }.flatten.uniq
97
+ option_types.singleton_class.send(:define_method, :build, -> { Comable::OptionType.new })
98
+ option_types
99
+ end
100
+
101
+ def option_types_attributes=(_option_types_attributes)
102
+ end
103
+
104
+ #
105
+ # Deprecated methods
106
+ #
107
+ deprecate :stocks, deprecator: Comable::Deprecator.instance
108
+ deprecate :sku_h_item_name, deprecator: Comable::Deprecator.instance
109
+ deprecate :sku_v_item_name, deprecator: Comable::Deprecator.instance
110
+ deprecate :code, deprecator: Comable::Deprecator.instance
111
+ deprecate :code=, deprecator: Comable::Deprecator.instance
112
+ deprecate :option_types_attributes=, deprecator: Comable::Deprecator.instance
54
113
  end
55
114
  end
@@ -7,19 +7,18 @@ module Comable
7
7
 
8
8
  included do
9
9
  comma do
10
- product_code
11
- code
10
+ product_id
11
+ id
12
12
  quantity
13
13
  sku_h_choice_name
14
14
  sku_v_choice_name
15
15
  end
16
16
  end
17
17
 
18
- delegate :code, to: :product, prefix: true, allow_nil: true
18
+ delegate :id, to: :product, prefix: true, allow_nil: true
19
19
 
20
- def product_code=(code)
21
- return if product_code == code
22
- self.product = Comable::Product.find_by(code: code)
20
+ def product_id=(id)
21
+ self.product = Comable::Product.find_by(id: id)
23
22
  end
24
23
  end
25
24
  end
@@ -10,7 +10,7 @@ module Comable
10
10
  include Comable::Liquidable
11
11
  include Comable::Stock::Csvable
12
12
 
13
- belongs_to :product, class_name: Comable::Product.name
13
+ belongs_to :variant, class_name: Comable::Variant.name, inverse_of: :stock
14
14
 
15
15
  #
16
16
  # @!group Scope
@@ -28,19 +28,16 @@ module Comable
28
28
  # @!endgroup
29
29
  #
30
30
 
31
- validates :product, presence: { message: Comable.t('admin.is_not_exists') }
32
- validates :code, presence: true, length: { maximum: 255 }
33
- validates :sku_h_choice_name, length: { maximum: 255 }
34
- validates :sku_v_choice_name, length: { maximum: 255 }
35
31
  # TODO: add conditions (by limitless flag, backoder flag and etc..)
36
32
  validates :quantity, numericality: { greater_than_or_equal_to: 0 }
37
33
 
38
- delegate :name, to: :product
39
- delegate :price, to: :product
34
+ # TODO: Remove the columns for compatible
35
+ delegate :product, to: :variant
36
+ delegate :price, to: :variant
40
37
  delegate :sku_h_item_name, to: :product
41
38
  delegate :sku_v_item_name, to: :product
42
39
 
43
- ransack_options attribute_select: { associations: :product }, ransackable_attributes: { except: :product_id }
40
+ ransack_options attribute_select: { associations: :variant }, ransackable_attributes: { only: :quantity }
44
41
 
45
42
  # 在庫の有無を取得する
46
43
  #
@@ -67,5 +64,45 @@ module Comable
67
64
  def unstocked?(quantity: 1)
68
65
  !stocked?(quantity: quantity)
69
66
  end
67
+
68
+ def name
69
+ if variant.options.any?
70
+ "#{variant.product.name} (#{variant.options.map(&:value).join('/')})"
71
+ else
72
+ variant.product.name
73
+ end
74
+ end
75
+
76
+ def sku_h_choice_name
77
+ variant.option_values.first.try(:name)
78
+ end
79
+
80
+ def sku_v_choice_name
81
+ variant.option_values.second.try(:name)
82
+ end
83
+
84
+ def code
85
+ variant.sku
86
+ end
87
+
88
+ def product=(product)
89
+ if variant
90
+ variant.product = product
91
+ else
92
+ build_variant(product: product)
93
+ end
94
+ end
95
+
96
+ #
97
+ # Deprecated methods
98
+ #
99
+ deprecate :product, deprecator: Comable::Deprecator.instance
100
+ deprecate :name, deprecator: Comable::Deprecator.instance
101
+ deprecate :code, deprecator: Comable::Deprecator.instance
102
+ deprecate :price, deprecator: Comable::Deprecator.instance
103
+ deprecate :sku_h_item_name, deprecator: Comable::Deprecator.instance
104
+ deprecate :sku_v_item_name, deprecator: Comable::Deprecator.instance
105
+ deprecate :sku_h_choice_name, deprecator: Comable::Deprecator.instance
106
+ deprecate :sku_v_choice_name, deprecator: Comable::Deprecator.instance
70
107
  end
71
108
  end
@@ -11,8 +11,6 @@ module Comable
11
11
 
12
12
  liquid_methods :name, :meta_keywords, :meta_description, :email
13
13
 
14
- delegate :name, to: :theme, prefix: true, allow_nil: true
15
-
16
14
  class << self
17
15
  def instance
18
16
  first || new(name: default_name)
@@ -10,6 +10,16 @@ module Comable
10
10
  validates :homepage, length: { maximum: 255 }
11
11
  validates :author, length: { maximum: 255 }
12
12
 
13
+ class << self
14
+ def dir
15
+ Rails.root.join('themes')
16
+ end
17
+ end
18
+
19
+ def dir
20
+ self.class.dir + name
21
+ end
22
+
13
23
  def default_version
14
24
  '0.1.0'
15
25
  end
@@ -0,0 +1,46 @@
1
+ module Comable
2
+ class Variant < ActiveRecord::Base
3
+ include Comable::Ransackable
4
+
5
+ belongs_to :product, class_name: Comable::Product.name, inverse_of: :variants
6
+ has_one :stock, class_name: Comable::Stock.name, inverse_of: :variant, dependent: :destroy, autosave: true
7
+
8
+ has_and_belongs_to_many :option_values, class_name: Comable::OptionValue.name, join_table: :comable_variants_option_values
9
+
10
+ accepts_nested_attributes_for :option_values, allow_destroy: true
11
+ accepts_nested_attributes_for :stock
12
+
13
+ validates :product, presence: { message: Comable.t('admin.is_not_exists') }
14
+ validates :price, presence: true, numericality: { greater_than_or_equal_to: 0 }
15
+ validates :sku, length: { maximum: 255 }
16
+
17
+ ransack_options attribute_select: { associations: [:product, :stock, :option_values] }, ransackable_attributes: { except: :product_id }
18
+
19
+ def quantity
20
+ stock.try(:quantity) || build_stock.quantity
21
+ end
22
+
23
+ def quantity=(quantity)
24
+ if stock
25
+ stock.quantity = quantity
26
+ else
27
+ build_stock(quantity: quantity)
28
+ end
29
+ end
30
+
31
+ def options
32
+ option_values.map do |option_value|
33
+ OpenStruct.new(type: option_value.option_type.try(:name), value: option_value.name)
34
+ end
35
+ end
36
+
37
+ def options=(options)
38
+ options = JSON.parse(options) if options.is_a? String
39
+ self.option_values = options.map do |option|
40
+ hash = option.symbolize_keys
41
+ option_type = Comable::OptionType.where(name: hash[:name]).first_or_initialize(&:save!)
42
+ Comable::OptionValue.where(name: hash[:value], option_type: option_type).first_or_initialize(&:save!)
43
+ end
44
+ end
45
+ end
46
+ end