spree_cm_commissioner 1.18.1 → 1.19.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -5
  3. data/app/controllers/spree/admin/event_blazer_queries_controller.rb +11 -4
  4. data/app/controllers/spree/admin/trip_blazer_queries_controller.rb +35 -0
  5. data/app/controllers/spree/api/v2/organizer/invite_crews_controller.rb +33 -0
  6. data/app/controllers/spree/api/v2/storefront/dynamic_field_options_controller.rb +5 -1
  7. data/app/controllers/spree/api/v2/tenant/checkout_controller.rb +2 -0
  8. data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +11 -0
  9. data/app/controllers/spree_cm_commissioner/well_known_controller.rb +21 -9
  10. data/app/interactors/spree_cm_commissioner/apple_app_site_association_fetcher.rb +27 -0
  11. data/app/interactors/spree_cm_commissioner/asset_links_fetcher.rb +27 -0
  12. data/app/interactors/spree_cm_commissioner/crew_invite_link_handler.rb +48 -0
  13. data/app/interactors/spree_cm_commissioner/telegram_chats_auto_finder.rb +144 -0
  14. data/app/models/spree_cm_commissioner/blazer_queryable.rb +8 -0
  15. data/app/models/spree_cm_commissioner/crew_invite_link.rb +4 -0
  16. data/app/models/spree_cm_commissioner/dynamic_field.rb +2 -0
  17. data/app/models/spree_cm_commissioner/dynamic_field_option.rb +2 -0
  18. data/app/models/spree_cm_commissioner/invite.rb +4 -6
  19. data/app/models/spree_cm_commissioner/pin_code.rb +3 -2
  20. data/app/models/spree_cm_commissioner/pin_code_telegram.rb +28 -0
  21. data/app/models/spree_cm_commissioner/promotion_category_decorator.rb +11 -0
  22. data/app/models/spree_cm_commissioner/taxon_decorator.rb +4 -2
  23. data/app/models/spree_cm_commissioner/telegram_chat.rb +6 -0
  24. data/app/models/spree_cm_commissioner/trip.rb +12 -0
  25. data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -0
  26. data/app/serializers/spree/v2/organizer/invite_crews_serializer.rb +11 -0
  27. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb +1 -1
  28. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -1
  29. data/app/views/blazer/queries/_content.html.erb +8 -0
  30. data/config/locales/en.yml +1 -0
  31. data/config/routes.rb +2 -0
  32. data/db/migrate/20250630103536_create_cm_telegram_chats.rb +13 -0
  33. data/db/migrate/20250707032008_add_vendor_id_to_spree_category.rb +7 -0
  34. data/db/migrate/20250711092937_add_position_to_cm_dynamic_fields.rb +11 -0
  35. data/db/migrate/20250711093045_add_position_to_cm_dynamic_field_options.rb +11 -0
  36. data/db/migrate/20250714121508_rename_cm_taxon_blazer_query_to_blazer_queryables.rb +7 -0
  37. data/db/migrate/20250714124323_make_cm_blazer_queryables_polymorphic.rb +19 -0
  38. data/lib/spree_cm_commissioner/version.rb +1 -1
  39. metadata +20 -4
  40. data/app/interactors/spree_cm_commissioner/universal_link_fetcher.rb +0 -54
  41. data/app/models/spree_cm_commissioner/taxon_blazer_query.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60a9ca64e7401f96f8cb7e220a28a12ca89d7bc84ce724b0e7751e1c0abf1d0e
4
- data.tar.gz: cb4e4fbfd87c785a73c23ee8fd3a02fadacf864d5c905df5a654c56069a79769
3
+ metadata.gz: dbe05a913d5525e83a57e29a837c4c1d5b9eec1607daba170f5ce305079b340b
4
+ data.tar.gz: '096d9299fd1faf8d19d7ca1ba00c82fbef35f1e1a938e48b0742f38a1f017aa8'
5
5
  SHA512:
6
- metadata.gz: 0db6f0473e7663f28e179e51cc68034c6b96315d402a38bb49fef0669ba23ae46cc615d7ee350ec551b1c7fd1686a724a1aef0057ce2b4f637913766c8cdd8c9
7
- data.tar.gz: bf5d35d082edc126bcead686c1d1de3e74f2a2bed22a1cbdd62e60dea23679c007ff1fb523f0a3447a3b598b1e3c66838b28f35e408b82024de877c5da237657
6
+ metadata.gz: a5b1efce06f85b8b0439b3d9bba50066547f386c7960fe808014ee29f52598f307407d4f3e40f8320b337adcb1776882bc5d31f9f30da2b8600ecef19e74b3db
7
+ data.tar.gz: 1a8bbf21cce85c8d0ce52acd9e1fe9a54f48e90a010829514f1a2e192542f4b03eb9ca40fc6e91d4a2450cd2b477d380aa9bd0dfdc23f748a07e78381f7fe810
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (1.18.1)
37
+ spree_cm_commissioner (1.19.0)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -572,10 +572,6 @@ GEM
572
572
  nokogiri (1.15.4)
573
573
  mini_portile2 (~> 2.8.2)
574
574
  racc (~> 1.4)
575
- nokogiri (1.15.4-x86_64-darwin)
576
- racc (~> 1.4)
577
- nokogiri (1.15.4-x86_64-linux)
578
- racc (~> 1.4)
579
575
  noticed (1.6.3)
580
576
  http (>= 4.0.0)
581
577
  rails (>= 5.2.0)
@@ -2,21 +2,28 @@ module Spree
2
2
  module Admin
3
3
  class EventBlazerQueriesController < Spree::Admin::ResourceController
4
4
  def model_class
5
- SpreeCmCommissioner::TaxonBlazerQuery
5
+ SpreeCmCommissioner::BlazerQueryable
6
6
  end
7
7
 
8
8
  def object_name
9
- 'spree_cm_commissioner_taxon_blazer_query'
9
+ 'spree_cm_commissioner_blazer_queryable'
10
10
  end
11
11
 
12
12
  def create
