spree_core 5.0.6 → 5.1.0.beta

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/logo.png +0 -0
  3. data/app/finders/spree/products/find.rb +28 -1
  4. data/app/finders/spree/taxons/find.rb +1 -1
  5. data/app/helpers/spree/base_helper.rb +1 -6
  6. data/app/helpers/spree/images_helper.rb +12 -13
  7. data/app/helpers/spree/integrations_helper.rb +15 -0
  8. data/app/helpers/spree/mail_helper.rb +3 -4
  9. data/app/javascript/spree/core/controllers/disable_submit_button_controller.js +19 -0
  10. data/app/mailers/spree/invitation_mailer.rb +24 -0
  11. data/app/models/concerns/spree/integrations_concern.rb +11 -0
  12. data/app/models/concerns/spree/product_scopes.rb +6 -6
  13. data/app/models/concerns/spree/translatable_resource.rb +4 -0
  14. data/app/models/concerns/spree/translatable_resource_scopes.rb +17 -3
  15. data/app/models/concerns/spree/unique_name.rb +2 -0
  16. data/app/models/concerns/spree/user_management.rb +33 -0
  17. data/app/models/concerns/spree/user_methods.rb +19 -0
  18. data/app/models/concerns/spree/user_roles.rb +43 -17
  19. data/app/models/spree/ability.rb +8 -6
  20. data/app/models/spree/asset.rb +1 -6
  21. data/app/models/spree/base.rb +1 -0
  22. data/app/models/spree/base_analytics_event_handler.rb +7 -2
  23. data/app/models/spree/classification.rb +13 -0
  24. data/app/models/spree/credit_card.rb +24 -2
  25. data/app/models/spree/custom_domain.rb +3 -2
  26. data/app/models/spree/export.rb +1 -1
  27. data/app/models/spree/integration.rb +63 -0
  28. data/app/models/spree/invitation.rb +153 -0
  29. data/app/models/spree/invitations/store.rb +6 -0
  30. data/app/models/spree/option_value.rb +2 -2
  31. data/app/models/spree/order.rb +16 -5
  32. data/app/models/spree/order_merger.rb +7 -5
  33. data/app/models/spree/page_sections/featured_posts.rb +0 -4
  34. data/app/models/spree/payment.rb +1 -2
  35. data/app/models/spree/payment_source.rb +0 -21
  36. data/app/models/spree/post.rb +0 -1
  37. data/app/models/spree/product.rb +75 -5
  38. data/app/models/spree/product_property.rb +1 -1
  39. data/app/models/spree/promotion/rules/item_total.rb +12 -12
  40. data/app/models/spree/property.rb +3 -1
  41. data/app/models/spree/reports/sales_total.rb +5 -1
  42. data/app/models/spree/role.rb +16 -0
  43. data/app/models/spree/role_user.rb +32 -1
  44. data/app/models/spree/shipment_handler.rb +1 -0
  45. data/app/models/spree/shipping_method.rb +2 -2
  46. data/app/models/spree/store.rb +9 -4
  47. data/app/models/spree/store_credit_category.rb +4 -0
  48. data/app/models/spree/taxon.rb +4 -7
  49. data/app/models/spree/theme.rb +1 -1
  50. data/app/models/spree/wishlist.rb +0 -7
  51. data/app/services/spree/country_to_timezone.rb +273 -0
  52. data/app/services/spree/products/prepare_nested_attributes.rb +2 -9
  53. data/app/services/spree/seeds/admin_user.rb +4 -2
  54. data/app/services/spree/seeds/all.rb +3 -1
  55. data/app/services/spree/seeds/digital_delivery.rb +20 -0
  56. data/app/services/spree/seeds/returns_environment.rb +27 -0
  57. data/app/services/spree/seeds/tax_categories.rb +12 -0
  58. data/app/services/spree/stores/settings_defaults_by_country.rb +38 -0
  59. data/app/services/spree/tags/bulk_add.rb +13 -7
  60. data/app/views/spree/addresses/_form.html.erb +1 -1
  61. data/app/views/spree/invitation_mailer/invitation_accepted.html.erb +12 -0
  62. data/app/views/spree/invitation_mailer/invitation_email.html.erb +21 -0
  63. data/app/views/spree/shared/_payment.html.erb +0 -9
  64. data/config/locales/en.yml +48 -20
  65. data/db/migrate/20250407085228_create_spree_integrations.rb +12 -0
  66. data/db/migrate/20250410061306_create_spree_invitations.rb +20 -0
  67. data/db/migrate/20250418174652_add_resource_to_spree_role_users.rb +8 -0
  68. data/db/migrate/20250508060800_add_selected_locale_to_spree_admin_users.rb +8 -0
  69. data/db/migrate/20250509143831_add_session_id_to_spree_assets.rb +5 -0
  70. data/lib/generators/spree/authentication/devise/templates/authentication_helpers.rb.tt +3 -3
  71. data/lib/spree/core/controller_helpers/auth.rb +15 -14
  72. data/lib/spree/core/controller_helpers/currency.rb +11 -0
  73. data/lib/spree/core/controller_helpers/strong_parameters.rb +3 -2
  74. data/lib/spree/core/engine.rb +13 -3
  75. data/lib/spree/core/version.rb +1 -1
  76. data/lib/spree/core.rb +1 -0
  77. data/lib/spree/permitted_attributes.rb +111 -13
  78. data/lib/spree/testing_support/common_rake.rb +7 -25
  79. data/lib/spree/testing_support/extension_rake.rb +1 -1
  80. data/lib/spree/testing_support/factories/integration_factory.rb +7 -0
  81. data/lib/spree/testing_support/factories/invitation_factory.rb +6 -0
  82. data/lib/spree/testing_support/factories/page_section_factory.rb +0 -4
  83. data/lib/spree/testing_support/factories/payment_factory.rb +0 -5
  84. data/lib/spree/testing_support/factories/payment_method_factory.rb +0 -5
  85. data/lib/spree/testing_support/factories/promotion_action_factory.rb +4 -0
  86. data/lib/spree/testing_support/factories/taxon_factory.rb +0 -6
  87. data/lib/spree/testing_support/factories/user_factory.rb +14 -1
  88. data/lib/spree/translation_migrations.rb +27 -15
  89. data/lib/tasks/core.rake +8 -0
  90. metadata +41 -8
  91. data/app/models/concerns/spree/payment_source_concern.rb +0 -39
  92. data/app/models/spree/gateway/custom_payment_source_method.rb +0 -33
  93. data/app/models/spree/product/slugs.rb +0 -112
  94. data/lib/spree/testing_support/factories/payment_source_factory.rb +0 -5
