spree_cm_commissioner 1.18.0.pre.pre2 → 1.18.0.pre.pre3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4397cedd70ecbd2c2b1055e1781ab2cec5e102fc49a026235bc4b343e339e175
4
- data.tar.gz: 030cd051f193e3e8f4b235a56bf42a7bfedcb003ecae825224352e79aa72655c
3
+ metadata.gz: 6164958fb3e35c7708b3715aa8c5c88db95fcb47b0ba8f943e4ee0f382243b29
4
+ data.tar.gz: e0caefc60f2d2da898ff43beb800db4c693425eca118aca821db9a2f3b07b56d
5
5
  SHA512:
6
- metadata.gz: 52d53b06702b30dcf5883997f8414d19f014cde234e3a5800e1590023354778c5b81f55ed3354ce30f922ef6607975dede7d17618432888c51d31d973f464971
7
- data.tar.gz: '036259fac1ae8b68277c951da23474ad9332ffee963670149f74789bd6750707f3561b219e802bef0631befc86de3fcfbc9da66ee56b5412c5846277284dee26'
6
+ metadata.gz: a40709614ead0f6dcbb87f1da2a034e795fa261421853b5971895cd7179c0371b4efe9356c5c088079469cf46a44a2d6d80eb94b4d487b939c287272c679aed5
7
+ data.tar.gz: 92412f627c52530fae22c31a57b19c6c53239681a839876b6941c19f82a741d3c883b19099b4bd09508e7caeb42b79f1a78d65ed91b836b540e1a99318b76df5
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (1.18.0.pre.pre2)
37
+ spree_cm_commissioner (1.18.0.pre.pre3)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -446,7 +446,6 @@ GEM
446
446
  google-cloud-recaptcha_enterprise-v1beta1 (0.10.0)
447
447
  gapic-common (>= 0.20.0, < 2.a)
448
448
  google-cloud-errors (~> 1.0)
449
- google-protobuf (3.25.8)
450
449
  google-protobuf (3.25.8-x86_64-darwin)
451
450
  google-protobuf (3.25.8-x86_64-linux)
452
451
  googleapis-common-protos (1.4.0)
@@ -461,9 +460,6 @@ GEM
461
460
  multi_json (~> 1.11)
462
461
  os (>= 0.9, < 2.0)
463
462
  signet (>= 0.16, < 2.a)
464
- grpc (1.72.0)
465
- google-protobuf (>= 3.25, < 5.0)
466
- googleapis-common-protos-types (~> 1.0)
467
463
  grpc (1.72.0-x86_64-darwin)
468
464
  google-protobuf (>= 3.25, < 5.0)
469
465
  googleapis-common-protos-types (~> 1.0)
@@ -551,7 +547,6 @@ GEM
551
547
  method_source (1.0.0)
552
548
  mini_magick (4.12.0)
553
549
  mini_mime (1.1.5)
554
- mini_portile2 (2.8.4)
555
550
  minitest (5.20.0)
556
551
  monetize (1.12.0)
557
552
  money (~> 6.12)
@@ -569,8 +564,9 @@ GEM
569
564
  net-smtp (0.4.0)
570
565
  net-protocol
571
566
  nio4r (2.5.9)
572
- nokogiri (1.15.4)
573
- mini_portile2 (~> 2.8.2)
567
+ nokogiri (1.18.8-x86_64-darwin)
568
+ racc (~> 1.4)
569
+ nokogiri (1.18.8-x86_64-linux-gnu)
574
570
  racc (~> 1.4)
575
571
  noticed (1.6.3)
576
572
  http (>= 4.0.0)
@@ -926,11 +922,11 @@ GEM
926
922
  zeitwerk (2.6.12)
927
923
 
928
924
  PLATFORMS
929
- ruby
930
925
  x86_64-darwin-19
931
926
  x86_64-darwin-20
932
927
  x86_64-darwin-21
933
928
  x86_64-darwin-22
929
+ x86_64-darwin-23
934
930
  x86_64-linux
935
931
 
936
932
  DEPENDENCIES