13
- event_blazer = SpreeCmCommissioner::TaxonBlazerQuery.new(taxon_id: params[:event_id], blazer_query_id: params[:blazer_query_id])
13
+ queryable = Spree::Taxon.find(params[:event_id])
14
+
15
+ event_blazer = SpreeCmCommissioner::BlazerQueryable.new(
16
+ queryable: queryable,
17
+ blazer_query_id: params[:blazer_query_id]
18
+ )
19
+
14
20
  if event_blazer.save
15
21
  flash[:success] = I18n.t('event_blazer_queries.success')
16
22
  else
17
23
  flash[:alert] = event_blazer.errors.full_messages.join(', ')
18
24
  end
19
- redirect_to blazer.query_path(id: event_blazer.blazer_query_id, event_id: event_blazer.taxon_id)
25
+
26
+ redirect_to blazer.query_path(id: event_blazer.blazer_query_id, event_id: queryable.id)
20
27
  end
21
28
  end
22
29
  end
@@ -0,0 +1,35 @@
1
+ module Spree
2
+ module Admin
3
+ class TripBlazerQueriesController < Spree::Admin::ResourceController
4
+ def model_class
5
+ SpreeCmCommissioner::BlazerQueryable
6
+ end
7
+
8
+ def object_name
9
+ 'spree_cm_commissioner_blazer_queryable'
10
+ end
11
+
12
+ def create
13
+ queryable = SpreeCmCommissioner::Trip.find_by(id: params[:trip_id])
14
+
15
+ if queryable.nil?
16
+ flash[:alert] = I18n.t('trip_blazer_queries.not_found')
17
+ redirect_to request.referer || spree.admin_trips_path and return
18
+ end
19
+
20
+ trip_blazer = SpreeCmCommissioner::BlazerQueryable.new(
21
+ queryable: queryable,
22
+ blazer_query_id: params[:blazer_query_id]
23
+ )
24
+
25
+ if trip_blazer.save
26
+ flash[:success] = I18n.t('trip_blazer_queries.success')
27
+ else
28
+ flash[:alert] = trip_blazer.errors.full_messages.join(', ')
29
+ end
30
+
31
+ redirect_to blazer.query_path(id: trip_blazer.blazer_query_id, trip_id: queryable.id)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Organizer
5
+ class InviteCrewsController < ::Spree::Api::V2::Organizer::BaseController
6
+ def show
7
+ render_serialized_payload { serialize_resource(invite) }
8
+ end
9
+
10
+ def update
11
+ context = SpreeCmCommissioner::CrewInviteLinkHandler.call(
12
+ params: params
13
+ )
14
+
15
+ if context.success?
16
+ render_serialized_payload { serialize_resource(context.invite) }
17
+ else
18
+ render_error_payload(context.message || I18n.t('invite.accept_fail'))
19
+ end
20
+ end
21
+
22
+ def invite
23
+ @invite ||= SpreeCmCommissioner::Invite.find_by!(token: params[:id])
24
+ end
25
+
26
+ def resource_serializer
27
+ ::Spree::V2::Organizer::InviteCrewsSerializer
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -8,7 +8,11 @@ module Spree
8
8
  return @collection if defined?(@collection)
9
9
  return SpreeCmCommissioner::DynamicFieldOption.none if params[:dynamic_field_id].blank?
10
10
 
11
- @collection = SpreeCmCommissioner::DynamicFieldOption.where(dynamic_field_id: params[:dynamic_field_id])
11
+ @collection = SpreeCmCommissioner::DynamicFieldOption
12
+ .where(dynamic_field_id: params[:dynamic_field_id])
13
+ .active
14
+ .order(position: :asc)
15
+
12
16
  @collection = @collection.where('value LIKE ?', "%#{params[:query]}%") if params[:query].present?
13
17
  @collection
14
18
  end
@@ -27,6 +27,8 @@ module Spree
27
27
  end
28
28
 
29
29
  def complete
30
+ return render_serialized_payload { serialized_current_order } if spree_current_order.confirm? || spree_current_order.complete?
31
+
30
32
  spree_authorize! :update, spree_current_order, order_token
31
33
 
32
34
  result = complete_service.call(order: spree_current_order)
@@ -6,6 +6,17 @@ module SpreeCmCommissioner
6
6
  def self.prepended(base)
7
7
  base.include SpreeCmCommissioner::OrderConcern
8
8
  end
9
+
10
+ # Override Spree's default behavior:
11
+ # By default, Spree raises an error if `complete` is called on a completed or confirmed order.
12
+ # We want to allow this call to succeed, so the API can be used both to:
13
+ # - complete the order (if it's not yet complete), or
14
+ # - return the latest state of a confirmed or completed order without raising a forbidden error.
15
+ def complete
16
+ return render_serialized_payload { serialized_current_order } if spree_current_order.confirm? || spree_current_order.complete?
17
+
18
+ super
19
+ end
9
20
  end
10
21
  end
11
22
  end
@@ -4,25 +4,37 @@ module SpreeCmCommissioner
4
4
  rescue_from StandardError, with: :handle_error
5
5
 
6
6
  def assetlinks_json
7
- render_universal_link('assetlinks.json')
7
+ render_platform_link(:android)
8
8
  end
9
9
 
10
10
  def apple_app_site_association
11
- render_universal_link('apple-app-site-association')
11
+ render_platform_link(:ios)
12
12
  end
13
13
 
14
14
  private
15
15
 
16
- def render_universal_link(universal_link)
17
- result = SpreeCmCommissioner::UniversalLinkFetcher.new(
18
- universal_link: universal_link,
16
+ def render_platform_link(platform)
17
+ fetcher_class = platform_link_finder(platform)
18
+
19
+ result = fetcher_class.call(
19
20
  store: @store,
20
21
  tenant: @tenant,
21
- refresh: params[:_refresh].to_s == 'true'
22
- ).call
22
+ refreshed: params[:_refreshed].present?
23
+ )
24
+
25
+ if result.success? && result.contents.present?
26
+ render json: result.contents
27
+ else
28
+ render_not_found
29
+ end
30
+ end
23
31
 