@@ -2,12 +2,16 @@ module Spree
2
2
  module Reports
3
3
  class SalesTotal < Spree::Report
4
4
  def line_items_scope
5
- store.line_items.where(
5
+ scope = store.line_items.where(
6
6
  order: Spree::Order.complete.where(
7
7
  currency: currency,
8
8
  completed_at: (date_from.to_time.beginning_of_day)..(date_to.to_time.end_of_day)
9
9
  )
10
10
  ).includes(:order, variant: :product)
11
+
12
+ scope = scope.where(vendor_id: vendor.id) if defined?(vendor) && vendor.present?
13
+
14
+ scope
11
15
  end
12
16
  end
13
17
  end
@@ -4,8 +4,24 @@ module Spree
4
4
 
5
5
  ADMIN_ROLE = 'admin'
6
6
 
7
+ #
8
+ # Associations
9
+ #
7
10
  has_many :role_users, class_name: 'Spree::RoleUser', dependent: :destroy
8
11
  has_many :users, through: :role_users, source: :user, source_type: Spree.user_class.to_s
9
12
  has_many :admin_users, through: :role_users, source: :user, source_type: Spree.admin_user_class.to_s
13
+ has_many :invitations, class_name: 'Spree::Invitation', dependent: :destroy
14
+
15
+ #
16
+ # Scopes
17
+ #
18
+ scope :admin, -> { where(name: ADMIN_ROLE) }
19
+
20
+ #
21
+ # Class Methods
22
+ #
23
+ def self.default_admin_role
24
+ find_or_create_by(name: ADMIN_ROLE)
25
+ end
10
26
  end
11
27
  end
@@ -1,6 +1,37 @@
1
1
  module Spree
2
2
  class RoleUser < Spree.base_class
3
- belongs_to :role, class_name: 'Spree::Role'
3
+ #
4
+ # Associations
5
+ #
6
+ belongs_to :role, class_name: 'Spree::Role', foreign_key: :role_id
4
7
  belongs_to :user, polymorphic: true
8
+ belongs_to :resource, polymorphic: true
9
+ belongs_to :invitation, class_name: 'Spree::Invitation', optional: true
10
+
11
+ #
12
+ # Validations
13
+ #
14
+ validates :role, presence: true
15
+ validates :user, presence: true
16
+ validates :resource, presence: true
17
+ validates :role_id, uniqueness: { scope: [:user_id, :resource_id, :user_type, :resource_type] }
18
+
19
+ #
20
+ # Delegations
21
+ #
22
+ delegate :name, to: :user
23
+
24
+ #
25
+ # Callbacks
26
+ #
27
+ before_validation :set_default_resource
28
+
29
+ private
30
+
31
+ # Set the default resource to the default store if the resource is not set
32
+ # this will allow a graceful migration from the old roles system to the new one
33
+ def set_default_resource
34
+ self.resource ||= Spree::Store.current
35
+ end
5
36
  end
6
37
  end
@@ -1,6 +1,7 @@
1
1
  module Spree
2
2
  class ShipmentHandler
3
3
  include Spree::Shipment::Emails
4
+ include Spree::IntegrationsConcern
4
5
 
5
6
  class << self
6
7
  def factory(shipment)
@@ -50,7 +50,7 @@ module Spree
50
50
  def include?(address)
51
51
  return false unless address
52
52
 
53
- zones.includes(:zone_members).any? do |zone|
53
+ zones.includes(zone_members: :zoneable).any? do |zone|
54
54
  zone.include?(address)
55
55
  end
56
56
  end
@@ -93,7 +93,7 @@ module Spree
93
93
  if estimated_transit_business_days_min == estimated_transit_business_days_max
94
94
  estimated_transit_business_days_min.to_s
95
95
  else
96
- [estimated_transit_business_days_min, estimated_transit_business_days_max].compact.join("-")
96
+ "#{estimated_transit_business_days_min}-#{estimated_transit_business_days_max}"
97
97
  end
98
98
  end
99
99
 
@@ -13,6 +13,7 @@ module Spree
13
13
  include Spree::Stores::Socials
14
14
  include Spree::Webhooks::HasWebhooks if defined?(Spree::Webhooks::HasWebhooks)
15
15
  include Spree::Security::Stores if defined?(Spree::Security::Stores)
16
+ include Spree::UserManagement
16
17
 
17
18
  #
18
19
  # Magic methods
@@ -100,8 +101,10 @@ module Spree
100
101
  has_many :custom_domains, class_name: 'Spree::CustomDomain', dependent: :destroy
101
102
  has_one :default_custom_domain, -> { where(default: true) }, class_name: 'Spree::CustomDomain'
102
103
 
103
- has_many :posts
104
- has_many :post_categories
104
+ has_many :posts, class_name: 'Spree::Post'
105
+ has_many :post_categories, class_name: 'Spree::PostCategory'
106
+
107
+ has_many :integrations, class_name: 'Spree::Integration'
105
108
 
106
109
  #
107
110
  # Page Builder associations
@@ -342,7 +345,7 @@ module Spree
342
345
  # @return [Spree::StockLocation]
343
346
  def default_stock_location
344
347
  @default_stock_location ||= begin
345
- stock_location_scope = Spree::StockLocation.order_default
348
+ stock_location_scope = Spree::StockLocation.where(default: true)
346
349
  stock_location_scope.first || ActiveRecord::Base.connected_to(role: :writing) do
347
350
  stock_location_scope.create(default: true, name: Spree.t(:default_stock_location_name), country: default_country)
348
351
  end
@@ -350,7 +353,9 @@ module Spree
350
353
  end
351
354
 
352
355
  def admin_users
353
- @admin_users ||= Spree.admin_user_class.joins(:spree_roles).where(spree_roles: { name: :admin })
356
+ Spree::Deprecation.warn('Store#admin_users is deprecated and will be removed in Spree 6.0. Please use Store#users instead.')
357
+
358
+ users
354
359
  end
355
360
 
356
361
  def favicon
@@ -28,6 +28,10 @@ module Spree
28
28
  end
29
29
  end
30
30
 
31
+ def can_be_deleted?
32
+ !store_credit_category_used?
33
+ end
34
+
31
35
  class << self
32
36
  def default_reimbursement_category(_options = {})
33
37
  Spree::StoreCreditCategory.first
@@ -1,4 +1,3 @@
1
- # TODO: let friendly id take care of sanitizing the url
2
1
  require 'stringex'
3
2
 
4
3
  module Spree
@@ -96,9 +95,11 @@ module Spree
96
95
  if Spree.use_translations?
97
96
  joins(:taxonomy).
98
97
  join_translation_table(Taxonomy).
99
- where(["LOWER(#{Taxonomy.translation_table_alias}.name) = ?", taxonomy_name.downcase.strip])
98
+ where(
99
+ Taxonomy.arel_table_alias[:name].lower.matches(taxonomy_name.downcase.strip)
100
+ )
100
101
  else
101
- joins(:taxonomy).where(["LOWER(#{Spree::Taxonomy.table_name}.name) = ?", taxonomy_name.downcase.strip])
102
+ joins(:taxonomy).where(Spree::Taxonomy.arel_table[:name].lower.matches(taxonomy_name.downcase.strip))
102
103
  end
103
104
  }
