shoperb-theme-editor 0.8.0
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.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +40 -0
- data/LICENSE.md +21 -0
- data/README.md +124 -0
- data/bin/shoperb +313 -0
- data/lib/shoperb_theme_editor/api/server.rb +10 -0
- data/lib/shoperb_theme_editor/api/views/callback.erb +53 -0
- data/lib/shoperb_theme_editor/api.rb +264 -0
- data/lib/shoperb_theme_editor/build/json.rb +167 -0
- data/lib/shoperb_theme_editor/build/liquid.rb +38 -0
- data/lib/shoperb_theme_editor/build/section.rb +51 -0
- data/lib/shoperb_theme_editor/build/settings.rb +224 -0
- data/lib/shoperb_theme_editor/build.rb +68 -0
- data/lib/shoperb_theme_editor/configuration.rb +98 -0
- data/lib/shoperb_theme_editor/error.rb +35 -0
- data/lib/shoperb_theme_editor/ext/array.rb +17 -0
- data/lib/shoperb_theme_editor/ext/nil_class.rb +7 -0
- data/lib/shoperb_theme_editor/ext/sequel.rb +82 -0
- data/lib/shoperb_theme_editor/ext.rb +2 -0
- data/lib/shoperb_theme_editor/init.rb +87 -0
- data/lib/shoperb_theme_editor/logger.rb +58 -0
- data/lib/shoperb_theme_editor/mounter/models/address.rb +65 -0
- data/lib/shoperb_theme_editor/mounter/models/attribute.rb +11 -0
- data/lib/shoperb_theme_editor/mounter/models/attribute_key.rb +17 -0
- data/lib/shoperb_theme_editor/mounter/models/base.rb +196 -0
- data/lib/shoperb_theme_editor/mounter/models/blog_category.rb +47 -0
- data/lib/shoperb_theme_editor/mounter/models/blog_post.rb +45 -0
- data/lib/shoperb_theme_editor/mounter/models/brand.rb +11 -0
- data/lib/shoperb_theme_editor/mounter/models/cart.rb +35 -0
- data/lib/shoperb_theme_editor/mounter/models/cart_item.rb +71 -0
- data/lib/shoperb_theme_editor/mounter/models/category.rb +99 -0
- data/lib/shoperb_theme_editor/mounter/models/collection.rb +40 -0
- data/lib/shoperb_theme_editor/mounter/models/country.rb +18 -0
- data/lib/shoperb_theme_editor/mounter/models/currency.rb +17 -0
- data/lib/shoperb_theme_editor/mounter/models/custom_field.rb +22 -0
- data/lib/shoperb_theme_editor/mounter/models/customer.rb +77 -0
- data/lib/shoperb_theme_editor/mounter/models/customer_customer_group.rb +12 -0
- data/lib/shoperb_theme_editor/mounter/models/customer_group.rb +13 -0
- data/lib/shoperb_theme_editor/mounter/models/customer_subscription.rb +40 -0
- data/lib/shoperb_theme_editor/mounter/models/customer_subscription_plan.rb +32 -0
- data/lib/shoperb_theme_editor/mounter/models/discount.rb +40 -0
- data/lib/shoperb_theme_editor/mounter/models/discount_variant.rb +15 -0
- data/lib/shoperb_theme_editor/mounter/models/image.rb +51 -0
- data/lib/shoperb_theme_editor/mounter/models/language.rb +17 -0
- data/lib/shoperb_theme_editor/mounter/models/link.rb +61 -0
- data/lib/shoperb_theme_editor/mounter/models/media_file.rb +19 -0
- data/lib/shoperb_theme_editor/mounter/models/menu.rb +21 -0
- data/lib/shoperb_theme_editor/mounter/models/meta.rb +10 -0
- data/lib/shoperb_theme_editor/mounter/models/news_item.rb +11 -0
- data/lib/shoperb_theme_editor/mounter/models/order.rb +133 -0
- data/lib/shoperb_theme_editor/mounter/models/order_item.rb +137 -0
- data/lib/shoperb_theme_editor/mounter/models/order_item_attribute.rb +17 -0
- data/lib/shoperb_theme_editor/mounter/models/order_return.rb +42 -0
- data/lib/shoperb_theme_editor/mounter/models/order_return_item.rb +29 -0
- data/lib/shoperb_theme_editor/mounter/models/order_return_item_entity.rb +25 -0
- data/lib/shoperb_theme_editor/mounter/models/order_return_parcel.rb +20 -0
- data/lib/shoperb_theme_editor/mounter/models/page.rb +26 -0
- data/lib/shoperb_theme_editor/mounter/models/payment_card.rb +21 -0
- data/lib/shoperb_theme_editor/mounter/models/payment_method.rb +67 -0
- data/lib/shoperb_theme_editor/mounter/models/payment_provider.rb +23 -0
- data/lib/shoperb_theme_editor/mounter/models/product.rb +144 -0
- data/lib/shoperb_theme_editor/mounter/models/product_attribute.rb +32 -0
- data/lib/shoperb_theme_editor/mounter/models/product_search.rb +53 -0
- data/lib/shoperb_theme_editor/mounter/models/product_type.rb +21 -0
- data/lib/shoperb_theme_editor/mounter/models/review.rb +38 -0
- data/lib/shoperb_theme_editor/mounter/models/search.rb +11 -0
- data/lib/shoperb_theme_editor/mounter/models/shipping_method.rb +39 -0
- data/lib/shoperb_theme_editor/mounter/models/shop.rb +58 -0
- data/lib/shoperb_theme_editor/mounter/models/state.rb +17 -0
- data/lib/shoperb_theme_editor/mounter/models/theme.rb +89 -0
- data/lib/shoperb_theme_editor/mounter/models/variant.rb +96 -0
- data/lib/shoperb_theme_editor/mounter/models/variant_attribute.rb +46 -0
- data/lib/shoperb_theme_editor/mounter/models/vendor.rb +38 -0
- data/lib/shoperb_theme_editor/mounter/server/assets.rb +35 -0
- data/lib/shoperb_theme_editor/mounter/server/defaults.rb +44 -0
- data/lib/shoperb_theme_editor/mounter/server/exception_handler.rb +22 -0
- data/lib/shoperb_theme_editor/mounter/server/partials/_shoperb_footer.liquid +0 -0
- data/lib/shoperb_theme_editor/mounter/server/partials/_shoperb_header.liquid +0 -0
- data/lib/shoperb_theme_editor/mounter/server/partials/_shoperb_stylesheets.liquid +3 -0
- data/lib/shoperb_theme_editor/mounter/server/renderer.rb +166 -0
- data/lib/shoperb_theme_editor/mounter/server/routes/cart.rb +127 -0
- data/lib/shoperb_theme_editor/mounter/server/routes/dummy.rb +34 -0
- data/lib/shoperb_theme_editor/mounter/server/routes/locale.rb +31 -0
- data/lib/shoperb_theme_editor/mounter/server/routes/pages.rb +33 -0
- data/lib/shoperb_theme_editor/mounter/server/routes/search.rb +18 -0
- data/lib/shoperb_theme_editor/mounter/server/routes.rb +366 -0
- data/lib/shoperb_theme_editor/mounter/server/routes_helper.rb +278 -0
- data/lib/shoperb_theme_editor/mounter/server.rb +66 -0
- data/lib/shoperb_theme_editor/mounter.rb +30 -0
- data/lib/shoperb_theme_editor/os.rb +13 -0
- data/lib/shoperb_theme_editor/package.rb +81 -0
- data/lib/shoperb_theme_editor/sync/images.rb +69 -0
- data/lib/shoperb_theme_editor/sync/pagination.rb +52 -0
- data/lib/shoperb_theme_editor/sync.rb +229 -0
- data/lib/shoperb_theme_editor/translations.rb +22 -0
- data/lib/shoperb_theme_editor/utils.rb +50 -0
- data/lib/shoperb_theme_editor.rb +159 -0
- data/shoperb_theme_editor.gemspec +60 -0
- metadata +510 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class Address < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
fields :id, :owner_id, :owner_type, :country_id, :state_id, :name,
|
9
|
+
:first_name, :last_name, :phone, :company, :county, :city, :zip,
|
10
|
+
:type,
|
11
|
+
:address1, :address2, :checksum, :account_type, :business, :email
|
12
|
+
|
13
|
+
belongs_to :country
|
14
|
+
belongs_to :state
|
15
|
+
|
16
|
+
def country_code= val
|
17
|
+
self.country = Country.all.detect{|o| o.code == val}
|
18
|
+
end
|
19
|
+
|
20
|
+
def state_name
|
21
|
+
state.try(:name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def order_name
|
25
|
+
order.try(:name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def full_name
|
29
|
+
[first_name.presence, last_name.presence].reject(&:blank?).join(" ")
|
30
|
+
end
|
31
|
+
|
32
|
+
def full_address
|
33
|
+
[address1.presence, address2.presence].reject(&:blank?).join(", ")
|
34
|
+
end
|
35
|
+
|
36
|
+
def company_with_phone
|
37
|
+
[company, phone].reject(&:blank?).join(", ")
|
38
|
+
end
|
39
|
+
|
40
|
+
def state_with_country
|
41
|
+
[state_name.presence, country_name.presence].reject(&:blank?).join(", ")
|
42
|
+
end
|
43
|
+
|
44
|
+
def city_state_with_zip
|
45
|
+
[city.presence, state_name.presence, zip.presence].reject(&:blank?).join(", ")
|
46
|
+
end
|
47
|
+
|
48
|
+
def zip_with_city
|
49
|
+
[zip.presence, city.presence].reject(&:blank?).join(", ")
|
50
|
+
end
|
51
|
+
|
52
|
+
def country_name
|
53
|
+
country&.localized_name
|
54
|
+
end
|
55
|
+
|
56
|
+
def owner
|
57
|
+
(Model.const_get(owner_type, false) rescue nil).try { |klass|
|
58
|
+
klass.all.detect { |obj| obj.attributes[:id] == owner_id }
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end end end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class AttributeKey < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
fields :id, :name, :handle, :creator_type
|
8
|
+
|
9
|
+
translates :name
|
10
|
+
|
11
|
+
def self.primary_key
|
12
|
+
:id
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end end end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class Base
|
5
|
+
|
6
|
+
module SequelClass
|
7
|
+
def fields(*args)
|
8
|
+
@fields_list ||= []
|
9
|
+
@fields_list |= args
|
10
|
+
c_fields(*args, cast: String)
|
11
|
+
end
|
12
|
+
|
13
|
+
def c_fields(*args, **opts)
|
14
|
+
@fields_casted ||= {}
|
15
|
+
args.each do |field|
|
16
|
+
@fields_casted[field] = opts
|
17
|
+
case opts[:cast].to_s
|
18
|
+
when JSON.to_s, Array.to_s
|
19
|
+
define_method field do
|
20
|
+
JSON.parse(@values[field.to_sym]) if @values[field.to_sym]
|
21
|
+
end
|
22
|
+
when BigDecimal.to_s
|
23
|
+
define_method field do
|
24
|
+
BigDecimal(@values[field.to_sym]) if @values[field.to_sym]
|
25
|
+
end
|
26
|
+
when Integer.to_s
|
27
|
+
define_method field do
|
28
|
+
Integer(@values[field.to_sym]) if @values[field.to_sym]
|
29
|
+
end
|
30
|
+
when TrueClass.to_s
|
31
|
+
define_method field do
|
32
|
+
@values[field.to_sym] == "1" || @values[field.to_sym] == "T"
|
33
|
+
end
|
34
|
+
define_method "#{field}?" do
|
35
|
+
public_send field
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def belongs_to(*args, **args2)
|
42
|
+
many_to_one(*args, **args2)
|
43
|
+
end
|
44
|
+
def has_many(*args, **args2)
|
45
|
+
one_to_many(*args, **args2)
|
46
|
+
args.each do |meth|
|
47
|
+
define_method meth do
|
48
|
+
public_send("#{meth}_dataset")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_by(*args, **args2)
|
54
|
+
find(**args2)
|
55
|
+
end
|
56
|
+
|
57
|
+
def includes(*args)
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def sum(*args)
|
62
|
+
super || 0
|
63
|
+
end
|
64
|
+
|
65
|
+
def size
|
66
|
+
count
|
67
|
+
end
|
68
|
+
|
69
|
+
def sample
|
70
|
+
all.sample
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def translates *args
|
75
|
+
c_fields :translations, cast: JSON
|
76
|
+
|
77
|
+
args.each do |arg|
|
78
|
+
define_method arg do |*_|
|
79
|
+
((translations || {})[Translations.locale] || {}).fetch(arg.to_s, @values[arg])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def assign(records)
|
85
|
+
db = ::Sequel::Model.db
|
86
|
+
create_table
|
87
|
+
|
88
|
+
data = records.map do |record|
|
89
|
+
@fields_casted.each_with_object([]) do |(field, opts), arr|
|
90
|
+
if opts[:cast].to_s == "TrueClass"
|
91
|
+
record[field.to_s] = record[field.to_s] ? '1' : '0'
|
92
|
+
end
|
93
|
+
|
94
|
+
if db.schema(table_name).to_h[field][:db_type] == "TEXT" && record[field.to_s] && !record[field.to_s].is_a?(String)
|
95
|
+
arr.push(JSON.dump( record[field.to_s] ))
|
96
|
+
else
|
97
|
+
arr.push( ( record[field.to_s] ))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
db[table_name].import(@fields_casted.keys, data)
|
102
|
+
rescue=>e
|
103
|
+
binding.pry
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_table
|
107
|
+
fields = @fields_casted
|
108
|
+
db = ::Sequel::Model.db
|
109
|
+
db.create_table(table_name) do
|
110
|
+
fields.each do |field, opts|
|
111
|
+
case field.to_s
|
112
|
+
when "id"
|
113
|
+
primary_key :id
|
114
|
+
when /_id$/, "lft", "rgt", "level"
|
115
|
+
Integer field
|
116
|
+
else
|
117
|
+
case opts[:cast].to_s
|
118
|
+
when BigDecimal.to_s
|
119
|
+
BigDecimal field
|
120
|
+
when Integer.to_s
|
121
|
+
Integer field
|
122
|
+
when TrueClass
|
123
|
+
Boolean field
|
124
|
+
else
|
125
|
+
text field
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end if db["SELECT count(*) a FROM sqlite_master WHERE type='table' AND name='#{table_name}'"].first[:a] == 0
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
module Sequel
|
136
|
+
extend ActiveSupport::Concern
|
137
|
+
|
138
|
+
included do
|
139
|
+
dataset_module do
|
140
|
+
def none
|
141
|
+
where(Sequel.lit("1=1"))
|
142
|
+
end
|
143
|
+
|
144
|
+
def as_dataset(relation)
|
145
|
+
filter(id: relation.map(&:id))
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
c_fields :custom_field_values, cast: JSON
|
150
|
+
end
|
151
|
+
|
152
|
+
def to_liquid context=nil
|
153
|
+
if klass = (ShoperbLiquid.const_get("#{self.class.to_s.demodulize}Drop"))
|
154
|
+
klass.new(self).tap do |drop|
|
155
|
+
drop.context = context if context
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def attributes
|
161
|
+
@values
|
162
|
+
end
|
163
|
+
|
164
|
+
def id
|
165
|
+
self.class.primary_key.to_s == "id" ? super : send(self.class.primary_key)
|
166
|
+
end
|
167
|
+
|
168
|
+
def as_dataset(relation)
|
169
|
+
self.class.as_dataset(relation)
|
170
|
+
end
|
171
|
+
|
172
|
+
def to_param
|
173
|
+
respond_to?(:permalink) ? permalink : id
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
class << self
|
178
|
+
|
179
|
+
def save
|
180
|
+
Cart.create_table
|
181
|
+
CartItem.create_table
|
182
|
+
|
183
|
+
[
|
184
|
+
Order, OrderItem, OrderReturn, OrderReturnItem, OrderReturnItemEntity,
|
185
|
+
OrderReturnParcel, PaymentCard, PaymentMethod,
|
186
|
+
PaymentProvider, ShippingMethod
|
187
|
+
].each do |klass|
|
188
|
+
klass.assign(klass.raw_data.map(&:stringify_keys))
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end end end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class BlogCategory < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
|
9
|
+
fields :id, :state, :name, :permalink, :description,
|
10
|
+
:handle, :translations
|
11
|
+
|
12
|
+
translates :name, :description
|
13
|
+
|
14
|
+
def self.primary_key
|
15
|
+
:id
|
16
|
+
end
|
17
|
+
|
18
|
+
dataset_module do
|
19
|
+
def active
|
20
|
+
as_dataset(to_a.select(&:active?))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
has_many :blog_posts
|
25
|
+
|
26
|
+
def self.sorted
|
27
|
+
sort_by { |root| root.position }
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
def active?
|
33
|
+
state == "active"
|
34
|
+
end
|
35
|
+
|
36
|
+
def images
|
37
|
+
Image.all.select { |image| image.entity == self }
|
38
|
+
end
|
39
|
+
|
40
|
+
def image
|
41
|
+
images.first
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end end end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class BlogPost < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
fields :id, :name, :content, :published_at, :permalink, :template,
|
9
|
+
:handle, :next_id, :prev_id, :state
|
10
|
+
|
11
|
+
translates :name, :content
|
12
|
+
belongs_to :category, class: :BlogCategory
|
13
|
+
|
14
|
+
def self.primary_key
|
15
|
+
:permalink
|
16
|
+
end
|
17
|
+
|
18
|
+
def active?
|
19
|
+
published_at.nil? || published_at <= Time.now
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.active
|
23
|
+
all.select(&:active?)
|
24
|
+
end
|
25
|
+
|
26
|
+
def next
|
27
|
+
BlogPost.active.detect { |post| post.attributes[:id] == self.next_id }
|
28
|
+
end
|
29
|
+
|
30
|
+
def prev
|
31
|
+
BlogPost.active.detect { |post| post.attributes[:id] == self.prev_id }
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def images
|
36
|
+
Image.all.select { |image| image.entity == self }
|
37
|
+
end
|
38
|
+
|
39
|
+
def image
|
40
|
+
images.first
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end end end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class Cart < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
fields :id, :token
|
9
|
+
|
10
|
+
attr_accessor :customer
|
11
|
+
|
12
|
+
def self.primary_key
|
13
|
+
:token
|
14
|
+
end
|
15
|
+
|
16
|
+
def items
|
17
|
+
CartItem
|
18
|
+
end
|
19
|
+
|
20
|
+
def total
|
21
|
+
items.to_a.sum(&:total)
|
22
|
+
end
|
23
|
+
|
24
|
+
def weight
|
25
|
+
items.to_a.sum(&:weight)
|
26
|
+
end
|
27
|
+
|
28
|
+
def require_shipping?
|
29
|
+
items.to_a.any?(&:require_shipping?)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end end end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class CartItem < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
fields :variant_sku, :name, :created_at, :updated_at
|
9
|
+
c_fields :id, cast: Integer
|
10
|
+
c_fields :amount, cast: BigDecimal
|
11
|
+
c_fields :variant_id, cast: Integer
|
12
|
+
c_fields :by_subscription, cast: TrueClass
|
13
|
+
|
14
|
+
belongs_to :variant
|
15
|
+
|
16
|
+
def self.primary_key
|
17
|
+
:id
|
18
|
+
end
|
19
|
+
|
20
|
+
delegate :product, to: :variant
|
21
|
+
delegate :sku, to: :variant
|
22
|
+
delegate :require_shipping?, to: :variant
|
23
|
+
|
24
|
+
def cart
|
25
|
+
Cart.first
|
26
|
+
end
|
27
|
+
|
28
|
+
def weight
|
29
|
+
amount * variant.weight.to_d
|
30
|
+
end
|
31
|
+
|
32
|
+
def total
|
33
|
+
amount * overwritten_price(variant.active_price.to_d)
|
34
|
+
end
|
35
|
+
|
36
|
+
def neto_total
|
37
|
+
amount * overwritten_price(variant.neto_active_price.to_d)
|
38
|
+
end
|
39
|
+
|
40
|
+
def bruto_total
|
41
|
+
amount * overwritten_price(variant.bruto_active_price.to_d)
|
42
|
+
end
|
43
|
+
|
44
|
+
def price
|
45
|
+
overwritten_price(variant.price)
|
46
|
+
end
|
47
|
+
|
48
|
+
def low_on_stock?
|
49
|
+
variant.present? && variant.available? && !variant.available?(:warehouse, amount)
|
50
|
+
end
|
51
|
+
|
52
|
+
def out_of_stock?
|
53
|
+
variant.nil? || !variant.available? || !variant.available?(:warehouse, amount)
|
54
|
+
end
|
55
|
+
|
56
|
+
def item_original_id
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def overwritten_price sum
|
61
|
+
if by_subscription
|
62
|
+
0.to_d
|
63
|
+
else
|
64
|
+
sum
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end end end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class Category < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
|
9
|
+
fields :id, :parent_id, :state, :name, :permalink, :description,
|
10
|
+
:lft, :rgt, :handle, :translations
|
11
|
+
|
12
|
+
translates :name, :description
|
13
|
+
fields :level
|
14
|
+
|
15
|
+
def self.primary_key
|
16
|
+
:id
|
17
|
+
end
|
18
|
+
|
19
|
+
dataset_module do
|
20
|
+
def roots
|
21
|
+
as_dataset(sorted.to_a.select(&:root?))
|
22
|
+
end
|
23
|
+
|
24
|
+
def active
|
25
|
+
as_dataset(to_a.select(&:active?))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
has_many :products
|
30
|
+
|
31
|
+
def parent
|
32
|
+
Category.active.detect { |parent| parent.attributes[:id] == self.parent_id }
|
33
|
+
end
|
34
|
+
|
35
|
+
def children
|
36
|
+
Category.active.where(parent_id: id)
|
37
|
+
end
|
38
|
+
|
39
|
+
def ancestors
|
40
|
+
as_dataset(self_and_ancestors.to_a.reject { |category| category.id == id })
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.sorted
|
44
|
+
sort_by { |root| root.lft }
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def self.active_roots
|
49
|
+
roots.select(&:active?)
|
50
|
+
end
|
51
|
+
|
52
|
+
def root
|
53
|
+
ancestors.last || self
|
54
|
+
end
|
55
|
+
|
56
|
+
def root?
|
57
|
+
parent_id.nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
def active?
|
61
|
+
state == "active"
|
62
|
+
end
|
63
|
+
|
64
|
+
def products_with_children
|
65
|
+
ids = products.map(&:id) | children.map(&:products_with_children).flatten.map(&:id)
|
66
|
+
Product.where(id: ids)
|
67
|
+
end
|
68
|
+
|
69
|
+
def products_for_self_and_children
|
70
|
+
arr = self_and_descendants.map(&:id)
|
71
|
+
Product.where(id: Product.active.to_a.select { |product| arr.include?(product.category_id) }.map(&:id))
|
72
|
+
end
|
73
|
+
|
74
|
+
def descends_from(category)
|
75
|
+
self_and_ancestors.include?(category)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self_and_ancestors
|
79
|
+
as_dataset(Category.active.to_a.select { |category| category.lft.to_i <= lft.to_i && category.rgt.to_i >= rgt.to_i })
|
80
|
+
end
|
81
|
+
|
82
|
+
def self_and_descendants
|
83
|
+
Category.active.to_a.select do |category|
|
84
|
+
category.ancestors.include?(self) || category.id == id
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def images
|
89
|
+
Image.all.select { |image| image.entity == self }
|
90
|
+
end
|
91
|
+
|
92
|
+
def image
|
93
|
+
images.first
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end end end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class Collection < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
fields :id, :name, :permalink, :handle, :image_id, :description
|
9
|
+
c_fields :product_ids, cast: Array
|
10
|
+
|
11
|
+
translates :name
|
12
|
+
|
13
|
+
def self.primary_key
|
14
|
+
:permalink
|
15
|
+
end
|
16
|
+
|
17
|
+
def products
|
18
|
+
Product.active.where(id: product_ids)
|
19
|
+
end
|
20
|
+
|
21
|
+
def vendors
|
22
|
+
Vendor.where(id: products.map(&:vendor).uniq.compact.map(&:id) )
|
23
|
+
end
|
24
|
+
|
25
|
+
def images
|
26
|
+
Image.all.select { |image| image.entity == self }
|
27
|
+
end
|
28
|
+
|
29
|
+
def image
|
30
|
+
images.first
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_liquid context=nil
|
34
|
+
ShoperbLiquid::ProductCollectionDrop.new(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end end end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class Country < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
fields :id, :code, :name, :iso3, :numeric, :eu, :na,
|
9
|
+
:region_name_key, :abstract
|
10
|
+
has_many :states
|
11
|
+
|
12
|
+
def localized_name
|
13
|
+
name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end end end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class Currency < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
fields :id, :name, :code, :symbol, :rate, :date
|
9
|
+
|
10
|
+
def self.primary_key
|
11
|
+
:id
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end end end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Shoperb module Theme module Editor
|
2
|
+
module Mounter
|
3
|
+
module Model
|
4
|
+
class CustomField < Sequel::Model
|
5
|
+
extend Base::SequelClass
|
6
|
+
include Base::Sequel
|
7
|
+
|
8
|
+
fields :id, :name, :description, :klass, :handle, :html_type
|
9
|
+
c_fields :customer_see, :customer_edit, :customer_delete, cast: TrueClass
|
10
|
+
c_fields :html_values, :default_values, cast: JSON
|
11
|
+
|
12
|
+
def self.primary_key
|
13
|
+
:id
|
14
|
+
end
|
15
|
+
|
16
|
+
class ::ShoperbLiquid::Base::CustomField < Shoperb::Theme::Editor::Mounter::Model::CustomField
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end end end
|