24
- if result[:success]
25
- render json: result[:data]
32
+ def platform_link_finder(platform)
33
+ case platform
34
+ when :android
35
+ SpreeCmCommissioner::AssetLinksFetcher
36
+ when :ios
37
+ SpreeCmCommissioner::AppleAppSiteAssociationFetcher
26
38
  else
27
39
  render_not_found
28
40
  end
@@ -0,0 +1,27 @@
1
+ module SpreeCmCommissioner
2
+ class AppleAppSiteAssociationFetcher < BaseInteractor
3
+ delegate :store, :tenant, :refreshed, to: :context
4
+
5
+ def call
6
+ key = cache_key
7
+
8
+ CmAppLogger.log(label: 'LOOKING_UP_CACHE', data: { cache_key: key })
9
+
10
+ Rails.cache.delete(key) if refreshed
11
+
12
+ context.contents = Rails.cache.fetch(key) do
13
+ CmAppLogger.log(label: 'CACHE_MISS', data: { cache_key: key })
14
+ resource.preferred_apple_app_site_association
15
+ end
16
+ end
17
+
18
+ def cache_key
19
+ updated_at = tenant&.updated_at || store&.updated_at
20
+ "well_known:apple-app-site-association:#{resource.class.name}:#{resource.id}:#{updated_at}"
21
+ end
22
+
23
+ def resource
24
+ tenant || store
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module SpreeCmCommissioner
2
+ class AssetLinksFetcher < BaseInteractor
3
+ delegate :store, :tenant, :refreshed, to: :context
4
+
5
+ def call
6
+ key = cache_key
7
+
8
+ CmAppLogger.log(label: 'LOOKING_UP_CACHE', data: { cache_key: key })
9
+
10
+ Rails.cache.delete(key) if refreshed
11
+
12
+ context.contents = Rails.cache.fetch(key) do
13
+ CmAppLogger.log(label: 'CACHE_MISS', data: { cache_key: key })
14
+ resource.preferred_assetlinks
15
+ end
16
+ end
17
+
18
+ def cache_key
19
+ updated_at = tenant&.updated_at || store&.updated_at
20
+ "well_known:assetlinks.json:#{resource.class.name}:#{resource.id}:#{updated_at}"
21
+ end
22
+
23
+ def resource
24
+ tenant || store
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,48 @@
1
+ module SpreeCmCommissioner
2
+ class CrewInviteLinkHandler < BaseInteractor
3
+ delegate :params, to: :context
4
+
5
+ def call
6
+ validate_data
7
+ assign_role_to_user
8
+ create_user_event
9
+ end
10
+
11
+ private
12
+
13
+ def validate_data
14
+ if invite.nil?
15
+ context.fail!(message: I18n.t('invite.url_not_found'))
16
+ else
17
+ context.invite = invite
18
+ end
19
+ end
20
+
21
+ def assign_role_to_user
22
+ return if user.operator?
23
+
24
+ role = Spree::Role.find_by(name: 'operator')
25
+ role_user = Spree::RoleUser.new(user_id: user.id, role_id: role.id)
26
+ role_user.save
27
+ end
28
+
29
+ def create_user_event
30
+ @user_event = SpreeCmCommissioner::UserEvent.new(
31
+ taxon_id: invite.taxon_id,
32
+ user_id: user.id
33
+ )
34
+
35
+ return if @user_event.save
36
+
37
+ context.fail!(message: I18n.t('invite.already_invited'))
38
+ end
39
+
40
+ def invite
41
+ @invite ||= SpreeCmCommissioner::Invite.find_by(token: params[:id])
42
+ end
43
+
44
+ def user
45
+ @user ||= Spree::User.find(params[:user_id])
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,144 @@
1
+ module SpreeCmCommissioner
2
+ class TelegramChatsAutoFinder < BaseInteractor
3
+ delegate :contact, :pin_code, to: :context
4
+
5
+ def call
6
+ context.chats = []
7
+ context.verified_chat_ids = []
8
+
9
+ updates = fetch_updates
10
+
11
+ if updates['result'].any?
12
+ updates['result'].sort_by { |u| u['update_id'] }.reverse.each do |update|
13
+ handle_message_update(update) if update['message']
14
+ handle_channel_post_update(update) if update['channel_post']
15
+ handle_chat_member_update(update) if update['my_chat_member']
16
+ end
17
+ end
18
+ context.fail!(message: 'No pin codes verified') if context.verified_chat_ids.empty?
19
+ end
20
+
21
+ private
22
+
23
+ def handle_chat_member_update(update)
24
+ chat = update.dig('my_chat_member', 'chat')
25
+ return unless chat
26
+
27
+ chat_data = {
28
+ id: chat['id'],
29
+ title: chat['title'] || 'Unnamed Chat',
30
+ type: chat['type']
31
+ }
32
+
33
+ return if context.chats.any? { |c| c[:id] == chat_data[:id] }
34
+
35
+ db_chat = SpreeCmCommissioner::TelegramChat.find_or_initialize_by(chat_id: chat_data[:id])
36
+ is_new_chat = db_chat.new_record?
37
+ db_chat.update(chat_title: chat_data[:title], chat_type: chat_data[:type])
38
+ context.chats << chat_data
39
+ message = "👋Hello! This is Bookme+ bot.\n\nPlease enter the 6-digit PIN code displayed in your portal."
40
+ send_message(chat_data[:id], message) if is_new_chat
41
+ end
42
+
43
+ def handle_channel_post_update(update)
44
+ message = update['channel_post']
45
+ process_pin_code_message(message)
46
+ end
47
+
48
+ def handle_message_update(update)
49
+ message = update['message']
50
+ process_pin_code_message(message)
51
+ end
52
+
53
+ def process_pin_code_message(message)
54
+ chat_id = message.dig('chat', 'id')
55
+ text = message['text']&.strip
56
+
57
+ return unless valid_pin_code?(text, chat_id)
58
+
59
+ pin_code_record = find_pin_code_record
60
+ return unless pin_code_record
61
+
62
+ vendor = find_vendor
63
+ return unless vendor
64
+
65
+ chat = update_telegram_chat(message, chat_id)
66
+ return unless chat
67
+
68
+ handle_successful_verification(chat, vendor, pin_code_record)
69
+ end
70
+
71
+ def valid_pin_code?(text, chat_id)
72
+ text && chat_id && text == pin_code
73
+ end
74
+
75
+ def find_pin_code_record
76
+ pin_code_record = SpreeCmCommissioner::PinCodeTelegram.find_by(code: pin_code, contact: contact)
77
+ unless pin_code_record
78
+ context.fail!(message: "Pin code #{pin_code} not found for contact #{contact}")
79
+ return nil
80
+ end
81
+ pin_code_record
82
+ end
83
+
84
+ def find_vendor
85
+ vendor = Spree::Vendor.find_by(id: contact)
86
+ unless vendor
87
+ context.fail!(message: "Vendor not found for contact #{contact}")
88
+ return nil
89
+ end
90
+ vendor
91
+ end
92
+
93
+ def update_telegram_chat(message, chat_id)
94
+ chat = SpreeCmCommissioner::TelegramChat.find_or_initialize_by(chat_id: chat_id)
95
+ unless chat.update(
96
+ chat_title: message.dig('chat', 'title') || 'Unnamed Chat',
97
+ chat_type: message.dig('chat', 'type')
98
+ )
99
+ context.fail!(message: "Failed to update chat: #{chat.errors.full_messages.join(', ')}")
100
+ return nil
101
+ end
102
+
103
+ context.chats << { id: chat.chat_id, title: chat.chat_title, type: chat.chat_type }
104
+ chat
105
+ end
106
+
107
+ def handle_successful_verification(chat, vendor, pin_code_record)
108
+ return if chat.vendor && chat.vendor != vendor
109
+
110
+ update_vendor_preferences(vendor, chat)
111
+ chat.update(active: true, vendor: vendor)
112
+ expire_pin_code(pin_code_record)
113
+ send_success_message(chat.chat_id, vendor.name)
114
+ context.verified_chat_ids << chat.chat_id
115
+ end
116
+
117
+ def update_vendor_preferences(vendor, chat)
118
+ vendor.update(
119
+ preferred_telegram_chat_id: chat.chat_id,
120
+ preferred_telegram_chat_name: chat.chat_title,
121
+ preferred_telegram_chat_type: chat.chat_type
122
+ )
123
+ end
124
+
125
+ def expire_pin_code(pin_code_record)
126
+ pin_code_record.expire
127
+ pin_code_record.save
128
+ end
129
+
130
+ def send_success_message(chat_id, vendor_name)
131
+ message = "✅ PIN code verified successfully! This chat is now connected to <b>#{vendor_name}</b>.\n\n" \
132
+ 'All completed orders will be sent to this chat.'
133
+ send_message(chat_id, message)
134
+ end
135
+
136
+ def fetch_updates
137
+ ::Telegram.bot.get_updates
138
+ end
139
+
140
+ def send_message(chat_id, text)
141
+ ::Telegram.bot.send_message(chat_id: chat_id, text: text, parse_mode: 'HTML')
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,8 @@
1
+ module SpreeCmCommissioner
2
+ class BlazerQueryable < SpreeCmCommissioner::Base
3
+ belongs_to :queryable, polymorphic: true
4
+ belongs_to :blazer_query, class_name: 'Blazer::Query'
5
+
6
+ validates :queryable_id, uniqueness: { scope: %i[queryable_type blazer_query_id], message: I18n.t('event_blazer_queries.fail') }
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ module SpreeCmCommissioner
2
+ class CrewInviteLink < Invite
3
+ end
4
+ end
@@ -1,5 +1,7 @@
1
1
  module SpreeCmCommissioner