104
105
 
@@ -153,10 +154,6 @@ module Spree
153
154
  sort_order == 'manual'
154
155
  end
155
156
 
156
- def page_builder_image
157
- square_image.presence || image
158
- end
159
-
160
157
  def active_products_with_descendants
161
158
  @active_products_with_descendants ||= store.products.
162
159
  joins(:classifications).
@@ -155,7 +155,7 @@ module Spree
155
155
  end
156
156
  end
157
157
 
158
- # Returns an array of available layout section classes for the theme, eg. header, footer, newsletter, etc.
158
+ # Returns an array of available layout section classes for the theme
159
159
  #
160
160
  # @return [Array<Class>]
161
161
  def available_layout_sections
@@ -36,13 +36,6 @@ module Spree
36
36
  @wished_items_count ||= variant_ids.count
37
37
  end
38
38
 
39
- # returns the variant ids in the wishlist
40
- #
41
- # @return [Array<Integer>]
42
- def variant_ids
43
- @variant_ids ||= wished_items.pluck(:variant_id)
44
- end
45
-
46
39
  def self.get_by_param(param)
47
40
  find_by(token: param)
48
41
  end
@@ -0,0 +1,273 @@
1
+ module Spree
2
+ class CountryToTimezone
3
+ prepend Spree::ServiceModule::Base
4
+
5
+ CAPITAL_CITIES = {
6
+ "AD"=>"Andorra la Vella",
7
+ "AE"=>"Abu Dhabi",
8
+ "AF"=>"Kabul",
9
+ "AG"=>"Saint John's",
10
+ "AI"=>"The Valley",
11
+ "AL"=>"Tirana",
12
+ "AM"=>"Yerevan",
13
+ "AN"=>"Willemstad",
14
+ "AO"=>"Luanda",
15
+ "AQ"=>nil,
16
+ "AR"=>"Buenos Aires",
17
+ "AS"=>"Pago Pago",
18
+ "AT"=>"Vienna",
19
+ "AU"=>"Canberra",
20
+ "AW"=>"Oranjestad",
21
+ "AZ"=>"Baku",
22
+ "BA"=>"Sarajevo",
23
+ "BB"=>"Bridgetown",
24
+ "BD"=>"Dhaka",
25
+ "BE"=>"Brussels",
26
+ "BF"=>"Ouagadougou",
27
+ "BG"=>"Sofia",
28
+ "BH"=>"Manama",
29
+ "BI"=>"Bujumbura",
30
+ "BJ"=>"Porto-Novo",
31
+ "BL"=>"Gustavia",
32
+ "BM"=>"Hamilton",
33
+ "BN"=>"Bandar Seri Begawan",
34
+ "BO"=>"La Paz",
35
+ "BR"=>"Brasilia",
36
+ "BS"=>"Nassau",
37
+ "BT"=>"Thimphu",
38
+ "BV"=>nil,
39
+ "BW"=>"Gaborone",
40
+ "BY"=>"Minsk",
41
+ "BZ"=>"Belmopan",
42
+ "CA"=>"Ottawa",
43
+ "CC"=>"West Island",
44
+ "CD"=>"Kinshasa",
45
+ "CF"=>"Bangui",
46
+ "CG"=>"Brazzaville",
47
+ "CH"=>"Bern",
48
+ "CI"=>"Yamoussoukro",
49
+ "CK"=>"Avarua",
50
+ "CL"=>"Santiago",
51
+ "CM"=>"Yaounde",
52
+ "CN"=>"Beijing",
53
+ "CO"=>"Bogota",
54
+ "CR"=>"San Jose",
55
+ "CU"=>"Havana",
56
+ "CV"=>"Praia",
57
+ "CX"=>"The Settlement",
58
+ "CY"=>"Nicosia",
59
+ "CZ"=>"Prague",
60
+ "DE"=>"Berlin",
61
+ "DJ"=>"Djibouti",
62
+ "DK"=>"Copenhagen",
63
+ "DM"=>"Roseau",
64
+ "DO"=>"Santo Domingo",
65
+ "DZ"=>"Algiers",
66
+ "EC"=>"Quito",
67
+ "EE"=>"Tallinn",
68
+ "EG"=>"Cairo",
69
+ "EH"=>nil,
70
+ "ER"=>"Asmara",
71
+ "ES"=>"Madrid",
72
+ "ET"=>"Addis Ababa",
73
+ "FI"=>"Helsinki",
74
+ "FJ"=>"Suva",
75
+ "FK"=>"Stanley",
76
+ "FM"=>"Palikir",
77
+ "FO"=>"Torshavn",
78
+ "FR"=>"Paris",
79
+ "GA"=>"Libreville",
80
+ "GB"=>"London",
81
+ "GD"=>"Saint George's",
82
+ "GE"=>"T'bilisi",
83
+ "GG"=>"Saint Peter Port",
84
+ "GH"=>"Accra",
85
+ "GI"=>"Gibraltar",
86
+ "GL"=>"Nuuk",
87
+ "GM"=>"Banjul",
88
+ "GN"=>"Conakry",
89
+ "GQ"=>"Malabo",
90
+ "GR"=>"Athens",
91
+ "GT"=>"Guatemala City",
92
+ "GU"=>"Hagatna",
93
+ "GW"=>"Bissau",
94
+ "GY"=>"Georgetown",
95
+ "HK"=>"Hong Kong",
96
+ "HM"=>nil,
97
+ "HN"=>"Tegucigalpa",
98
+ "HR"=>"Zagreb",
99
+ "HT"=>"Port-au-Prince",
100
+ "HU"=>"Budapest",
101
+ "ID"=>"Jakarta",
102
+ "IE"=>"Dublin",
103
+ "IL"=>"Jerusalem",
104
+ "IM"=>"Douglas",
105
+ "IN"=>"New Delhi",
106
+ "IO"=>nil,
107
+ "IQ"=>"Baghdad",
108
+ "IR"=>"Tehran",
109
+ "IS"=>"Reykjavik",
110
+ "IT"=>"Rome",
111
+ "JE"=>"Saint Helier",
112
+ "JM"=>"Kingston",
113
+ "JO"=>"Amman",
114
+ "JP"=>"Tokyo",
115
+ "KE"=>"Nairobi",
116
+ "KG"=>"Bishkek",
117
+ "KH"=>"Phnom Penh",
118
+ "KI"=>"Tarawa",
119
+ "KM"=>"Moroni",
120
+ "KN"=>"Basseterre",
121
+ "KP"=>"Pyongyang",
122
+ "KR"=>"Seoul",
123
+ "KW"=>"Kuwait City",
124
+ "KY"=>"George Town",
125
+ "KZ"=>"Astana",
126
+ "LA"=>"Vientiane",
127
+ "LB"=>"Beirut",
128
+ "LC"=>"Castries",
129
+ "LI"=>"Vaduz",
130
+ "LK"=>"Colombo",
131
+ "LR"=>"Monrovia",
132
+ "LS"=>"Maseru",
133
+ "LT"=>"Vilnius",
134
+ "LU"=>"Luxembourg",
135
+ "LV"=>"Riga",
136
+ "LY"=>"Tripoli",
137
+ "MA"=>"Rabat",
138
+ "MC"=>"Monaco",
139
+ "MD"=>"Chisinau",
140
+ "ME"=>"Podgorica",
141
+ "MF"=>"Marigot",
142
+ "MG"=>"Antananarivo",
143
+ "MH"=>"Majuro",
144
+ "MK"=>"Skopje",
145
+ "ML"=>"Bamako",
146
+ "MM"=>"Rangoon",
147
+ "MN"=>"Ulaanbaatar",
148
+ "MO"=>nil,
149
+ "MP"=>"Saipan",
150
+ "MR"=>"Nouakchott",
151
+ "MS"=>"Plymouth",
152
+ "MT"=>"Valletta",
153
+ "MU"=>"Port Louis",
154
+ "MV"=>"Male",
155
+ "MW"=>"Lilongwe",
156
+ "MX"=>"Mexico City",
157
+ "MY"=>"Kuala Lumpur",
158
+ "MZ"=>"Maputo",
159
+ "NA"=>"Windhoek",
160
+ "NC"=>"Noumea",
161
+ "NE"=>"Niamey",
162
+ "NF"=>"Kingston",
163
+ "NG"=>"Abuja",
164
+ "NI"=>"Managua",
165
+ "NL"=>"Amsterdam",
166
+ "NO"=>"Oslo",
167
+ "NP"=>"Kathmandu",
168
+ "NR"=>nil,
169
+ "NU"=>"Alofi",
170
+ "NZ"=>"Wellington",
171
+ "OM"=>"Muscat",
172
+ "PA"=>"Panama City",
173
+ "PE"=>"Lima",
174
+ "PF"=>"Papeete",
175
+ "PG"=>"Port Moresby",
176
+ "PH"=>"Manila",
177
+ "PK"=>"Islamabad",
178
+ "PL"=>"Warsaw",
179
+ "PM"=>"Saint-Pierre",
180
+ "PN"=>"Adamstown",
181
+ "PR"=>"San Juan",
182
+ "PS"=>nil,
183
+ "PT"=>"Lisbon",
184
+ "PW"=>"Melekeok",
185
+ "PY"=>"Asuncion",
186
+ "QA"=>"Doha",
187
+ "RO"=>"Bucharest",
188
+ "RS"=>"Belgrade",
189
+ "RU"=>"Moscow",
190
+ "RW"=>"Kigali",
191
+ "SA"=>"Riyadh",
192
+ "SB"=>"Honiara",
193
+ "SC"=>"Victoria",
194
+ "SD"=>"Khartoum",
195
+ "SE"=>"Stockholm",
196
+ "SG"=>"Singapore",
197
+ "SH"=>"Jamestown",
198
+ "SI"=>"Ljubljana",
199
+ "SJ"=>"Longyearbyen",
200
+ "SK"=>"Bratislava",
201
+ "SL"=>"Freetown",
202
+ "SM"=>"San Marino",
203
+ "SN"=>"Dakar",
204
+ "SO"=>"Mogadishu",
205
+ "SR"=>"Paramaribo",
206
+ "ST"=>"Sao Tome",
207
+ "SV"=>"San Salvador",
208
+ "SY"=>"Damascus",
209
+ "SZ"=>"Mbabane",
210
+ "TC"=>"Grand Turk",
211
+ "TD"=>"N'Djamena",
212
+ "TF"=>nil,
213
+ "TG"=>"Lome",
214
+ "TH"=>"Bangkok",
215
+ "TJ"=>"Dushanbe",
216
+ "TK"=>nil,
217
+ "TL"=>"Dili",
218
+ "TM"=>"Ashgabat",
219
+ "TN"=>"Tunis",
220
+ "TO"=>"Nuku'alofa",
221
+ "TR"=>"Ankara",
222
+ "TT"=>"Port-of-Spain",
223
+ "TV"=>"Funafuti",
224
+ "TW"=>"Taipei",
225
+ "TZ"=>"Dar es Salaam",
226
+ "UA"=>"Kyiv",
227
+ "UG"=>"Kampala",
228
+ "US"=>"Washington, DC",
229
+ "UY"=>"Montevideo",
230
+ "UZ"=>"Tashkent",
231
+ "VA"=>"Vatican City",
232
+ "VC"=>"Kingstown",
233
+ "VE"=>"Caracas",
234
+ "VG"=>"Road Town",
235
+ "VI"=>"Charlotte Amalie",
236
+ "VN"=>"Hanoi",
237
+ "VU"=>"Port-Vila",
238
+ "WF"=>"Mata-Utu",
239
+ "WS"=>"Apia",
240
+ "YE"=>"Sanaa",
241
+ "YT"=>"Mamoudzou",
242
+ "ZA"=>"Pretoria",
243
+ "ZM"=>"Lusaka",
244
+ "ZW"=>"Harare"}.freeze
245
+
246
+ def call(code:)
247
+ case code
248
+ when 'US', 'CA'
249
+ success('Central Time (US & Canada)')
250
+ else
251
+ success(from_timezone_helper(code))
252
+ end
253
+ end
254
+
255
+ private
256
+
257
+ def from_timezone_helper(code)
258
+ timezones = ActiveSupport::TimeZone.country_zones(code)
259
+ return 'Central Time (US & Canada)' if timezones.empty?
260
+
261
+ timezones.first.name if timezones.size == 1
262
+
263
+ # If there is more than one timezone for the country, then we'll use the capital city
264
+ # to determine the timezone
265
+ # eg GB has London and Edinburgh
266
+ capital_city = CAPITAL_CITIES[code]
267
+ capital_city_time_zone = timezones.find{ |tz| tz.name.match(capital_city) }
268
+ return capital_city_time_zone.name if capital_city_time_zone.present?
269
+
270
+ timezones.first.name
271
+ end
272
+ end
273
+ end
@@ -136,15 +136,8 @@ module Spree
136
136
  o.position = opt[:position]
