comable-core 0.6.0 → 0.7.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/comable/application_controller.rb +4 -0
- data/app/helpers/comable/application_helper.rb +23 -8
- data/app/helpers/comable/products_helper.rb +0 -63
- data/app/models/comable/image.rb +1 -1
- data/app/models/comable/navigation.rb +12 -0
- data/app/models/comable/navigation_item.rb +52 -0
- data/app/models/comable/option_type.rb +19 -0
- data/app/models/comable/option_value.rb +14 -0
- data/app/models/comable/order.rb +1 -0
- data/app/models/comable/order_item/csvable.rb +1 -1
- data/app/models/comable/order_item.rb +38 -7
- data/app/models/comable/page.rb +3 -1
- data/app/models/comable/payment.rb +1 -1
- data/app/models/comable/product/csvable.rb +1 -0
- data/app/models/comable/product.rb +68 -9
- data/app/models/comable/stock/csvable.rb +5 -6
- data/app/models/comable/stock.rb +45 -8
- data/app/models/comable/store.rb +0 -2
- data/app/models/comable/theme.rb +10 -0
- data/app/models/comable/variant.rb +46 -0
- data/app/models/concerns/comable/cart_owner.rb +6 -2
- data/app/models/concerns/comable/checkout.rb +2 -2
- data/app/models/concerns/comable/linkable.rb +46 -0
- data/app/models/concerns/comable/sku_choice.rb +1 -9
- data/app/uploaders/comable/image_uploader.rb +9 -0
- data/config/locales/en.yml +67 -2
- data/config/locales/ja.yml +66 -2
- data/db/migrate/20150701094210_create_comable_navigation.rb +8 -0
- data/db/migrate/20150706085056_create_comable_navigation_item.rb +15 -0
- data/db/migrate/20150805074914_add_published_at_to_comable_products.rb +9 -0
- data/db/migrate/20150823071425_create_comable_variants.rb +10 -0
- data/db/migrate/20150823072622_create_comable_option_types.rb +10 -0
- data/db/migrate/20150823072955_create_comable_option_values.rb +11 -0
- data/db/migrate/20150823073250_create_comable_variants_option_values.rb +8 -0
- data/db/migrate/20150823073809_change_comable_products_and_comable_stocks.rb +82 -0
- data/db/migrate/20150823102819_change_comable_order_items.rb +50 -0
- data/lib/comable/core.rb +1 -0
- data/lib/comable/deprecator.rb +1 -1
- data/lib/comable/errors.rb +7 -0
- metadata +74 -21
- data/app/uploaders/image_uploader.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfeeb810107eafe21ff7ccc16a8796708892aa08
|
4
|
+
data.tar.gz: af72df7aebb8d185f96c36a9c53ad4ca3a7d769f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b8ad2b68377430abf27f0113075d2ca0771d51b4377765e87663c6e52b63309f39a4b2ad2f59823a0dd23d513ad2763f307a5cc8401b581b7d2139ea4c4ea43
|
7
|
+
data.tar.gz: 909ec7862a42e7f29977abedc6eb1f9af4e99c22298469525c1ae95bac369b82d3e0462a65c01a01d2d51c259067f633200a71c457d4fc90fd65df154441d11c
|
@@ -5,7 +5,9 @@ module Comable
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def current_comable_user
|
8
|
-
resource = current_admin_user
|
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
|
65
|
-
|
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(
|
69
|
-
session.delete(:user_return_to) ||
|
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) ||
|
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) ||
|
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) ||
|
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
|
data/app/models/comable/image.rb
CHANGED
@@ -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
|
data/app/models/comable/order.rb
CHANGED
@@ -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
|
@@ -5,14 +5,16 @@ module Comable
|
|
5
5
|
include Comable::Liquidable
|
6
6
|
include Comable::OrderItem::Csvable
|
7
7
|
|
8
|
-
belongs_to :
|
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:
|
89
|
-
code: stock.code,
|
123
|
+
name: stock.name,
|
90
124
|
price: stock.price,
|
91
|
-
|
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
|
data/app/models/comable/page.rb
CHANGED
@@ -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: :
|
51
|
+
before_transition to: :resumed, do: -> (s) { s.provider_resume! }
|
52
52
|
end
|
53
53
|
|
54
54
|
class << self
|
@@ -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 :
|
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
|
-
|
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
|
52
|
-
|
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
|
-
|
11
|
-
|
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 :
|
18
|
+
delegate :id, to: :product, prefix: true, allow_nil: true
|
19
19
|
|
20
|
-
def
|
21
|
-
|
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
|
data/app/models/comable/stock.rb
CHANGED
@@ -10,7 +10,7 @@ module Comable
|
|
10
10
|
include Comable::Liquidable
|
11
11
|
include Comable::Stock::Csvable
|
12
12
|
|
13
|
-
belongs_to :
|
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
|
-
|
39
|
-
delegate :
|
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: :
|
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
|
data/app/models/comable/store.rb
CHANGED
data/app/models/comable/theme.rb
CHANGED
@@ -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
|