2
2
  class DynamicField < SpreeCmCommissioner::Base
3
+ acts_as_list column: :position, scope: :vendor_id
4
+
3
5
  belongs_to :vendor, class_name: 'Spree::Vendor', optional: false
4
6
 
5
7
  has_many :dynamic_field_options, class_name: 'SpreeCmCommissioner::DynamicFieldOption', dependent: :destroy
@@ -1,5 +1,7 @@
1
1
  module SpreeCmCommissioner
2
2
  class DynamicFieldOption < SpreeCmCommissioner::Base
3
+ acts_as_list column: :position, scope: :dynamic_field_id
4
+
3
5
  belongs_to :dynamic_field, class_name: 'SpreeCmCommissioner::DynamicField', optional: false
4
6
  has_many :guest_dynamic_fields, class_name: 'SpreeCmCommissioner::GuestDynamicField', dependent: :restrict_with_error
5
7
 
@@ -5,16 +5,14 @@ module SpreeCmCommissioner
5
5
  has_many :invite_user_events, class_name: 'SpreeCmCommissioner::InviteUserEvent', dependent: :destroy
6
6
  scope :active, -> { where('expires_at > ?', Time.current) }
7
7
 
8
- after_create :set_expiration
9
-
10
- def set_expiration
11
- update(expires_at: 3.days.from_now)
12
- end
13
-
14
8
  def invite_url
15
9
  "#{Spree::Store.default.formatted_url}/invite/#{token}?utm_source=email"
16
10
  end
17
11
 
12
+ def invite_crew_link
13
+ "#{Spree::Store.default.formatted_url}/invite_crews/#{token}"
14
+ end
15
+
18
16
  def url_valid?
19
17
  expires_at.present? && expires_at > Time.current
20
18
  end
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
2
2
  class PinCode < SpreeCmCommissioner::Base
3
3
  has_secure_token
4
4
 
5
- enum contact_type: { 'phone_number' => 0, 'email' => 1 }
5
+ enum contact_type: { 'phone_number' => 0, 'email' => 1, 'telegram' => 2 }
6
6
 
7
7
  validates :code, length: { maximum: 6 }
8
8
  validates :contact, presence: true
@@ -130,7 +130,8 @@ module SpreeCmCommissioner
130
130
  'SpreeCmCommissioner::PinCodeMobileConfirm' => I18n.t('pincode.readable_type.confirmation_code'),
131
131
  'SpreeCmCommissioner::PinCodeUpdateUserLogin' => I18n.t('pincode.readable_type.update_user_login'),