137
137
  o.save!
138
138
  end
139
-
140
- option_value_identificator = if opt[:option_value_name].present?
141
- opt[:option_value_name]
142
- else
143
- opt[:option_value_presentation].parameterize
144
- end
145
-
146
- option_value = option_type.option_values.where(name: option_value_identificator).first_or_initialize do |o|
147
- o.name = o.presentation = opt[:option_value_presentation]
139
+ option_value = option_type.option_values.where(name: opt[:value].parameterize).first_or_initialize do |o|
140
+ o.name = o.presentation = opt[:value]
148
141
  o.save!
149
142
  end
150
143
 
@@ -12,9 +12,11 @@ module Spree
12
12
  first_name: 'Spree',
13
13
  last_name: 'Admin'
14
14
  )
15
-
16
- user.spree_roles << Spree::Role.find_or_create_by(name: :admin)
17
15
  user.save!
16
+
17
+ Spree::Store.all.each do |store|
18
+ store.add_user(user)
19
+ end
18
20
  end
19
21
  end
20
22
  end
@@ -14,9 +14,11 @@ module Spree
14
14
  Roles.call
15
15
 
16
16
  # additional data
17
- DefaultReimbursementTypes.call
17
+ ReturnsEnvironment.call
18
18
  ShippingCategories.call
