spree_cm_commissioner 1.14.0 → 1.16.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 +4 -4
- data/Gemfile.lock +12 -1
- data/README.md +43 -1
- data/app/assets/images/category_icons/art_icon.png +0 -0
- data/app/assets/images/category_icons/concert_icon.png +0 -0
- data/app/assets/images/category_icons/fundraising_icon.png +0 -0
- data/app/assets/images/category_icons/marathon_icon.png +0 -0
- data/app/assets/images/category_icons/online_icon.png +0 -0
- data/app/assets/images/category_icons/workshop_icon.png +0 -0
- data/app/controllers/spree/admin/users_controller_decorator.rb +13 -0
- data/app/controllers/spree/api/chatrace/guests_controller.rb +2 -1
- data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +1 -0
- data/app/controllers/spree/api/v2/storefront/cart_payment_method_groups_controller.rb +12 -1
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +3 -1
- data/app/controllers/spree/api/v2/tenant/cart_controller.rb +11 -0
- data/app/controllers/spree/api/v2/tenant/checkout_controller.rb +1 -0
- data/app/controllers/spree/api/v2/tenant/order_histories_controller.rb +65 -0
- data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +1 -1
- data/app/controllers/spree_cm_commissioner/well_known_controller.rb +46 -0
- data/app/factory/spree_cm_commissioner/invite_guest_claimed_telegram_message_factory.rb +8 -8
- data/app/helpers/spree/admin/base_helper_decorator.rb +2 -2
- data/app/helpers/spree_cm_commissioner/transit/order_query_helper.rb +17 -0
- data/app/interactors/spree_cm_commissioner/create_event.rb +31 -6
- data/app/interactors/spree_cm_commissioner/create_ticket.rb +36 -1
- data/app/interactors/spree_cm_commissioner/host_matcher.rb +28 -0
- data/app/interactors/spree_cm_commissioner/place_decoder.rb +16 -0
- data/app/interactors/spree_cm_commissioner/place_service.rb +32 -0
- data/app/interactors/spree_cm_commissioner/user_pin_code_authenticator.rb +9 -0
- data/app/models/concerns/spree_cm_commissioner/json_preference_validator.rb +23 -0
- data/app/models/concerns/spree_cm_commissioner/kyc_bitwise.rb +3 -1
- data/app/models/concerns/spree_cm_commissioner/store_preference.rb +2 -0
- data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +10 -0
- data/app/models/spree_cm_commissioner/guest.rb +11 -2
- data/app/models/spree_cm_commissioner/invite_guest.rb +8 -0
- data/app/models/spree_cm_commissioner/option_type_decorator.rb +2 -0
- data/app/models/spree_cm_commissioner/option_value_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/option_value_vehicle.rb +8 -0
- data/app/models/spree_cm_commissioner/order_decorator.rb +5 -0
- data/app/models/spree_cm_commissioner/payment_method_decorator.rb +8 -1
- data/app/models/spree_cm_commissioner/place.rb +3 -0
- data/app/models/spree_cm_commissioner/store_decorator.rb +2 -1
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +4 -0
- data/app/models/spree_cm_commissioner/taxon_place.rb +12 -0
- data/app/models/spree_cm_commissioner/tenant.rb +5 -0
- data/app/models/spree_cm_commissioner/user_decorator.rb +14 -3
- data/app/models/spree_cm_commissioner/vehicle.rb +3 -0
- data/app/models/spree_cm_commissioner/vehicle_option_type.rb +6 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +7 -3
- data/app/models/spree_cm_commissioner/vendor_place.rb +11 -3
- data/app/overrides/spree/admin/stores/_form/store_preferences.html.erb.deface +85 -12
- data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +3 -4
- data/app/queries/spree_cm_commissioner/reservation_query.rb +12 -0
- data/app/serializers/spree/v2/organizer/invite_guest_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +1 -0
- data/app/serializers/spree/v2/tenant/cart_serializer.rb +8 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +1 -1
- data/app/services/spree_cm_commissioner/organizer/export_invite_guest_csv_service.rb +63 -0
- data/app/services/spree_cm_commissioner/payment_method_type_mapper.rb +11 -0
- data/app/views/spree/admin/tenants/_form.html.erb +59 -2
- data/config/initializers/spree_permitted_attributes.rb +3 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20250127081646_add_preferences_to_cm_tenants.rb +7 -0
- data/db/migrate/20250527043231_create_spree_commissioner_taxon_places.rb +15 -0
- data/db/migrate/20250528090330_add_place_type_to_cm_vendor_place.rb +6 -0
- data/db/migrate/20250531074036_create_spree_cm_commissioner_option_value_vehicle.rb +10 -0
- data/db/migrate/20250531074258_create_spree_cm_commissioner_vehicle_option_types.rb +10 -0
- data/db/migrate/20250602094751_add_host_to_cm_tenants.rb +6 -0
- data/db/migrate/20250609015216_remove_claimed_at_and_expires_at_from_cm_invite_guest.rb +6 -0
- data/db/migrate/20250610080108_add_contact_to_cm_guests.rb +5 -0
- data/db/migrate/20250611023548_add_country_code_to_guests.rb +5 -0
- data/db/migrate/20250612035937_add_intel_phone_number_to_guests.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/invite_guests_factory.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/tenant_factory.rb +1 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +17 -4
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +1 -0
- data/spree_cm_commissioner.gemspec +2 -0
- metadata +62 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 169845d2403406e562178fb3b438559b9d4cc42d93776513b5b7235399f69e2a
|
4
|
+
data.tar.gz: 5d7526b7df7150bddd97deb2989f08a014437b4c4c9efc8a318405d335e35e27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba5ff297f04ed5f749794f56b8c38900d36ce76d5b78a7778c0e06007816004190745ad3664b038be3c84e30a540deb57715652ed6d8012593b57126a14dba9c
|
7
|
+
data.tar.gz: d83b272f1fe458cc17fa833e2edd1a643ffa9c25f888c8432bc4e08d10ce1b16e8a2e870b52532995448043dda00eab8473f50e8f687dbf11ee6e45eca58556e
|
data/Gemfile.lock
CHANGED
@@ -34,7 +34,7 @@ GIT
|
|
34
34
|
PATH
|
35
35
|
remote: .
|
36
36
|
specs:
|
37
|
-
spree_cm_commissioner (1.
|
37
|
+
spree_cm_commissioner (1.16.0)
|
38
38
|
activerecord-multi-tenant
|
39
39
|
activerecord_json_validator (~> 2.1, >= 2.1.3)
|
40
40
|
aws-sdk-cloudfront
|
@@ -66,6 +66,8 @@ PATH
|
|
66
66
|
spree_backend (>= 4.5.0)
|
67
67
|
spree_extension
|
68
68
|
spree_multi_vendor (>= 2.4.1)
|
69
|
+
spree_vpago
|
70
|
+
strong_password (~> 0.0.10)
|
69
71
|
telegram-bot
|
70
72
|
twilio-ruby (~> 5.48.0)
|
71
73
|
|
@@ -849,6 +851,14 @@ GEM
|
|
849
851
|
spree_backend (>= 4.3.0.rc1)
|
850
852
|
spree_emails (>= 4.3.0.rc1)
|
851
853
|
spree_extension
|
854
|
+
spree_vpago (2.0.5.pre.beta)
|
855
|
+
faraday
|
856
|
+
google-cloud-firestore
|
857
|
+
spree_api (>= 4.5)
|
858
|
+
spree_backend (>= 4.5)
|
859
|
+
spree_core (>= 4.5)
|
860
|
+
spree_extension
|
861
|
+
spree_multi_vendor (>= 2.4.1)
|
852
862
|
sprockets (4.2.1)
|
853
863
|
concurrent-ruby (~> 1.0)
|
854
864
|
rack (>= 2.2.4, < 4)
|
@@ -866,6 +876,7 @@ GEM
|
|
866
876
|
stimulus-rails (1.3.0)
|
867
877
|
railties (>= 6.0.0)
|
868
878
|
stringex (2.8.6)
|
879
|
+
strong_password (0.0.10)
|
869
880
|
telegram-bot (0.15.7)
|
870
881
|
actionpack (>= 4.0, < 7.1)
|
871
882
|
activesupport (>= 4.0, < 7.1)
|
data/README.md
CHANGED
@@ -123,6 +123,48 @@ EXCEPTION_TELEGRAM_BOT_TOKEN=""
|
|
123
123
|
EXCEPTION_NOTIFIER_TELEGRAM_CHANNEL_ID=""
|
124
124
|
```
|
125
125
|
|
126
|
+
## JSON Format Examples For Store and Tenant Preferences
|
127
|
+
|
128
|
+
### Asset Links Format
|
129
|
+
For Android app integration, use the following format in your `assetlinks.json`:
|
130
|
+
|
131
|
+
```json
|
132
|
+
[
|
133
|
+
{
|
134
|
+
"relation": ["delegate_permission/common.handle_all_urls"],
|
135
|
+
"target": {
|
136
|
+
"namespace": "android_app",
|
137
|
+
"package_name": "com.yourapp.app",
|
138
|
+
"sha256_cert_fingerprints": [
|
139
|
+
"SHA256_CERTIFICATE_FINGERPRINT_HERE"
|
140
|
+
]
|
141
|
+
}
|
142
|
+
}
|
143
|
+
]
|
144
|
+
```
|
145
|
+
|
146
|
+
### Apple App Site Association Format
|
147
|
+
For iOS app integration, use the following format in your `apple-app-site-association`:
|
148
|
+
|
149
|
+
```json
|
150
|
+
{
|
151
|
+
"webcredentials": {
|
152
|
+
"apps": [
|
153
|
+
"TEAM_ID.com.yourapp.app"
|
154
|
+
]
|
155
|
+
},
|
156
|
+
"applinks": {
|
157
|
+
"apps": [],
|
158
|
+
"details": [
|
159
|
+
{
|
160
|
+
"appID": "TEAM_ID.com.yourapp.app",
|
161
|
+
"paths": ["*"]
|
162
|
+
}
|
163
|
+
]
|
164
|
+
}
|
165
|
+
}
|
166
|
+
```
|
167
|
+
|
126
168
|
## Using Deface DSL (.deface files)
|
127
169
|
|
128
170
|
- Make sure the path of override should match the path of view template
|
@@ -338,7 +380,7 @@ end
|
|
338
380
|
|
339
381
|
## Protected Cloudfront with signed requests
|
340
382
|
|
341
|
-
To use signed cookies with CloudFront, you'll need to set up your CloudFront distribution to require signed cookies and then generate and distribute the signed cookies to your users. Here
|
383
|
+
To use signed cookies with CloudFront, you'll need to set up your CloudFront distribution to require signed cookies and then generate and distribute the signed cookies to your users. Here's how to do it using Terraform for infrastructure setup and Ruby for cookie generation.
|
342
384
|
|
343
385
|
### Generating keypair
|
344
386
|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -5,6 +5,19 @@ module Spree
|
|
5
5
|
base.before_action :build_profile, only: %i[create update]
|
6
6
|
end
|
7
7
|
|
8
|
+
# override
|
9
|
+
def create
|
10
|
+
@user = Spree.user_class.new(user_params)
|
11
|
+
@user.assigned_roles = Spree::Role.where(id: params.dig(:user, :spree_role_ids)).pluck(:name) if params.dig(:user, :spree_role_ids)
|
12
|
+
|
13
|
+
if @user.save
|
14
|
+
flash[:success] = flash_message_for(@user, :successfully_created)
|
15
|
+
redirect_to spree.edit_admin_user_path(@user)
|
16
|
+
else
|
17
|
+
render :new, status: :unprocessable_entity
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
8
21
|
private
|
9
22
|
|
10
23
|
def build_profile
|
@@ -48,7 +48,8 @@ module Spree
|
|
48
48
|
order_phone_number: order.intel_phone_number || order.customer_address&.phone,
|
49
49
|
checked_in_at: guest.check_in&.confirmed_at,
|
50
50
|
qr_data: guest.qr_data,
|
51
|
-
order_qr_data: order.qr_data
|
51
|
+
order_qr_data: order.qr_data,
|
52
|
+
country_code: guest.country_code
|
52
53
|
}
|
53
54
|
end
|
54
55
|
end
|
@@ -17,7 +17,7 @@ module Spree
|
|
17
17
|
# override
|
18
18
|
def collection
|
19
19
|
@collection ||= SpreeCmCommissioner::PaymentMethods::GroupByBank.new.execute(
|
20
|
-
payment_methods:
|
20
|
+
payment_methods: payment_methods,
|
21
21
|
preferred_payment_method_id: spree_current_user&.preferred_payment_method_id
|
22
22
|
)
|
23
23
|
end
|
@@ -26,6 +26,17 @@ module Spree
|
|
26
26
|
def collection_serializer
|
27
27
|
SpreeCmCommissioner::V2::Storefront::PaymentMethodGroupSerializer
|
28
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def payment_methods
|
33
|
+
methods = spree_current_order.available_payment_methods
|
34
|
+
|
35
|
+
return methods.reject(&:mini_app?) if params[:type].blank?
|
36
|
+
|
37
|
+
type = SpreeCmCommissioner::PaymentMethodTypeMapper.call(params[:type])
|
38
|
+
methods.select { |pm| pm.mini_app? && pm.type == type }
|
39
|
+
end
|
29
40
|
end
|
30
41
|
end
|
31
42
|
end
|
@@ -6,6 +6,7 @@ module Spree
|
|
6
6
|
include Spree::Api::V2::Storefront::OrderConcern
|
7
7
|
include Spree::Api::V2::CouponCodesHelper
|
8
8
|
include Spree::Api::V2::Storefront::MetadataControllerConcern
|
9
|
+
include SpreeCmCommissioner::OrderConcern
|
9
10
|
|
10
11
|
around_action :wrap_with_multitenant_without, except: %i[create]
|
11
12
|
|
@@ -138,6 +139,16 @@ module Spree
|
|
138
139
|
end
|
139
140
|
end
|
140
141
|
|
142
|
+
# Restart the checkout flow to bring the order back to the cart view
|
143
|
+
def restart_checkout_flow
|
144
|
+
spree_authorize! :update, spree_current_order, order_token
|
145
|
+
|
146
|
+
spree_current_order.restart_checkout_flow
|
147
|
+
spree_current_order.update_with_updater!
|
148
|
+
|
149
|
+
render_serialized_payload { serialized_current_order }
|
150
|
+
end
|
151
|
+
|
141
152
|
private
|
142
153
|
|
143
154
|
def wrap_with_multitenant_without(&block)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V2
|
4
|
+
module Tenant
|
5
|
+
class OrderHistoriesController < BaseController
|
6
|
+
# GET /api/v2/tenant/order_histories
|
7
|
+
# For user - no params needed
|
8
|
+
# For guest - pass: { "order_tokens[]": [1, 2, 3] }
|
9
|
+
|
10
|
+
around_action :wrap_with_multitenant_without
|
11
|
+
|
12
|
+
def index
|
13
|
+
render_serialized_payload do
|
14
|
+
serialize_collection(paginated_collection)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# PATCH /api/v2/tenant/order_histories/:id/archive
|
19
|
+
def archive
|
20
|
+
order_token = params[:id]
|
21
|
+
order = Spree::Order.not_archived.find_by!(token: order_token)
|
22
|
+
|
23
|
+
spree_authorize! :update, order, order_token
|
24
|
+
raise CanCan::AccessDenied unless order.payment?
|
25
|
+
|
26
|
+
if order.mark_as_archive
|
27
|
+
render_serialized_payload { serialize_resource(order) }
|
28
|
+
else
|
29
|
+
render_error_payload(order.errors.full_messages.to_sentence)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def wrap_with_multitenant_without(&block)
|
36
|
+
MultiTenant.without(&block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def collection
|
40
|
+
if spree_current_user.present?
|
41
|
+
spree_current_user.orders.payment.not_archived
|
42
|
+
else
|
43
|
+
order_tokens = Array(params[:order_tokens])
|
44
|
+
return Spree::Order.none if order_tokens.empty?
|
45
|
+
|
46
|
+
Spree::Order.payment.not_archived.without_user.where(token: order_tokens)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def collection_serializer
|
51
|
+
Spree::V2::Tenant::CartSerializer
|
52
|
+
end
|
53
|
+
|
54
|
+
def resource_serializer
|
55
|
+
Spree::V2::Tenant::CartSerializer
|
56
|
+
end
|
57
|
+
|
58
|
+
def model_class
|
59
|
+
Spree::Order
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -37,7 +37,7 @@ module SpreeCmCommissioner
|
|
37
37
|
bit_fields = SpreeCmCommissioner::KycBitwise::BIT_FIELDS.keys
|
38
38
|
|
39
39
|
if permitted_resource_params[:use_product_kyc] == '1'
|
40
|
-
permitted_resource_params[:kyc] =
|
40
|
+
permitted_resource_params[:kyc] = @product.kyc
|
41
41
|
else
|
42
42
|
@kyc_result = calculate_kyc_value(params[:variant])
|
43
43
|
permitted_resource_params[:kyc] = @kyc_result
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class WellKnownController < ApplicationController
|
3
|
+
before_action :identify_request_source
|
4
|
+
rescue_from StandardError, with: :handle_error
|
5
|
+
|
6
|
+
def show
|
7
|
+
case params[:id]
|
8
|
+
when 'assetlinks.json'
|
9
|
+
render_preference(:preferred_assetlinks)
|
10
|
+
when 'apple-app-site-association'
|
11
|
+
render_preference(:preferred_apple_app_site_association)
|
12
|
+
else
|
13
|
+
render_not_found
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def identify_request_source
|
20
|
+
host = params[:original_host].presence || request.host.downcase
|
21
|
+
|
22
|
+
result = SpreeCmCommissioner::HostMatcher.call(host: host)
|
23
|
+
|
24
|
+
@store = result.store
|
25
|
+
@tenant = result.tenant
|
26
|
+
end
|
27
|
+
|
28
|
+
def render_preference(preference_key)
|
29
|
+
if @store&.send(preference_key).present?
|
30
|
+
render json: @store.send(preference_key)
|
31
|
+
elsif @tenant&.send(preference_key).present?
|
32
|
+
render json: @tenant.send(preference_key)
|
33
|
+
else
|
34
|
+
render_not_found
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def render_not_found
|
39
|
+
render json: { error: 'Not found' }, status: :not_found
|
40
|
+
end
|
41
|
+
|
42
|
+
def handle_error
|
43
|
+
render json: { error: 'Internal server error' }, status: :internal_server_error
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -24,14 +24,15 @@
|
|
24
24
|
|
25
25
|
module SpreeCmCommissioner
|
26
26
|
class InviteGuestClaimedTelegramMessageFactory < TelegramMessageFactory
|
27
|
-
attr_reader :order, :vendor, :show_details_link
|
27
|
+
attr_reader :order, :vendor, :guest, :show_details_link
|
28
28
|
|
29
|
-
def initialize(title:, order:,
|
29
|
+
def initialize(title:, order:, guest:, **options)
|
30
30
|
@order = order
|
31
|
-
@vendor = vendor
|
32
|
-
@
|
31
|
+
@vendor = options[:vendor]
|
32
|
+
@guest = guest
|
33
|
+
@show_details_link = options[:show_details_link] || false
|
33
34
|
|
34
|
-
super(title: title, subtitle: subtitle)
|
35
|
+
super(title: title, subtitle: options[:subtitle])
|
35
36
|
end
|
36
37
|
|
37
38
|
def selected_line_items
|
@@ -79,9 +80,8 @@ module SpreeCmCommissioner
|
|
79
80
|
text = []
|
80
81
|
|
81
82
|
text << bold('🙍 Claimed By')
|
82
|
-
text << "Name: #{
|
83
|
-
text << "Tel: #{inline_code(
|
84
|
-
text << "Email: #{inline_code(order.email)}" if order.email.present?
|
83
|
+
text << "Name: #{guest.first_name} #{guest.last_name}" if guest.first_name.present? || guest.last_name.present?
|
84
|
+
text << "Tel: #{inline_code(guest.intel_phone_number)}" if guest.intel_phone_number.present?
|
85
85
|
|
86
86
|
if show_details_link && order.guests.any?
|
87
87
|
text << ''
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Spree
|
2
2
|
module Admin
|
3
3
|
module BaseHelperDecorator
|
4
|
-
def render_vector_icon(asset_path,
|
5
|
-
return inline_svg_tag asset_path, size: '24px*24px' if asset_path.end_with?('.svg')
|
4
|
+
def render_vector_icon(asset_path, options = {})
|
5
|
+
return inline_svg_tag asset_path, size: options[:size] || '24px*24px' if asset_path.end_with?('.svg')
|
6
6
|
|
7
7
|
image_tag asset_path, width: '24px'
|
8
8
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Transit
|
3
|
+
module OrderQueryHelper
|
4
|
+
def self.transit_orders_for_vendor(vendor_id)
|
5
|
+
return Spree::Order.none if vendor_id.nil?
|
6
|
+
|
7
|
+
Spree::Order
|
8
|
+
.includes(:user, :created_by, { payments: :payment_method }, { line_items: { variant: :product } })
|
9
|
+
.joins(line_items: { variant: :product })
|
10
|
+
.where(spree_products: { product_type: :transit })
|
11
|
+
.where(spree_variants: { vendor_id: vendor_id })
|
12
|
+
.distinct
|
13
|
+
.order(created_at: :desc)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -9,7 +9,8 @@ module SpreeCmCommissioner
|
|
9
9
|
assign_vendor
|
10
10
|
assign_prototype
|
11
11
|
create_child_taxon
|
12
|
-
|
12
|
+
build_asset
|
13
|
+
create_place
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
@@ -55,15 +56,39 @@ module SpreeCmCommissioner
|
|
55
56
|
context.fail!(message: child_taxon.errors.full_messages.join(', '))
|
56
57
|
end
|
57
58
|
|
58
|
-
def
|
59
|
-
return if context.params[
|
59
|
+
def asset(banner_type, asset_param, failure_message)
|
60
|
+
return if context.params[asset_param].nil?
|
60
61
|
|
61
|
-
banner =
|
62
|
+
banner = banner_type.create(
|
62
63
|
viewable: @parent_taxon,
|
63
|
-
attachment: context.params[
|
64
|
+
attachment: context.params[asset_param]
|
64
65
|
)
|
65
66
|
|
66
|
-
context.fail!(message:
|
67
|
+
context.fail!(message: failure_message) unless banner.persisted?
|
68
|
+
end
|
69
|
+
|
70
|
+
def build_asset
|
71
|
+
asset(SpreeCmCommissioner::TaxonCategoryIcon, :category_icon, 'Logo upload failed') if context.params[:category_icon].present?
|
72
|
+
asset(SpreeCmCommissioner::TaxonHomeBanner, :home_banner, 'Home banner upload failed') if context.params[:home_banner].present?
|
73
|
+
context.params[:app_banner] = context.params[:home_banner] if context.params[:use_main_photo] == '1'
|
74
|
+
asset(SpreeCmCommissioner::TaxonAppBanner, :app_banner, 'App banner upload failed') if context.params[:app_banner].present?
|
75
|
+
asset(SpreeCmCommissioner::TaxonWebBanner, :web_banner, 'Web banner upload failed') if context.params[:web_banner].present?
|
76
|
+
end
|
77
|
+
|
78
|
+
def create_place
|
79
|
+
return if context.params[:base_64_content].blank?
|
80
|
+
|
81
|
+
place = SpreeCmCommissioner::PlaceDecoder.process_place(context.params[:base_64_content])
|
82
|
+
|
83
|
+
if place.save
|
84
|
+
SpreeCmCommissioner::TaxonPlace.create(
|
85
|
+
place_id: place.id,
|
86
|
+
taxon_id: @parent_taxon.id,
|
87
|
+
description: context.params[:place_description]
|
88
|
+
)
|
89
|
+
else
|
90
|
+
context.fail!(message: place.errors.full_messages.join(', '))
|
91
|
+
end
|
67
92
|
end
|
68
93
|
end
|
69
94
|
end
|
@@ -9,6 +9,8 @@ module SpreeCmCommissioner
|
|
9
9
|
set_option_value
|
10
10
|
create_variant
|
11
11
|
create_stock_item
|
12
|
+
upload_image
|
13
|
+
create_place
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
@@ -75,6 +77,37 @@ module SpreeCmCommissioner
|
|
75
77
|
context.fail!(message: @stock_item.errors.full_messages.join(', '))
|
76
78
|
end
|
77
79
|
|
80
|
+
def upload_image
|
81
|
+
return if context.params[:ticket_image].blank?
|
82
|
+
|
83
|
+
@image = @ticket.master.images.new(attachment: context.params[:ticket_image])
|
84
|
+
return if @image.save
|
85
|
+
|
86
|
+
context.fail!(message: @image.errors.full_messages.join(', '))
|
87
|
+
end
|
88
|
+
|
89
|
+
def create_place
|
90
|
+
if context.params[:base_64_content].present?
|
91
|
+
place = SpreeCmCommissioner::PlaceDecoder.process_place(context.params[:base_64_content])
|
92
|
+
|
93
|
+
if place.save
|
94
|
+
product_place = SpreeCmCommissioner::ProductPlace.create(
|
95
|
+
place_id: place.id,
|
96
|
+
product_id: @ticket.id
|
97
|
+
)
|
98
|
+
context.fail!(message: product_place.errors.full_messages.join(', ')) unless product_place.persisted?
|
99
|
+
else
|
100
|
+
context.fail!(message: place.errors.full_messages.join(', '))
|
101
|
+
end
|
102
|
+
elsif context.params[:place_id].present?
|
103
|
+
product_place = SpreeCmCommissioner::ProductPlace.create(
|
104
|
+
place_id: context.params[:place_id],
|
105
|
+
product_id: @ticket.id
|
106
|
+
)
|
107
|
+
context.fail!(message: product_place.errors.full_messages.join(', ')) unless product_place.persisted?
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
78
111
|
def ticket_params
|
79
112
|
{
|
80
113
|
name: context.params[:name],
|
@@ -88,7 +121,9 @@ module SpreeCmCommissioner
|
|
88
121
|
vendor_id: context.params[:vendor_id],
|
89
122
|
status: context.params[:status],
|
90
123
|
shipping_category_id: context.params[:shipping_category_id],
|
91
|
-
option_type_ids: context.params[:option_type_ids]
|
124
|
+
option_type_ids: context.params[:option_type_ids],
|
125
|
+
allow_anonymous_booking: context.params[:allow_anonymous_booking],
|
126
|
+
allow_self_check_in: context.params[:allow_self_check_in]
|
92
127
|
}
|
93
128
|
end
|
94
129
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class HostMatcher < BaseInteractor
|
3
|
+
delegate :host, to: :context
|
4
|
+
|
5
|
+
def call
|
6
|
+
normalized_host = normalize_host(host)
|
7
|
+
|
8
|
+
context.store = find_store(normalized_host)
|
9
|
+
return if context.store.present?
|
10
|
+
|
11
|
+
context.tenant = find_tenant(normalized_host)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def normalize_host(host)
|
17
|
+
host.sub(/^www\./, '')
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_store(normalized_host)
|
21
|
+
Spree::Store.find_by(code: normalized_host)
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_tenant(normalized_host)
|
25
|
+
SpreeCmCommissioner::Tenant.find_by(host: "https://#{normalized_host}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class PlaceDecoder
|
3
|
+
def self.process_place(base_64_content)
|
4
|
+
begin
|
5
|
+
place_data = JSON.parse(Base64.strict_decode64(base_64_content))
|
6
|
+
rescue ArgumentError, JSON::ParserError => e
|
7
|
+
Rails.logger.error("Failed to decode and parse place data: #{e.message}")
|
8
|
+
return nil
|
9
|
+
end
|
10
|
+
|
11
|
+
place = SpreeCmCommissioner::Place.where(reference: place_data['reference']).first_or_initialize
|
12
|
+
place.assign_attributes(place_data)
|
13
|
+
place
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class PlaceService
|
3
|
+
def initialize(model:, place_class:, params:)
|
4
|
+
@model = model # e.g., Taxon or Product
|
5
|
+
@place_class = place_class # e.g., TaxonPlace or ProductPlace
|
6
|
+
@params = params
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
@base64_content = @params[:base_64_content]
|
11
|
+
@place_name = @params[:place_name]
|
12
|
+
|
13
|
+
if @base64_content.blank?
|
14
|
+
existing_place = @place_class
|
15
|
+
existing_place.delete if existing_place && @place_name.blank?
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
place = PlaceDecoder.process_place(@base64_content)
|
20
|
+
return if place.nil?
|
21
|
+
|
22
|
+
if place.save # rubocop:disable Style/GuardClause
|
23
|
+
existing_place = @place_class
|
24
|
+
if existing_place.present?
|
25
|
+
existing_place.update(place_id: place.id)
|
26
|
+
else
|
27
|
+
@model.places << place
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -33,6 +33,7 @@ module SpreeCmCommissioner
|
|
33
33
|
|
34
34
|
user = Spree::User.new(create_options)
|
35
35
|
user.confirmed_at = Time.zone.now
|
36
|
+
assign_role(user) if context.role.present?
|
36
37
|
|
37
38
|
if user.save
|
38
39
|
context.user = user
|
@@ -41,6 +42,14 @@ module SpreeCmCommissioner
|
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
45
|
+
def assign_role(user)
|
46
|
+
role = Spree::Role.find_by(name: context.role)
|
47
|
+
return unless role
|
48
|
+
|
49
|
+
user.assigned_roles = [role.name]
|
50
|
+
user.spree_roles << role
|
51
|
+
end
|
52
|
+
|
44
53
|
def mark_pin_code_expired!
|
45
54
|
SpreeCmCommissioner::PinCode.mark_expired!(context.pin_code_token)
|
46
55
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module JsonPreferenceValidator
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
validate :validate_json_preferences
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def validate_json_preferences
|
12
|
+
%i[preferred_assetlinks preferred_apple_app_site_association].each do |pref|
|
13
|
+
next if send(pref).blank?
|
14
|
+
|
15
|
+
begin
|
16
|
+
JSON.parse(send(pref))
|
17
|
+
rescue JSON::ParserError => e
|
18
|
+
errors.add(pref, "is not valid JSON: #{e.message}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|