132
132
  'SpreeCmCommissioner::PinCodeEmailConfirm' => I18n.t('pincode.readable_type.confirmation_code'),
133
- 'SpreeCmCommissioner::OtpCode' => I18n.t('pincode.readable_type.otp_code')
133
+ 'SpreeCmCommissioner::OtpCode' => I18n.t('pincode.readable_type.otp_code'),
134
+ 'SpreeCmCommissioner::PinCodeTelegram' => I18n.t('pincode.readable_type.telegram_verification')
134
135
  }
135
136
  end
136
137
 
@@ -0,0 +1,28 @@
1
+ module SpreeCmCommissioner
2
+ class PinCodeTelegram < PinCode
3
+ before_validation :set_telegram_attrs, on: :create
4
+ validates :contact, presence: true, numericality: { only_integer: true }, if: :telegram?
5
+
6
+ belongs_to :vendor, class_name: 'Spree::Vendor', foreign_key: 'contact', primary_key: 'id'
7
+
8
+ def telegram?
9
+ true
10
+ end
11
+
12
+ def expires_in_seconds
13
+ 5 * 60
14
+ end
15
+
16
+ def expired?
17
+ expired_at < Time.zone.now
18
+ end
19
+
20
+ private
21
+
22
+ def set_telegram_attrs
23
+ self.contact_type = :telegram
24
+ self.type = 'SpreeCmCommissioner::PinCodeTelegram'
25
+ self.expired_at = Time.zone.now + expires_in_seconds unless expired_at
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ module PromotionCategoryDecorator
3
+ def self.prepended(base)
4
+ base.belongs_to :vendor, class_name: 'Spree::Vendor', optional: true
5
+ end
6
+ end
7
+ end
8
+
9
+ unless Spree::PromotionCategory.included_modules.include?(SpreeCmCommissioner::PromotionCategoryDecorator)
10
+ Spree::PromotionCategory.prepend(SpreeCmCommissioner::PromotionCategoryDecorator)
11
+ end
@@ -57,14 +57,16 @@ module SpreeCmCommissioner
57
57
  base.has_many :crew_invites, class_name: 'SpreeCmCommissioner::CrewInvite', dependent: :destroy
58
58
  base.has_many :invite_user_events, through: :user_events, class_name: 'SpreeCmCommissioner::InviteUserEvent'
59
59
 
60
+ base.has_many :crew_invite_links, class_name: 'SpreeCmCommissioner::CrewInviteLink', dependent: :destroy
61
+
60
62
  base.has_many :invite_guests, class_name: 'SpreeCmCommissioner::InviteGuest', foreign_key: :event_id
61
63
 
62
64
  base.has_many :line_items, through: :products
63
65
  base.has_many :event_line_items, class_name: 'Spree::LineItem', foreign_key: :event_id
64
66
  base.has_many :event_products, class_name: 'Spree::Product', foreign_key: :event_id
65
67
 
66
- base.has_many :event_blazer_queries, class_name: 'SpreeCmCommissioner::TaxonBlazerQuery'
67
- base.has_many :blazer_queries, through: :event_blazer_queries, class_name: 'Blazer::Query'
68
+ base.has_many :event_blazer_queries, as: :queryable, class_name: 'SpreeCmCommissioner::BlazerQueryable'
69
+ base.has_many :blazer_queries, through: :event_blazer_queries, source: :blazer_query, class_name: 'Blazer::Query'
68
70
 
69
71
  base.has_many :taxon_option_types, class_name: 'SpreeCmCommissioner::TaxonOptionType'
70
72
  base.has_many :taxon_option_values, class_name: 'SpreeCmCommissioner::TaxonOptionValue'
@@ -0,0 +1,6 @@
1
+ module SpreeCmCommissioner
2
+ class TelegramChat < Base
3
+ belongs_to :vendor, class_name: 'Spree::Vendor'
4
+ validates :chat_id, presence: true, uniqueness: true
5
+ end
6
+ end
@@ -4,6 +4,18 @@ module SpreeCmCommissioner
4
4
  attr_accessor :hours, :minutes, :seconds
5
5
 
6
6
  before_validation :convert_duration_to_seconds
7
+
8
+ belongs_to :product, class_name: 'Spree::Product', inverse_of: :trip, optional: false
9
+ belongs_to :vehicle, class_name: 'SpreeCmCommissioner::Vehicle', optional: false
10
+ belongs_to :origin, class_name: 'SpreeCmCommissioner::Place', optional: true
11
+ belongs_to :destination, class_name: 'SpreeCmCommissioner::Place', optional: true
12
+
13
+ has_many :trip_blazer_queries, as: :queryable, class_name: 'SpreeCmCommissioner::BlazerQueryable'
14
+ has_many :blazer_queries, through: :trip_blazer_queries, source: :blazer_query, class_name: 'Blazer::Query'
15
+
16
+ has_many :trip_stops, class_name: 'SpreeCmCommissioner::TripStop', dependent: :destroy
17
+ has_many :variants, through: :product
18
+ has_many :inventory_items, through: :variants
7
19
  belongs_to :variant, class_name: 'Spree::Variant'
8
20
 
9
21
  belongs_to :route, class_name: 'Spree::Product'
@@ -78,6 +78,7 @@ module SpreeCmCommissioner
78
78
  base.has_many :invoices, class_name: 'SpreeCmCommissioner::Invoice', dependent: :destroy
79
79
  base.has_many :subscriptions, through: :customers, class_name: 'SpreeCmCommissioner::Subscription'
80
80
  base.has_many :subscription_orders, through: :subscriptions, class_name: 'Spree::Order', source: :orders
81
+ base.has_many :promotion_categories, class_name: 'Spree::PromotionCategory', foreign_key: :vendor_id, dependent: :destroy
81
82
 
82
83
  base.has_many :homepage_section_relatables,
83
84
  class_name: 'SpreeCmCommissioner::HomepageSectionRelatable',
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module V2
3
+ module Organizer
4
+ class InviteCrewsSerializer < BaseSerializer
5
+ attributes :token, :expires_at
6
+ belongs_to :taxon, serializer: Spree::V2::Organizer::TaxonSerializer
7
+ belongs_to :inviter, serializer: Spree::V2::Organizer::UserSerializer
8
+ end
9
+ end
10
+ end
11
+ end
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Storefront
4
4
  class DynamicFieldOptionSerializer < BaseSerializer