@@ -38,14 +38,25 @@ module Spree
38
38
  def update
39
39
  spree_authorize! :update, spree_current_order, order_token
40
40
 
41
- update_dynamic_fields if guest_params[:guest_dynamic_fields_attributes]
42
-
43
- resource.assign_attributes(guest_params.except(:guest_dynamic_fields_attributes))
44
-
45
- if resource.save
46
- render_serialized_payload { serialize_resource(resource) }
47
- else
48
- render_error_payload(resource, 400)
41
+ begin
42
+ if guest_params[:guest_dynamic_fields_attributes]
43
+ resource.guest_dynamic_fields.destroy_all
44
+
45
+ guest_params[:guest_dynamic_fields_attributes].each do |attr|
46
+ field = build_dynamic_field(attr)
47
+ field.save!
48
+ end
49
+ end
50
+
51
+ resource.assign_attributes(guest_params.except(:guest_dynamic_fields_attributes))
52
+
53
+ if resource.save
54
+ render_serialized_payload { serialize_resource(resource) }
55
+ else
56
+ render_error_payload(resource.errors, 400)
57
+ end
58
+ rescue ActiveRecord::RecordInvalid => e
59
+ render_error_payload(e.record.errors, 400)
49
60
  end
50
61
  end
51
62
 
@@ -84,21 +95,12 @@ module Spree
84
95
  )
85
96
  end
86
97
 
87
- def update_dynamic_fields
88
- resource.guest_dynamic_fields.destroy_all
89
-
90
- dynamic_fields_attrs = guest_params[:guest_dynamic_fields_attributes]
91
-
92
- resource.guest_dynamic_fields = dynamic_fields_attrs.map do |attr|
93
- build_dynamic_field(attr)
94
- end
95
- end
96
-
97
98
  def build_dynamic_field(attr)
98
99
  field = resource.guest_dynamic_fields.build(attr.except(:id))
99
100
 
100
101
  if field.dynamic_field.requires_dynamic_field_options?
101
- field.dynamic_field_option = field.dynamic_field.dynamic_field_options.find_by(id: field.value)
102
+ option = field.dynamic_field.dynamic_field_options.find_by(id: field.value)
103
+ field.dynamic_field_option = option if option
102
104
  end
103
105
 
104
106
  field
@@ -48,7 +48,7 @@ module Spree
48
48
  quantity: add_item_params[:quantity],
49
49
  public_metadata: add_item_params[:public_metadata],
50
50
  private_metadata: add_item_params[:private_metadata],
51
- options: add_item_params[:options]&.to_h
51
+ options: add_item_params[:options]
52
52
  )
53
53
 
54
54
  render_order(result)
@@ -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,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
@@ -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
@@ -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
@@ -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',
@@ -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:
@@ -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
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '1.18.0-pre2'.freeze
2
+ VERSION = '1.18.0-pre3'.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.0.pre.pre2
4
+ version: 1.18.0.pre.pre3
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-09 00:00:00.000000000 Z
11
+ date: 2025-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -1038,7 +1038,9 @@ files:
1038
1038
  - app/interactors/spree_cm_commissioner/account_linkage.rb
1039
1039
  - app/interactors/spree_cm_commissioner/account_recover.rb
1040
1040
  - app/interactors/spree_cm_commissioner/account_updater.rb
1041
+ - app/interactors/spree_cm_commissioner/apple_app_site_association_fetcher.rb
1041
1042
  - app/interactors/spree_cm_commissioner/apply_service_availability.rb
1043
+ - app/interactors/spree_cm_commissioner/asset_links_fetcher.rb
1042
1044
  - app/interactors/spree_cm_commissioner/base_interactor.rb
1043
1045
  - app/interactors/spree_cm_commissioner/bib_number_swapper.rb
1044
1046
  - app/interactors/spree_cm_commissioner/chatrace_order_creator.rb
@@ -1107,6 +1109,7 @@ files:
1107
1109
  - app/interactors/spree_cm_commissioner/subscriptions_order_creator.rb
