spree_core 5.0.3 → 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.
- checksums.yaml +4 -4
- data/app/assets/images/logo.png +0 -0
- data/app/finders/spree/products/find.rb +28 -1
- data/app/finders/spree/taxons/find.rb +1 -1
- data/app/helpers/spree/integrations_helper.rb +15 -0
- data/app/javascript/spree/core/controllers/disable_submit_button_controller.js +19 -0
- data/app/mailers/spree/invitation_mailer.rb +24 -0
- data/app/models/concerns/spree/integrations_concern.rb +11 -0
- data/app/models/concerns/spree/product_scopes.rb +6 -6
- data/app/models/concerns/spree/translatable_resource.rb +4 -0
- data/app/models/concerns/spree/translatable_resource_scopes.rb +17 -3
- data/app/models/concerns/spree/unique_name.rb +2 -0
- data/app/models/concerns/spree/user_management.rb +33 -0
- data/app/models/concerns/spree/user_methods.rb +19 -0
- data/app/models/concerns/spree/user_roles.rb +43 -17
- data/app/models/spree/ability.rb +8 -6
- data/app/models/spree/asset.rb +1 -6
- data/app/models/spree/base.rb +1 -0
- data/app/models/spree/base_analytics_event_handler.rb +7 -2
- data/app/models/spree/classification.rb +13 -0
- data/app/models/spree/custom_domain.rb +2 -1
- data/app/models/spree/export.rb +1 -1
- data/app/models/spree/integration.rb +63 -0
- data/app/models/spree/invitation.rb +153 -0
- data/app/models/spree/invitations/store.rb +6 -0
- data/app/models/spree/order.rb +17 -1
- data/app/models/spree/order_merger.rb +7 -5
- data/app/models/spree/page_blocks/products/buy_buttons.rb +8 -0
- data/app/models/spree/page_blocks/products/quantity_selector.rb +4 -0
- data/app/models/spree/page_blocks/products/variant_picker.rb +4 -0
- data/app/models/spree/page_sections/featured_product.rb +4 -0
- data/app/models/spree/page_sections/image_banner.rb +12 -0
- data/app/models/spree/page_sections/image_with_text.rb +12 -0
- data/app/models/spree/page_sections/newsletter.rb +1 -1
- data/app/models/spree/page_sections/rich_text.rb +11 -0
- data/app/models/spree/page_sections/video.rb +8 -0
- data/app/models/spree/product.rb +10 -2
- data/app/models/spree/product_property.rb +1 -1
- data/app/models/spree/property.rb +3 -1
- data/app/models/spree/reports/sales_total.rb +5 -1
- data/app/models/spree/role.rb +16 -0
- data/app/models/spree/role_user.rb +32 -1
- data/app/models/spree/shipment.rb +1 -1
- data/app/models/spree/shipment_handler.rb +1 -0
- data/app/models/spree/shipping_method.rb +1 -1
- data/app/models/spree/store.rb +11 -4
- data/app/models/spree/store_credit_category.rb +4 -0
- data/app/models/spree/taxon.rb +4 -3
- data/app/models/spree/variant.rb +9 -1
- data/app/services/spree/country_to_timezone.rb +273 -0
- data/app/services/spree/seeds/admin_user.rb +4 -2
- data/app/services/spree/seeds/all.rb +3 -1
- data/app/services/spree/seeds/digital_delivery.rb +20 -0
- data/app/services/spree/seeds/returns_environment.rb +27 -0
- data/app/services/spree/seeds/tax_categories.rb +12 -0
- data/app/services/spree/stores/settings_defaults_by_country.rb +38 -0
- data/app/services/spree/tags/bulk_add.rb +13 -7
- data/app/views/spree/invitation_mailer/invitation_accepted.html.erb +12 -0
- data/app/views/spree/invitation_mailer/invitation_email.html.erb +21 -0
- data/config/locales/en.yml +48 -9
- data/db/migrate/20250407085228_create_spree_integrations.rb +12 -0
- data/db/migrate/20250410061306_create_spree_invitations.rb +20 -0
- data/db/migrate/20250418174652_add_resource_to_spree_role_users.rb +8 -0
- data/db/migrate/20250508060800_add_selected_locale_to_spree_admin_users.rb +8 -0
- data/db/migrate/20250509143831_add_session_id_to_spree_assets.rb +5 -0
- data/lib/generators/spree/authentication/devise/devise_generator.rb +5 -2
- data/lib/generators/spree/authentication/devise/templates/authentication_helpers.rb.tt +3 -3
- data/lib/generators/spree/install/install_generator.rb +5 -0
- data/lib/spree/core/controller_helpers/auth.rb +16 -14
- data/lib/spree/core/controller_helpers/currency.rb +11 -0
- data/lib/spree/core/controller_helpers/order.rb +2 -1
- data/lib/spree/core/controller_helpers/strong_parameters.rb +3 -2
- data/lib/spree/core/engine.rb +13 -2
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +1 -0
- data/lib/spree/permitted_attributes.rb +118 -13
- data/lib/spree/testing_support/capybara_config.rb +1 -1
- data/lib/spree/testing_support/factories/integration_factory.rb +7 -0
- data/lib/spree/testing_support/factories/invitation_factory.rb +6 -0
- data/lib/spree/testing_support/factories/promotion_action_factory.rb +4 -0
- data/lib/spree/testing_support/factories/stock_item_factory.rb +5 -1
- data/lib/spree/testing_support/factories/user_factory.rb +14 -1
- data/lib/spree/translation_migrations.rb +27 -15
- data/lib/tasks/core.rake +8 -0
- metadata +41 -4
@@ -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
|
@@ -14,9 +14,11 @@ module Spree
|
|
14
14
|
Roles.call
|
15
15
|
|
16
16
|
# additional data
|
17
|
-
|
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
|
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
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<h1>
|
2
|
+
<%= Spree.t('invitation_mailer.greeting', user_name: @invitation.inviter.first_name) %>
|
3
|
+
</h1>
|
4
|
+
<p>
|
5
|
+
<%= Spree.t('invitation_mailer.invitation_accepted.body', invitee_name: @invitation.invitee&.name, resource_name: @invitation.resource.name) %>
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<p>
|
9
|
+
<%= Spree.t('invitation_mailer.thanks') %><br />
|
10
|
+
<%= current_store.name %>
|
11
|
+
</p>
|
12
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<h1>
|
2
|
+
<%= Spree.t('invitation_mailer.greeting', user_name: @invitation.invitee&.first_name || @invitation.email) %>
|
3
|
+
</h1>
|
4
|
+
<p>
|
5
|
+
<%= Spree.t('invitation_mailer.invitation_email.body', inviter_name: @invitation.inviter.name, resource_name: @invitation.resource.name) %>
|
6
|
+
</p>
|
7
|
+
<p>
|
8
|
+
<%= Spree.t('invitation_mailer.invitation_email.link_description') %>
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<% if spree.respond_to?(:admin_invitation_url) %>
|
12
|
+
<p>
|
13
|
+
<%= link_to Spree.t('invitation_mailer.invitation_email.link_text'), spree.admin_invitation_url(@invitation, token: @invitation.token, host: @invitation.store.formatted_url) %>
|
14
|
+
</p>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<p>
|
18
|
+
<%= Spree.t('invitation_mailer.thanks') %><br />
|
19
|
+
<%= current_store.name %>
|
20
|
+
</p>
|
21
|
+
|
data/config/locales/en.yml
CHANGED
@@ -52,6 +52,9 @@ en:
|
|
52
52
|
year: Year
|
53
53
|
spree/inventory_unit:
|
54
54
|
state: State
|
55
|
+
spree/invitation:
|
56
|
+
expires_at: Expires at
|
57
|
+
inviter: Inviter
|
55
58
|
spree/line_item:
|
56
59
|
price: Price
|
57
60
|
quantity: Quantity
|
@@ -194,6 +197,10 @@ en:
|
|
194
197
|
spree/zone:
|
195
198
|
description: Description
|
196
199
|
name: Name
|
200
|
+
user:
|
201
|
+
current_sign_in: Current sign in at
|
202
|
+
last_sign_in: Last sign in at
|
203
|
+
sign_in_count: Sign in count
|
197
204
|
errors:
|
198
205
|
messages:
|
199
206
|
blank: can't be blank
|
@@ -334,6 +341,9 @@ en:
|
|
334
341
|
spree/export:
|
335
342
|
one: Export
|
336
343
|
other: Exports
|
344
|
+
spree/integration:
|
345
|
+
one: Integration
|
346
|
+
other: Integrations
|
337
347
|
spree/inventory_unit:
|
338
348
|
one: Inventory Unit
|
339
349
|
other: Inventory Units
|
@@ -349,6 +359,18 @@ en:
|
|
349
359
|
spree/order:
|
350
360
|
one: Order
|
351
361
|
other: Orders
|
362
|
+
spree/page:
|
363
|
+
one: Page
|
364
|
+
other: Pages
|
365
|
+
spree/page_block:
|
366
|
+
one: Page Block
|
367
|
+
other: Page Blocks
|
368
|
+
spree/page_link:
|
369
|
+
one: Page Link
|
370
|
+
other: Page Links
|
371
|
+
spree/page_section:
|
372
|
+
one: Page Section
|
373
|
+
other: Page Sections
|
352
374
|
spree/payment:
|
353
375
|
one: Payment
|
354
376
|
other: Payments
|
@@ -526,7 +548,6 @@ en:
|
|
526
548
|
accepts_email_marketing: Accepts email marketing
|
527
549
|
account: Account
|
528
550
|
account_info: Account info
|
529
|
-
account_members: Team
|
530
551
|
action: Action
|
531
552
|
actions:
|
532
553
|
approve: Approve
|
@@ -546,6 +567,7 @@ en:
|
|
546
567
|
receive: Mark as received
|
547
568
|
refund: Refund
|
548
569
|
reject: Reject
|
570
|
+
resend: Resend
|
549
571
|
resolve: Mark as resolved
|
550
572
|
save: Save
|
551
573
|
select_file: Select file
|
@@ -784,6 +806,7 @@ en:
|
|
784
806
|
continue_as_guest: Continue as a guest
|
785
807
|
continue_selling_when_out_of_stock: Continue selling when out of stock
|
786
808
|
continue_shopping: Continue shopping
|
809
|
+
continue_without_logging_in: Continue without logging in
|
787
810
|
copy: Copy
|
788
811
|
copy_id: Copy ID
|
789
812
|
copy_link: Copy link
|
@@ -819,14 +842,13 @@ en:
|
|
819
842
|
coupon_codes: Coupon codes
|
820
843
|
create: Create
|
821
844
|
create_a_new_account: Create a new account
|
822
|
-
create_account: Create account
|
823
845
|
create_customer: Create customer
|
824
846
|
create_new: Create new
|
825
847
|
create_new_order: Create new order
|
826
848
|
create_new_team: Create new team
|
827
849
|
create_reimbursement: Create reimbursement
|
828
|
-
created_at: Created
|
829
|
-
created_by: Created
|
850
|
+
created_at: Created at
|
851
|
+
created_by: Created by
|
830
852
|
credit: Credit
|
831
853
|
credit_allowed: Credit allowed
|
832
854
|
credit_card: Credit Card
|
@@ -1122,6 +1144,7 @@ en:
|
|
1122
1144
|
internationalization: Internationalization
|
1123
1145
|
invalid_credit_card: Invalid credit card.
|
1124
1146
|
invalid_exchange_variant: Invalid exchange variant.
|
1147
|
+
invalid_or_expired_invitation: Invalid or expired invitation
|
1125
1148
|
invalid_payment_provider: Invalid payment provider.
|
1126
1149
|
invalid_promotion_action: Invalid promotion action.
|
1127
1150
|
invalid_promotion_rule: Invalid promotion rule.
|
@@ -1129,6 +1152,20 @@ en:
|
|
1129
1152
|
inventory_adjustment: Inventory Adjustment
|
1130
1153
|
inventory_error_flash_for_insufficient_quantity: An item in your cart has become unavailable.
|
1131
1154
|
inventory_state: Inventory State
|
1155
|
+
invitation_accepted: Invitation accepted!
|
1156
|
+
invitation_mailer:
|
1157
|
+
greeting: Hi %{user_name},
|
1158
|
+
invitation_accepted:
|
1159
|
+
body: "%{invitee_name} has accepted your invitation to join %{resource_name}"
|
1160
|
+
subject: "%{invitee_name} has accepted your invitation to join %{resource_name}"
|
1161
|
+
invitation_email:
|
1162
|
+
body: "%{inviter_name} has invited you to join %{resource_name}"
|
1163
|
+
link_description: 'To accept this invitation, please click the link below:'
|
1164
|
+
subject: Invitation to join %{resource_name}
|
1165
|
+
thanks: Thank you,
|
1166
|
+
invitation_resent: Invitation resent!
|
1167
|
+
invitations: Invitations
|
1168
|
+
invited_by: Invited by
|
1132
1169
|
is_not_available_to_shipment_address: is not available to shipment address
|
1133
1170
|
iso: ISO Alpha-2
|
1134
1171
|
iso3: ISO Alpha-3
|
@@ -1164,7 +1201,6 @@ en:
|
|
1164
1201
|
list: List
|
1165
1202
|
live: Live
|
1166
1203
|
loading: Loading
|
1167
|
-
loading_tree: Loading tree. Please wait…
|
1168
1204
|
locale_changed: Locale Changed
|
1169
1205
|
location: Location
|
1170
1206
|
lock: Lock
|
@@ -1179,7 +1215,6 @@ en:
|
|
1179
1215
|
login_failed: Login authentication failed.
|
1180
1216
|
login_name: Login
|
1181
1217
|
logo: Logo
|
1182
|
-
logo_alt: Brand logo
|
1183
1218
|
logout: Logout
|
1184
1219
|
logs: Logs
|
1185
1220
|
look_for_similar_items: Look for similar items
|
@@ -1233,7 +1268,7 @@ en:
|
|
1233
1268
|
new_billing_address: New Billing Address
|
1234
1269
|
new_country: New Country
|
1235
1270
|
new_custom_domain: New Custom Domain
|
1236
|
-
new_customer:
|
1271
|
+
new_customer: New Customer
|
1237
1272
|
new_customer_return: New Customer Return
|
1238
1273
|
new_digital_asset: New digital asset
|
1239
1274
|
new_domain: New domain
|
@@ -1429,6 +1464,9 @@ en:
|
|
1429
1464
|
newsletter_form:
|
1430
1465
|
button_text_default: Submit
|
1431
1466
|
placeholder_default: Enter your email
|
1467
|
+
products:
|
1468
|
+
buy_buttons:
|
1469
|
+
display_name: Add To Cart
|
1432
1470
|
page_not_found: Sorry! Page you are looking can’t be found.
|
1433
1471
|
page_sections:
|
1434
1472
|
announcement_bar:
|
@@ -1459,7 +1497,6 @@ en:
|
|
1459
1497
|
video:
|
1460
1498
|
heading_1_default: Why I recommend it?
|
1461
1499
|
heading_2_default: There's nothing like a soft hint of blush to add dimension and color to your look.
|
1462
|
-
page_settings: Page settings
|
1463
1500
|
pages: Pages
|
1464
1501
|
pages_defaults:
|
1465
1502
|
homepage:
|
@@ -1517,6 +1554,7 @@ en:
|
|
1517
1554
|
percent: Percent
|
1518
1555
|
percent_per_item: Percent Per Item
|
1519
1556
|
permalink: Permalink
|
1557
|
+
permissions: Permissions
|
1520
1558
|
personal_details: Personal details
|
1521
1559
|
phone: Phone
|
1522
1560
|
place_order: Place Order
|
@@ -2119,6 +2157,7 @@ en:
|
|
2119
2157
|
translations_for: "%{resource_name} translations"
|
2120
2158
|
tree: Tree
|
2121
2159
|
true_label: 'TRUE'
|
2160
|
+
try_removing_filters: Try removing some filters to see more products
|
2122
2161
|
twitter: Twitter
|
2123
2162
|
type: Type
|
2124
2163
|
type_to_search: Type to search
|
@@ -2139,7 +2178,7 @@ en:
|
|
2139
2178
|
update_billing_address: Update billing address
|
2140
2179
|
update_contact_information: Update contact information
|
2141
2180
|
update_shipping_address: Update shipping address
|
2142
|
-
|
2181
|
+
updated_at: Updated at
|
2143
2182
|
updating: Updating
|
2144
2183
|
upload_image: Upload image
|
2145
2184
|
url: URL
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateSpreeIntegrations < ActiveRecord::Migration[7.2]
|
2
|
+
def change
|
3
|
+
create_table :spree_integrations, if_not_exists: true do |t|
|
4
|
+
t.references :store, null: false, index: true
|
5
|
+
t.string :type, null: false, index: true
|
6
|
+
t.text :preferences
|
7
|
+
t.boolean :active, default: false, null: false, index: true
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CreateSpreeInvitations < ActiveRecord::Migration[7.2]
|
2
|
+
def change
|
3
|
+
create_table :spree_invitations do |t|
|
4
|
+
t.string :email, index: true, null: false
|
5
|
+
t.string :token, index: { unique: true }, null: false
|
6
|
+
t.string :status, null: false, index: true
|
7
|
+
|
8
|
+
t.references :resource, polymorphic: true, index: true, null: false # eg. Store, Vendor, Account
|
9
|
+
t.references :inviter, polymorphic: true, index: true, null: false
|
10
|
+
t.references :invitee, polymorphic: true, index: true
|
11
|
+
t.references :role, null: false
|
12
|
+
|
13
|
+
t.datetime :accepted_at
|
14
|
+
t.datetime :expires_at, index: true
|
15
|
+
t.datetime :deleted_at, index: true
|
16
|
+
|
17
|
+
t.timestamps
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|