5
- attributes :id, :value, :dynamic_field_id, :status, :created_at, :updated_at
5
+ attributes :id, :value, :dynamic_field_id, :status, :created_at, :updated_at, :position
6
6
  end
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Storefront
4
4
  class DynamicFieldSerializer < BaseSerializer
5
- attributes :id, :label, :data_type, :vendor_id, :multiple_select, :created_at, :updated_at
5
+ attributes :id, :label, :data_type, :vendor_id, :multiple_select, :created_at, :updated_at, :position
6
6
 
7
7
  has_many :dynamic_field_options, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
8
8
  end
@@ -47,6 +47,14 @@
47
47
  class: "btn btn-primary",
48
48
  style: "margin-left: 10px;" %>
49
49
  </div>
50
+ <% elsif !@error && @success && params[:trip_id].present? %>
51
+ <div>
52
+ <%= link_to 'Save Trip',
53
+ spree.admin_trip_blazer_queries_path(trip_id: params[:trip_id], blazer_query_id: @query.id),
54
+ method: :post,
55
+ class: "btn btn-primary",
56
+ style: "margin-left: 10px;" %>
57
+ </div>
50
58
  <% end %>
51
59
  </div>
52
60
 
@@ -547,6 +547,7 @@ en:
547
547
  update_user_login: "update user code"
548
548
  contact_update: "update contact code"
549
549
  otp_code: "OTP code"
550
+ telegram_verification: "telegram code"
550
551
 
551
552
  notifications:
552
553
  spree_cm_commissioner:
data/config/routes.rb CHANGED
@@ -274,6 +274,7 @@ Spree::Core::Engine.add_routes do
274
274
  resources :vendors, controller: :tenant_vendors
275
275
  end
276
276
  resources :event_blazer_queries
277
+ resources :trip_blazer_queries
277
278
  end
278
279
 
279
280
  resources :events, controller: 'events/base' do
@@ -450,6 +451,7 @@ Spree::Core::Engine.add_routes do
450
451
  resources :images
451
452
  resource :s3_signed_urls
452
453
  resources :invites
454
+ resources :invite_crews, only: %i[show update]
453
455
  resources :invite_guests, only: %i[show update]
454
456
  end
455
457
 
@@ -0,0 +1,13 @@
1
+ class CreateCmTelegramChats < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cm_telegram_chats, if_not_exists: true do |t|
4
+ t.bigint :chat_id, null: false
5
+ t.string :chat_title
6
+ t.string :chat_type
7
+ t.boolean :active, default: false
8
+ t.references :vendor, foreign_key: { to_table: :spree_vendors }
9
+ t.timestamps
10
+ end
11
+ add_index :cm_telegram_chats, :chat_id, unique: true, if_not_exists: true
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ class AddVendorIdToSpreeCategory < ActiveRecord::Migration[7.0]
2
+ def change
3
+ unless column_exists?(:spree_promotion_categories, :vendor_id)
4
+ add_reference :spree_promotion_categories, :vendor, index: true, foreign_key: { to_table: :spree_vendors }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ class AddPositionToCmDynamicFields < ActiveRecord::Migration[7.0]
2
+ def change
3
+ unless column_exists?(:cm_dynamic_fields, :position)
4
+ add_column :cm_dynamic_fields, :position, :integer, default: 0, null: false
5
+ end
6
+
7
+ unless index_exists?(:cm_dynamic_fields, :position, name: 'index_dynamic_fields_on_position')
8
+ add_index :cm_dynamic_fields, :position, name: 'index_dynamic_fields_on_position'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class AddPositionToCmDynamicFieldOptions < ActiveRecord::Migration[7.0]
2
+ def change
3
+ unless column_exists?(:cm_dynamic_field_options, :position)
4
+ add_column :cm_dynamic_field_options, :position, :integer, default: 0, null: false
5
+ end
6
+
7
+ unless index_exists?(:cm_dynamic_field_options, :position, name: 'index_dynamic_field_options_on_position')
8
+ add_index :cm_dynamic_field_options, :position, name: 'index_dynamic_field_options_on_position'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ class RenameCmTaxonBlazerQueryToBlazerQueryables < ActiveRecord::Migration[7.0]
2
+ def change
3
+ if table_exists?(:cm_taxon_blazer_queries)
4
+ rename_table :cm_taxon_blazer_queries, :cm_blazer_queryables
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ class MakeCmBlazerQueryablesPolymorphic < ActiveRecord::Migration[7.0]
2
+ def change
3
+ if column_exists?(:cm_blazer_queryables, :taxon_id) && !column_exists?(:cm_blazer_queryables, :queryable_id)
4
+ rename_column :cm_blazer_queryables, :taxon_id, :queryable_id
5
+ end
6
+
7
+ unless column_exists?(:cm_blazer_queryables, :queryable_type)
8
+ add_column :cm_blazer_queryables, :queryable_type, :string, default: 'Spree::Taxon'
9
+ end
10
+
11
+ if foreign_key_exists?(:cm_blazer_queryables, column: :queryable_id)
12
+ remove_foreign_key :cm_blazer_queryables, column: :queryable_id
13
+ end
14
+
15
+ unless index_exists?(:cm_blazer_queryables, [:queryable_type, :queryable_id], name: 'index_cm_blazer_queryables_on_queryable_type_and_id')
16
+ add_index :cm_blazer_queryables, [:queryable_type, :queryable_id], name: 'index_cm_blazer_queryables_on_queryable_type_and_id'
17
+ end
18
+ end
19
+ end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '1.18.1'.freeze
2
+ VERSION = '1.19.0'.freeze
3
3
 
4
4
  module_function
5
5
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_cm_commissioner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.1
4
+ version: 1.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-10 00:00:00.000000000 Z
11
+ date: 2025-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -787,6 +787,7 @@ files:
787
787
  - app/controllers/spree/admin/telegram_bots_controller.rb
