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.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +40 -0
  3. data/LICENSE.md +21 -0
  4. data/README.md +124 -0
  5. data/bin/shoperb +313 -0
  6. data/lib/shoperb_theme_editor/api/server.rb +10 -0
  7. data/lib/shoperb_theme_editor/api/views/callback.erb +53 -0
  8. data/lib/shoperb_theme_editor/api.rb +264 -0
  9. data/lib/shoperb_theme_editor/build/json.rb +167 -0
  10. data/lib/shoperb_theme_editor/build/liquid.rb +38 -0
  11. data/lib/shoperb_theme_editor/build/section.rb +51 -0
  12. data/lib/shoperb_theme_editor/build/settings.rb +224 -0
  13. data/lib/shoperb_theme_editor/build.rb +68 -0
  14. data/lib/shoperb_theme_editor/configuration.rb +98 -0
  15. data/lib/shoperb_theme_editor/error.rb +35 -0
  16. data/lib/shoperb_theme_editor/ext/array.rb +17 -0
  17. data/lib/shoperb_theme_editor/ext/nil_class.rb +7 -0
  18. data/lib/shoperb_theme_editor/ext/sequel.rb +82 -0
  19. data/lib/shoperb_theme_editor/ext.rb +2 -0
  20. data/lib/shoperb_theme_editor/init.rb +87 -0
  21. data/lib/shoperb_theme_editor/logger.rb +58 -0
  22. data/lib/shoperb_theme_editor/mounter/models/address.rb +65 -0
  23. data/lib/shoperb_theme_editor/mounter/models/attribute.rb +11 -0
  24. data/lib/shoperb_theme_editor/mounter/models/attribute_key.rb +17 -0
  25. data/lib/shoperb_theme_editor/mounter/models/base.rb +196 -0
  26. data/lib/shoperb_theme_editor/mounter/models/blog_category.rb +47 -0
  27. data/lib/shoperb_theme_editor/mounter/models/blog_post.rb +45 -0
  28. data/lib/shoperb_theme_editor/mounter/models/brand.rb +11 -0
  29. data/lib/shoperb_theme_editor/mounter/models/cart.rb +35 -0
  30. data/lib/shoperb_theme_editor/mounter/models/cart_item.rb +71 -0
  31. data/lib/shoperb_theme_editor/mounter/models/category.rb +99 -0
  32. data/lib/shoperb_theme_editor/mounter/models/collection.rb +40 -0
  33. data/lib/shoperb_theme_editor/mounter/models/country.rb +18 -0
  34. data/lib/shoperb_theme_editor/mounter/models/currency.rb +17 -0
  35. data/lib/shoperb_theme_editor/mounter/models/custom_field.rb +22 -0
  36. data/lib/shoperb_theme_editor/mounter/models/customer.rb +77 -0
  37. data/lib/shoperb_theme_editor/mounter/models/customer_customer_group.rb +12 -0
  38. data/lib/shoperb_theme_editor/mounter/models/customer_group.rb +13 -0
  39. data/lib/shoperb_theme_editor/mounter/models/customer_subscription.rb +40 -0
  40. data/lib/shoperb_theme_editor/mounter/models/customer_subscription_plan.rb +32 -0
  41. data/lib/shoperb_theme_editor/mounter/models/discount.rb +40 -0
  42. data/lib/shoperb_theme_editor/mounter/models/discount_variant.rb +15 -0
  43. data/lib/shoperb_theme_editor/mounter/models/image.rb +51 -0
  44. data/lib/shoperb_theme_editor/mounter/models/language.rb +17 -0
  45. data/lib/shoperb_theme_editor/mounter/models/link.rb +61 -0
  46. data/lib/shoperb_theme_editor/mounter/models/media_file.rb +19 -0
  47. data/lib/shoperb_theme_editor/mounter/models/menu.rb +21 -0
  48. data/lib/shoperb_theme_editor/mounter/models/meta.rb +10 -0
  49. data/lib/shoperb_theme_editor/mounter/models/news_item.rb +11 -0
  50. data/lib/shoperb_theme_editor/mounter/models/order.rb +133 -0
  51. data/lib/shoperb_theme_editor/mounter/models/order_item.rb +137 -0
  52. data/lib/shoperb_theme_editor/mounter/models/order_item_attribute.rb +17 -0
  53. data/lib/shoperb_theme_editor/mounter/models/order_return.rb +42 -0
  54. data/lib/shoperb_theme_editor/mounter/models/order_return_item.rb +29 -0
  55. data/lib/shoperb_theme_editor/mounter/models/order_return_item_entity.rb +25 -0
  56. data/lib/shoperb_theme_editor/mounter/models/order_return_parcel.rb +20 -0
  57. data/lib/shoperb_theme_editor/mounter/models/page.rb +26 -0
  58. data/lib/shoperb_theme_editor/mounter/models/payment_card.rb +21 -0
  59. data/lib/shoperb_theme_editor/mounter/models/payment_method.rb +67 -0
  60. data/lib/shoperb_theme_editor/mounter/models/payment_provider.rb +23 -0
  61. data/lib/shoperb_theme_editor/mounter/models/product.rb +144 -0
  62. data/lib/shoperb_theme_editor/mounter/models/product_attribute.rb +32 -0
  63. data/lib/shoperb_theme_editor/mounter/models/product_search.rb +53 -0
  64. data/lib/shoperb_theme_editor/mounter/models/product_type.rb +21 -0
  65. data/lib/shoperb_theme_editor/mounter/models/review.rb +38 -0
  66. data/lib/shoperb_theme_editor/mounter/models/search.rb +11 -0
  67. data/lib/shoperb_theme_editor/mounter/models/shipping_method.rb +39 -0
  68. data/lib/shoperb_theme_editor/mounter/models/shop.rb +58 -0
  69. data/lib/shoperb_theme_editor/mounter/models/state.rb +17 -0
  70. data/lib/shoperb_theme_editor/mounter/models/theme.rb +89 -0
  71. data/lib/shoperb_theme_editor/mounter/models/variant.rb +96 -0
  72. data/lib/shoperb_theme_editor/mounter/models/variant_attribute.rb +46 -0
  73. data/lib/shoperb_theme_editor/mounter/models/vendor.rb +38 -0
  74. data/lib/shoperb_theme_editor/mounter/server/assets.rb +35 -0
  75. data/lib/shoperb_theme_editor/mounter/server/defaults.rb +44 -0
  76. data/lib/shoperb_theme_editor/mounter/server/exception_handler.rb +22 -0
  77. data/lib/shoperb_theme_editor/mounter/server/partials/_shoperb_footer.liquid +0 -0
  78. data/lib/shoperb_theme_editor/mounter/server/partials/_shoperb_header.liquid +0 -0
  79. data/lib/shoperb_theme_editor/mounter/server/partials/_shoperb_stylesheets.liquid +3 -0
  80. data/lib/shoperb_theme_editor/mounter/server/renderer.rb +166 -0
  81. data/lib/shoperb_theme_editor/mounter/server/routes/cart.rb +127 -0
  82. data/lib/shoperb_theme_editor/mounter/server/routes/dummy.rb +34 -0
  83. data/lib/shoperb_theme_editor/mounter/server/routes/locale.rb +31 -0
  84. data/lib/shoperb_theme_editor/mounter/server/routes/pages.rb +33 -0
  85. data/lib/shoperb_theme_editor/mounter/server/routes/search.rb +18 -0
  86. data/lib/shoperb_theme_editor/mounter/server/routes.rb +366 -0
  87. data/lib/shoperb_theme_editor/mounter/server/routes_helper.rb +278 -0
  88. data/lib/shoperb_theme_editor/mounter/server.rb +66 -0
  89. data/lib/shoperb_theme_editor/mounter.rb +30 -0
  90. data/lib/shoperb_theme_editor/os.rb +13 -0
  91. data/lib/shoperb_theme_editor/package.rb +81 -0
  92. data/lib/shoperb_theme_editor/sync/images.rb +69 -0
  93. data/lib/shoperb_theme_editor/sync/pagination.rb +52 -0
  94. data/lib/shoperb_theme_editor/sync.rb +229 -0
  95. data/lib/shoperb_theme_editor/translations.rb +22 -0
  96. data/lib/shoperb_theme_editor/utils.rb +50 -0
  97. data/lib/shoperb_theme_editor.rb +159 -0
  98. data/shoperb_theme_editor.gemspec +60 -0
  99. 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,11 @@
1
+ module Shoperb module Theme module Editor
2
+ module Mounter
3
+ module Model
4
+ class Attribute < Sequel::Model
5
+ extend Base::SequelClass
6
+ include Base::Sequel
7
+ # todo: TODOREF2
8
+ end
9
+ end
10
+ end
11
+ 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,11 @@
1
+ module Shoperb module Theme module Editor
2
+ module Mounter
3
+ module Model
4
+ class Brand < Sequel::Model
5
+ extend Base::SequelClass
6
+ include Base::Sequel
7
+
8
+ end
9
+ end
10
+ end
11
+ 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