1108
1110
  - app/interactors/spree_cm_commissioner/subscriptions_order_cron_executor.rb
1109
1111
  - app/interactors/spree_cm_commissioner/subscriptions_prepaid_order_creator.rb
1112
+ - app/interactors/spree_cm_commissioner/telegram_chats_auto_finder.rb
1110
1113
  - app/interactors/spree_cm_commissioner/telegram_chats_finder.rb
1111
1114
  - app/interactors/spree_cm_commissioner/telegram_debug_pin_code_sender.rb
1112
1115
  - app/interactors/spree_cm_commissioner/telegram_notification_sender.rb
@@ -1116,7 +1119,6 @@ files:
1116
1119
  - app/interactors/spree_cm_commissioner/telegram_web_app_vendor_user_checker.rb
1117
1120
  - app/interactors/spree_cm_commissioner/transactional_email_sender.rb
1118
1121
  - app/interactors/spree_cm_commissioner/unique_device_token_cron_executor.rb
1119
- - app/interactors/spree_cm_commissioner/universal_link_fetcher.rb
1120
1122
  - app/interactors/spree_cm_commissioner/update_payment_gateway_status.rb
1121
1123
  - app/interactors/spree_cm_commissioner/user_contact_updater.rb
1122
1124
  - app/interactors/spree_cm_commissioner/user_device_token_deregister.rb
@@ -1302,6 +1304,7 @@ files:
1302
1304
  - app/models/spree_cm_commissioner/pin_code_mobile_confirm.rb
1303
1305
  - app/models/spree_cm_commissioner/pin_code_otp.rb
1304
1306
  - app/models/spree_cm_commissioner/pin_code_registration.rb
1307
+ - app/models/spree_cm_commissioner/pin_code_telegram.rb
1305
1308
  - app/models/spree_cm_commissioner/pin_code_update_user_login.rb
1306
1309
  - app/models/spree_cm_commissioner/place.rb
1307
1310
  - app/models/spree_cm_commissioner/product_completion_step.rb
@@ -1321,6 +1324,7 @@ files:
1321
1324
  - app/models/spree_cm_commissioner/promotion/rules/guest_occupations.rb
1322
1325
  - app/models/spree_cm_commissioner/promotion/rules/vendors.rb
1323
1326
  - app/models/spree_cm_commissioner/promotion/rules/weekend.rb
1327
+ - app/models/spree_cm_commissioner/promotion_category_decorator.rb
1324
1328
  - app/models/spree_cm_commissioner/promotion_decorator.rb
1325
1329
  - app/models/spree_cm_commissioner/property_decorator.rb
1326
1330
  - app/models/spree_cm_commissioner/prototype_decorator.rb
@@ -1355,6 +1359,7 @@ files:
1355
1359
  - app/models/spree_cm_commissioner/taxon_web_banner.rb
1356
1360
  - app/models/spree_cm_commissioner/taxonomy_decorator.rb
1357
1361
  - app/models/spree_cm_commissioner/telegram_bot.rb
1362
+ - app/models/spree_cm_commissioner/telegram_chat.rb
1358
1363
  - app/models/spree_cm_commissioner/tenant.rb
1359
1364
  - app/models/spree_cm_commissioner/transactional_email.rb
1360
1365
  - app/models/spree_cm_commissioner/trip.rb
@@ -2518,9 +2523,11 @@ files:
2518
2523
  - db/migrate/20250611023548_add_country_code_to_guests.rb
2519
2524
  - db/migrate/20250612035937_add_intel_phone_number_to_guests.rb
2520
2525
  - db/migrate/20250616084219_add_description_to_cm_vendor_place.rb
2526
+ - db/migrate/20250630103536_create_cm_telegram_chats.rb
2521
2527
  - db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb
2522
2528
  - db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb
2523
2529
  - db/migrate/20250702091935_add_status_to_dynamic_field_option.rb
2530
+ - db/migrate/20250707032008_add_vendor_id_to_spree_category.rb
2524
2531
  - docker-compose.yml
2525
2532
  - docs/option_types/attr_types.md
2526
2533
  - 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