788
788
  - app/controllers/spree/admin/tenant_vendors_controller.rb
789
789
  - app/controllers/spree/admin/tenants_controller.rb
790
+ - app/controllers/spree/admin/trip_blazer_queries_controller.rb
790
791
  - app/controllers/spree/admin/user_events_controller.rb
791
792
  - app/controllers/spree/admin/user_identity_providers_controller.rb
792
793
  - app/controllers/spree/admin/users_controller_decorator.rb
@@ -819,6 +820,7 @@ files:
819
820
  - app/controllers/spree/api/v2/operator/taxons_controller.rb
820
821
  - app/controllers/spree/api/v2/organizer/base_controller.rb
821
822
  - app/controllers/spree/api/v2/organizer/images_controller.rb
823
+ - app/controllers/spree/api/v2/organizer/invite_crews_controller.rb
822
824
  - app/controllers/spree/api/v2/organizer/invite_guests_controller.rb
823
825
  - app/controllers/spree/api/v2/organizer/invites_controller.rb
824
826
  - app/controllers/spree/api/v2/organizer/s3_signed_urls_controller.rb
@@ -1038,7 +1040,9 @@ files:
1038
1040
  - app/interactors/spree_cm_commissioner/account_linkage.rb
1039
1041
  - app/interactors/spree_cm_commissioner/account_recover.rb
1040
1042
  - app/interactors/spree_cm_commissioner/account_updater.rb
1043
+ - app/interactors/spree_cm_commissioner/apple_app_site_association_fetcher.rb
1041
1044
  - app/interactors/spree_cm_commissioner/apply_service_availability.rb
1045
+ - app/interactors/spree_cm_commissioner/asset_links_fetcher.rb
1042
1046
  - app/interactors/spree_cm_commissioner/base_interactor.rb
1043
1047
  - app/interactors/spree_cm_commissioner/bib_number_swapper.rb
1044
1048
  - app/interactors/spree_cm_commissioner/chatrace_order_creator.rb
@@ -1048,6 +1052,7 @@ files:
1048
1052
  - app/interactors/spree_cm_commissioner/conversion_pre_calculator.rb
1049
1053
  - app/interactors/spree_cm_commissioner/create_event.rb
1050
1054
  - app/interactors/spree_cm_commissioner/create_ticket.rb
1055
+ - app/interactors/spree_cm_commissioner/crew_invite_link_handler.rb
1051
1056
  - app/interactors/spree_cm_commissioner/crew_inviter.rb
1052
1057
  - app/interactors/spree_cm_commissioner/customer_content_notification_creator.rb
1053
1058
  - app/interactors/spree_cm_commissioner/customer_notification_cron_executor.rb
@@ -1107,6 +1112,7 @@ files:
1107
1112
  - app/interactors/spree_cm_commissioner/subscriptions_order_creator.rb
1108
1113
  - app/interactors/spree_cm_commissioner/subscriptions_order_cron_executor.rb
1109
1114
  - app/interactors/spree_cm_commissioner/subscriptions_prepaid_order_creator.rb
1115
+ - app/interactors/spree_cm_commissioner/telegram_chats_auto_finder.rb
1110
1116
  - app/interactors/spree_cm_commissioner/telegram_chats_finder.rb
1111
1117
  - app/interactors/spree_cm_commissioner/telegram_debug_pin_code_sender.rb
1112
1118
  - app/interactors/spree_cm_commissioner/telegram_notification_sender.rb
@@ -1116,7 +1122,6 @@ files:
1116
1122
  - app/interactors/spree_cm_commissioner/telegram_web_app_vendor_user_checker.rb
1117
1123
  - app/interactors/spree_cm_commissioner/transactional_email_sender.rb
1118
1124
  - app/interactors/spree_cm_commissioner/unique_device_token_cron_executor.rb
1119
- - app/interactors/spree_cm_commissioner/universal_link_fetcher.rb
1120
1125
  - app/interactors/spree_cm_commissioner/update_payment_gateway_status.rb
1121
1126
  - app/interactors/spree_cm_commissioner/user_contact_updater.rb
1122
1127
  - app/interactors/spree_cm_commissioner/user_device_token_deregister.rb
@@ -1223,6 +1228,7 @@ files:
1223
1228
  - app/models/spree_cm_commissioner/asset.rb
1224
1229
  - app/models/spree_cm_commissioner/back_image.rb
1225
1230
  - app/models/spree_cm_commissioner/base.rb
1231
+ - app/models/spree_cm_commissioner/blazer_queryable.rb
1226
1232
  - app/models/spree_cm_commissioner/branch.rb
1227
1233
  - app/models/spree_cm_commissioner/check_in.rb
1228
1234
  - app/models/spree_cm_commissioner/check_in_ability.rb
@@ -1231,6 +1237,7 @@ files:
1231
1237
  - app/models/spree_cm_commissioner/cms_page_decorator.rb
1232
1238
  - app/models/spree_cm_commissioner/configuration.rb
1233
1239
  - app/models/spree_cm_commissioner/crew_invite.rb
1240
+ - app/models/spree_cm_commissioner/crew_invite_link.rb
1234
1241
  - app/models/spree_cm_commissioner/customer.rb
1235
1242
  - app/models/spree_cm_commissioner/customer_notification.rb
1236
1243
  - app/models/spree_cm_commissioner/customer_promotion_rule.rb
@@ -1302,6 +1309,7 @@ files:
1302
1309
  - app/models/spree_cm_commissioner/pin_code_mobile_confirm.rb
1303
1310
  - app/models/spree_cm_commissioner/pin_code_otp.rb
1304
1311
  - app/models/spree_cm_commissioner/pin_code_registration.rb
1312
+ - app/models/spree_cm_commissioner/pin_code_telegram.rb
1305
1313
  - app/models/spree_cm_commissioner/pin_code_update_user_login.rb
1306
1314
  - app/models/spree_cm_commissioner/place.rb
1307
1315
  - app/models/spree_cm_commissioner/product_completion_step.rb