19
19
  StoreCreditCategories.call
20
+ TaxCategories.call
21
+ DigitalDelivery.call
20
22
 
21
23
  # store & stock location
22
24
  Stores.call
@@ -0,0 +1,20 @@
1
+ module Spree
2
+ module Seeds
3
+ class DigitalDelivery
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call
7
+ digital_shipping_category = Spree::ShippingCategory.find_or_create_by!(name: 'Digital')
8
+ zones = Spree::Zone.all
9
+
10
+ digital_shipping_method = Spree::ShippingMethod.find_or_initialize_by(name: Spree.t('digital.digital_delivery'))
11
+
12
+ digital_shipping_method.display_on = 'both'
13
+ digital_shipping_method.shipping_categories = [digital_shipping_category]
14
+ digital_shipping_method.calculator ||= Spree::Calculator::Shipping::DigitalDelivery.create!
15
+ digital_shipping_method.zones = zones
16
+ digital_shipping_method.save!
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ module Spree
2
+ module Seeds
3
+ class ReturnsEnvironment
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call
7
+ Spree::RefundReason.find_or_create_by!(name: 'Return processing', mutable: false)
8
+ [
9
+ 'Better price available',
10
+ 'Missed estimated delivery date',
11
+ 'Missing parts or accessories',
12
+ 'Damaged/Defective',
13
+ 'Different from what was ordered',
14
+ 'Different from description',
15
+ 'No longer needed/wanted',
16
+ 'Accidental order',
17
+ 'Unauthorized purchase',
18
+ ].each do |name|
19
+ Spree::ReturnAuthorizationReason.find_or_create_by!(name: name)
20
+ end
21
+ Spree::ReimbursementType.find_or_create_by!(name: 'Store Credit', type: 'Spree::ReimbursementType::StoreCredit')
22
+ Spree::ReimbursementType.find_or_create_by!(name: 'Exchange', type: 'Spree::ReimbursementType::Exchange')
23
+ Spree::ReimbursementType.find_or_create_by!(name: 'Original payment', type: 'Spree::ReimbursementType::OriginalPayment')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ module Spree
2
+ module Seeds
3
+ class TaxCategories
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ def call
7
+ Spree::TaxCategory.find_or_create_by(name: 'Default', is_default: true)
8
+ Spree::TaxCategory.find_or_create_by(name: 'Non-taxable')
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,38 @@
1
+ module Spree
2
+ module Stores
3
+ class SettingsDefaultsByCountry
4
+ prepend Spree::ServiceModule::Base
5
+
6
+ IMPERIAL = %w[US GB LR MM].freeze
7
+
8
+ def call(code:)
9
+ default_unit_system = unit_system(code)
10
+
11
+ success(
12
+ unit_system: default_unit_system,
13
+ weight_unit: weight_unit(default_unit_system),
14
+ timezone: timezone(code)
15
+ )
16
+ end
17
+
18
+ private
19
+
20
+ def unit_system(code)
21
+ IMPERIAL.include?(code) ? :imperial : :metric
22
+ end
23
+
24
+ def weight_unit(unit_system)
25
+ unit_system.to_s == 'metric' ? 'kg' : 'lb'
26
+ end
27
+
28
+ def timezone(code)
29
+ case code
30
+ when 'US', 'CA'
31
+ 'Central Time (US & Canada)'
32
+ else
33
+ Spree::CountryToTimezone.call(code: code).value
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -16,7 +16,19 @@ module Spree
16
16
 
17
17
  record_class = records.first.class
18
18
 
19
- taggings_to_upsert = records.pluck(:id).map do |record_id|
19
+ taggings_to_upsert = taggings_attributes(tags, records, context: context, record_class: record_class)
20
+
21
+ return if taggings_to_upsert.empty?
22
+
23
+ ActsAsTaggableOn::Tagging.insert_all(taggings_to_upsert)
24
+
25
+ record_class.where(id: records.pluck(:id)).touch_all
26
+ end
27
+
28
+ private
29
+
30
+ def taggings_attributes(tags, records, context:, record_class:)
31
+ records.pluck(:id).map do |record_id|
20
32
  tags.map do |tag|
21
33
  {
22
34
  taggable_id: record_id,
@@ -26,12 +38,6 @@ module Spree
26
38
  }
27
39
  end
28
40
  end.flatten.compact
29
-
30
- return if taggings_to_upsert.empty?
31
-
32
- ActsAsTaggableOn::Tagging.insert_all(taggings_to_upsert)
33
-
34
- record_class.where(id: records.pluck(:id)).touch_all
35
41
  end
36
42
  end
37
43
  end