@@ -1321,6 +1329,7 @@ files:
1321
1329
  - app/models/spree_cm_commissioner/promotion/rules/guest_occupations.rb
1322
1330
  - app/models/spree_cm_commissioner/promotion/rules/vendors.rb
1323
1331
  - app/models/spree_cm_commissioner/promotion/rules/weekend.rb
1332
+ - app/models/spree_cm_commissioner/promotion_category_decorator.rb
1324
1333
  - app/models/spree_cm_commissioner/promotion_decorator.rb
1325
1334
  - app/models/spree_cm_commissioner/property_decorator.rb
1326
1335
  - app/models/spree_cm_commissioner/prototype_decorator.rb
@@ -1342,7 +1351,6 @@ files:
1342
1351
  - app/models/spree_cm_commissioner/store_decorator.rb
1343
1352
  - app/models/spree_cm_commissioner/subscription.rb
1344
1353
  - app/models/spree_cm_commissioner/taxon_app_banner.rb
1345
- - app/models/spree_cm_commissioner/taxon_blazer_query.rb
1346
1354
  - app/models/spree_cm_commissioner/taxon_brand_logo.rb
1347
1355
  - app/models/spree_cm_commissioner/taxon_category_icon.rb
1348
1356
  - app/models/spree_cm_commissioner/taxon_decorator.rb
@@ -1355,6 +1363,7 @@ files:
1355
1363
  - app/models/spree_cm_commissioner/taxon_web_banner.rb
1356
1364
  - app/models/spree_cm_commissioner/taxonomy_decorator.rb
1357
1365
  - app/models/spree_cm_commissioner/telegram_bot.rb
1366
+ - app/models/spree_cm_commissioner/telegram_chat.rb
1358
1367
  - app/models/spree_cm_commissioner/tenant.rb
1359
1368
  - app/models/spree_cm_commissioner/transactional_email.rb
1360
1369
  - app/models/spree_cm_commissioner/trip.rb
@@ -1567,6 +1576,7 @@ files:
1567
1576
  - app/serializers/spree/v2/organizer/asset_serializer.rb
1568
1577
  - app/serializers/spree/v2/organizer/base_serializer.rb
1569
1578
  - app/serializers/spree/v2/organizer/image_serializer.rb
1579
+ - app/serializers/spree/v2/organizer/invite_crews_serializer.rb
1570
1580
  - app/serializers/spree/v2/organizer/invite_guest_serializer.rb
1571
1581
  - app/serializers/spree/v2/organizer/invite_serializer.rb
1572
1582
  - app/serializers/spree/v2/organizer/s3_signed_url_serializer.rb
@@ -2518,9 +2528,15 @@ files:
2518
2528
  - db/migrate/20250611023548_add_country_code_to_guests.rb
2519
2529
  - db/migrate/20250612035937_add_intel_phone_number_to_guests.rb
2520
2530
  - db/migrate/20250616084219_add_description_to_cm_vendor_place.rb
2531
+ - db/migrate/20250630103536_create_cm_telegram_chats.rb
2521
2532
  - db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb
2522
2533
  - db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb
2523
2534
  - db/migrate/20250702091935_add_status_to_dynamic_field_option.rb
2535
+ - db/migrate/20250707032008_add_vendor_id_to_spree_category.rb
2536
+ - db/migrate/20250711092937_add_position_to_cm_dynamic_fields.rb
2537
+ - db/migrate/20250711093045_add_position_to_cm_dynamic_field_options.rb
2538
+ - db/migrate/20250714121508_rename_cm_taxon_blazer_query_to_blazer_queryables.rb
2539
+ - db/migrate/20250714124323_make_cm_blazer_queryables_polymorphic.rb
2524
2540
  - docker-compose.yml
2525
2541
  - docs/option_types/attr_types.md
2526
2542
  - docs/private_key.pem
@@ -1,54 +0,0 @@
1
- module SpreeCmCommissioner
2
- class UniversalLinkFetcher < BaseInteractor
3
- delegate :universal_link, :store, :tenant, :refresh, to: :context
4
-
5
- def call
6
- return not_found unless resource
7
-
8
- data = load_cached_preference(resource)
9
- return not_found if data.blank?
10
-
11
- { success: true, data: data }
12
- end
13
-
14
- private
15
-
16
- def resource
17
- @resource ||= store.presence || tenant
18
- end
19
-
20
- def load_cached_preference(resource)
21
- preference_key = preference_key_for(universal_link)
22
- return nil unless preference_key && resource.respond_to?(preference_key)
23
-
24
- updated_at = resource.try(:updated_at)&.to_i || 'no_updated_at'
25
- cache_key = build_cache_key(universal_link, resource, updated_at)
26
-
27
- CmAppLogger.log(label: 'LOOKING_UP_CACHE', data: { cache_key: cache_key })
28
-
29
- Rails.cache.delete(cache_key) if refresh
30
-
31
- Rails.cache.fetch(cache_key, expires_in: 1.day, force: refresh) do
32
- CmAppLogger.log(label: 'CACHE_MISS', data: { cache_key: cache_key })
33
- resource.public_send(preference_key).presence
34
- end
35
- end
36
-
37
- def build_cache_key(universal_link, resource, updated_at)
38
- "well_known:#{universal_link}:#{resource.class.name}:#{resource.id}:#{updated_at}"
39
- end
40
-
41
- def preference_key_for(universal_link)
42
- case universal_link
43
- when 'assetlinks.json'
44
- :preferred_assetlinks
45
- when 'apple-app-site-association'
46
- :preferred_apple_app_site_association
47
- end
48
- end
49
-
50
- def not_found
51
- { success: false, error: 'Not found' }
52
- end
53
- end
54
- end
@@ -1,8 +0,0 @@
1
- module SpreeCmCommissioner
2
- class TaxonBlazerQuery < SpreeCmCommissioner::Base
3
- belongs_to :taxon, class_name: 'Spree::Taxon'
4
- belongs_to :blazer_query, class_name: 'Blazer::Query'
5
-
6
- validates :taxon_id, uniqueness: { scope: :blazer_query_id, message: I18n.t('event_blazer_queries.fail') }
7
- end
8
- end