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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +12 -1
  3. data/README.md +43 -1
  4. data/app/assets/images/category_icons/art_icon.png +0 -0
  5. data/app/assets/images/category_icons/concert_icon.png +0 -0
  6. data/app/assets/images/category_icons/fundraising_icon.png +0 -0
  7. data/app/assets/images/category_icons/marathon_icon.png +0 -0
  8. data/app/assets/images/category_icons/online_icon.png +0 -0
  9. data/app/assets/images/category_icons/workshop_icon.png +0 -0
  10. data/app/controllers/spree/admin/users_controller_decorator.rb +13 -0
  11. data/app/controllers/spree/api/chatrace/guests_controller.rb +2 -1
  12. data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +1 -0
  13. data/app/controllers/spree/api/v2/storefront/cart_payment_method_groups_controller.rb +12 -1
  14. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +3 -1
  15. data/app/controllers/spree/api/v2/tenant/cart_controller.rb +11 -0
  16. data/app/controllers/spree/api/v2/tenant/checkout_controller.rb +1 -0
  17. data/app/controllers/spree/api/v2/tenant/order_histories_controller.rb +65 -0
  18. data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +1 -1
  19. data/app/controllers/spree_cm_commissioner/well_known_controller.rb +46 -0
  20. data/app/factory/spree_cm_commissioner/invite_guest_claimed_telegram_message_factory.rb +8 -8
  21. data/app/helpers/spree/admin/base_helper_decorator.rb +2 -2
  22. data/app/helpers/spree_cm_commissioner/transit/order_query_helper.rb +17 -0
  23. data/app/interactors/spree_cm_commissioner/create_event.rb +31 -6
  24. data/app/interactors/spree_cm_commissioner/create_ticket.rb +36 -1
  25. data/app/interactors/spree_cm_commissioner/host_matcher.rb +28 -0
  26. data/app/interactors/spree_cm_commissioner/place_decoder.rb +16 -0
  27. data/app/interactors/spree_cm_commissioner/place_service.rb +32 -0
  28. data/app/interactors/spree_cm_commissioner/user_pin_code_authenticator.rb +9 -0
  29. data/app/models/concerns/spree_cm_commissioner/json_preference_validator.rb +23 -0
  30. data/app/models/concerns/spree_cm_commissioner/kyc_bitwise.rb +3 -1
  31. data/app/models/concerns/spree_cm_commissioner/store_preference.rb +2 -0
  32. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +10 -0
  33. data/app/models/spree_cm_commissioner/guest.rb +11 -2
  34. data/app/models/spree_cm_commissioner/invite_guest.rb +8 -0
  35. data/app/models/spree_cm_commissioner/option_type_decorator.rb +2 -0
  36. data/app/models/spree_cm_commissioner/option_value_decorator.rb +1 -0
  37. data/app/models/spree_cm_commissioner/option_value_vehicle.rb +8 -0
  38. data/app/models/spree_cm_commissioner/order_decorator.rb +5 -0
  39. data/app/models/spree_cm_commissioner/payment_method_decorator.rb +8 -1
  40. data/app/models/spree_cm_commissioner/place.rb +3 -0
  41. data/app/models/spree_cm_commissioner/store_decorator.rb +2 -1
  42. data/app/models/spree_cm_commissioner/taxon_decorator.rb +4 -0
  43. data/app/models/spree_cm_commissioner/taxon_place.rb +12 -0
  44. data/app/models/spree_cm_commissioner/tenant.rb +5 -0
  45. data/app/models/spree_cm_commissioner/user_decorator.rb +14 -3
  46. data/app/models/spree_cm_commissioner/vehicle.rb +3 -0
  47. data/app/models/spree_cm_commissioner/vehicle_option_type.rb +6 -0
  48. data/app/models/spree_cm_commissioner/vendor_decorator.rb +7 -3
  49. data/app/models/spree_cm_commissioner/vendor_place.rb +11 -3
  50. data/app/overrides/spree/admin/stores/_form/store_preferences.html.erb.deface +85 -12
  51. data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +3 -4
  52. data/app/queries/spree_cm_commissioner/reservation_query.rb +12 -0
  53. data/app/serializers/spree/v2/organizer/invite_guest_serializer.rb +1 -1
  54. data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +1 -0
  55. data/app/serializers/spree/v2/tenant/cart_serializer.rb +8 -0
  56. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +1 -1
  57. data/app/services/spree_cm_commissioner/organizer/export_invite_guest_csv_service.rb +63 -0
  58. data/app/services/spree_cm_commissioner/payment_method_type_mapper.rb +11 -0
  59. data/app/views/spree/admin/tenants/_form.html.erb +59 -2
  60. data/config/initializers/spree_permitted_attributes.rb +3 -0
  61. data/config/routes.rb +7 -0
  62. data/db/migrate/20250127081646_add_preferences_to_cm_tenants.rb +7 -0
  63. data/db/migrate/20250527043231_create_spree_commissioner_taxon_places.rb +15 -0
  64. data/db/migrate/20250528090330_add_place_type_to_cm_vendor_place.rb +6 -0
  65. data/db/migrate/20250531074036_create_spree_cm_commissioner_option_value_vehicle.rb +10 -0
  66. data/db/migrate/20250531074258_create_spree_cm_commissioner_vehicle_option_types.rb +10 -0
  67. data/db/migrate/20250602094751_add_host_to_cm_tenants.rb +6 -0
  68. data/db/migrate/20250609015216_remove_claimed_at_and_expires_at_from_cm_invite_guest.rb +6 -0
  69. data/db/migrate/20250610080108_add_contact_to_cm_guests.rb +5 -0
  70. data/db/migrate/20250611023548_add_country_code_to_guests.rb +5 -0
  71. data/db/migrate/20250612035937_add_intel_phone_number_to_guests.rb +5 -0
  72. data/lib/spree_cm_commissioner/test_helper/factories/invite_guests_factory.rb +6 -0
  73. data/lib/spree_cm_commissioner/test_helper/factories/tenant_factory.rb +1 -0
  74. data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +17 -4
  75. data/lib/spree_cm_commissioner/version.rb +1 -1
  76. data/lib/spree_cm_commissioner.rb +1 -0
  77. data/spree_cm_commissioner.gemspec +2 -0
  78. metadata +62 -2
@@ -15,13 +15,15 @@ module SpreeCmCommissioner
15
15
  guest_expectation: 0b1000000000,
16
16
  guest_social_contact: 0b10000000000,
17
17
  guest_address: 0b100000000000,
18
- guest_phone_number: 0b1000000000000
18
+ guest_phone_number: 0b1000000000000,
19
+ guest_contact: 0b10000000000000
19
20
  }.freeze
20
21
 
21
22
  ORDERED_BIT_FIELDS = %i[
22
23
  guest_name
23
24
  guest_gender
24
25
  guest_phone_number
26
+ guest_contact
25
27
  guest_dob
26
28
  guest_occupation
27
29
  guest_nationality
@@ -6,6 +6,8 @@ module SpreeCmCommissioner
6
6
  preference :sms_sender_id, :string
7
7
  preference :telegram_order_alert_chat_id, :string
8
8
  preference :telegram_order_request_alert_chat_id, :string
9
+ preference :assetlinks, :string, default: ''
10
+ preference :apple_app_site_association, :string, default: ''
9
11
  end
10
12
  end
11
13
  end
@@ -0,0 +1,10 @@
1
+ module SpreeCmCommissioner
2
+ module TenantPreference
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ preference :assetlinks, :string, default: ''
7
+ preference :apple_app_site_association, :string, default: ''
8
+ end
9
+ end
10
+ end
@@ -1,6 +1,8 @@
1
+ # rubocop:disable Metrics/ClassLength
1
2
  module SpreeCmCommissioner
2
3
  class Guest < SpreeCmCommissioner::Base
3
4
  include SpreeCmCommissioner::KycBitwise
5
+ include SpreeCmCommissioner::PhoneNumberSanitizer
4
6
 
5
7
  delegate :kyc, to: :line_item, allow_nil: true
6
8
  delegate :allowed_upload_later?, to: :line_item, allow_nil: true
@@ -48,13 +50,13 @@ module SpreeCmCommissioner
48
50
  validates :bib_index, uniqueness: true, allow_nil: true
49
51
 
50
52
  self.whitelisted_ransackable_associations = %w[id_card event]
51
- self.whitelisted_ransackable_attributes = %w[first_name last_name phone_number gender occupation_id card_type created_at check_in_status]
53
+ self.whitelisted_ransackable_attributes = %w[first_name last_name phone_number gender contact occupation_id card_type created_at check_in_status]
52
54
 
53
55
  def self.csv_importable_columns
54
56
  %i[
55
57
  first_name last_name phone_number age dob gender address other_occupation
56
58
  entry_type nationality_id other_organization expectation emergency_contact bib_number
57
- preferred_telegram_user_id seat_number
59
+ preferred_telegram_user_id seat_number country_code contact
58
60
  ]
59
61
  end
60
62
 
@@ -77,6 +79,8 @@ module SpreeCmCommissioner
77
79
  return upload_later? || (id_card.present? && id_card.allowed_checkout?) if field == :guest_id_card
78
80
  return address.present? if field == :guest_address
79
81
  return phone_number.present? if field == :guest_phone_number
82
+ return country_code.present? if field == :guest_country_code
83
+ return contact.present? if field == :guest_contact
80
84
 
81
85
  false
82
86
  end
@@ -110,6 +114,10 @@ module SpreeCmCommissioner
110
114
  address.blank?
111
115
  when :guest_phone_number
112
116
  phone_number.blank?
117
+ when :guest_country_code
118
+ country_code.blank?
119
+ when :guest_contact
120
+ contact.blank?
113
121
  else
114
122
  false
115
123
  end
@@ -219,3 +227,4 @@ module SpreeCmCommissioner
219
227
  end
220
228
  end
221
229
  end
230
+ # rubocop:enable Metrics/ClassLength
@@ -19,5 +19,13 @@ module SpreeCmCommissioner
19
19
  line_item = order.line_items.first
20
20
  line_item.guests.count >= order.line_items.first.number_of_guests
21
21
  end
22
+
23
+ def invitation_link
24
+ "#{Spree::Store.default.formatted_url}/invite_guests/#{token}?utm_source=email"
25
+ end
26
+
27
+ def ticket_url(guest_token)
28
+ "#{Spree::Store.default.formatted_url}/invite_guests/#{token}/guest_invitations/#{guest_token}"
29
+ end
22
30
  end
23
31
  end
@@ -14,6 +14,8 @@ module SpreeCmCommissioner
14
14
 
15
15
  base.has_many :variants, through: :products
16
16
 
17
+ base.has_many :vehicle_option_types, class_name: 'SpreeCmCommissioner::VehicleOptionType', foreign_key: :option_type_id, dependent: :destroy
18
+
17
19
  base.scope :promoted, -> { where(promoted: true) }
18
20
  base.whitelisted_ransackable_attributes = %w[kind]
19
21
 
@@ -2,6 +2,7 @@ module SpreeCmCommissioner
2
2
  module OptionValueDecorator
3
3
  def self.prepended(base)
4
4
  base.include SpreeCmCommissioner::OptionValueAttrType
5
+ base.has_many :option_value_vehicles, class_name: 'SpreeCmCommissioner::OptionValueVehicle', foreign_key: :option_value_id, dependent: :destroy
5
6
  end
6
7
 
7
8
  def display_icon
@@ -0,0 +1,8 @@
1
+ require_dependency 'spree_cm_commissioner'
2
+
3
+ module SpreeCmCommissioner
4
+ class OptionValueVehicle < ApplicationRecord
5
+ belongs_to :vehicle, class_name: 'SpreeCmCommissioner::Vehicle'
6
+ belongs_to :option_value, class_name: 'Spree::OptionValue'
7
+ end
8
+ end
@@ -192,6 +192,11 @@ module SpreeCmCommissioner
192
192
  Spree::Money.new(outstanding_balance, currency: currency).to_s
193
193
  end
194
194
 
195
+ # override spree_vpago method
196
+ def payment_host
197
+ tenant&.host.presence || ENV.fetch('DEFAULT_URL_HOST')
198
+ end
199
+
195
200
  private
196
201
 
197
202
  # override :spree_api
@@ -1,11 +1,18 @@
1
1
  module SpreeCmCommissioner
2
2
  module PaymentMethodDecorator
3
- DISPLAY = %i[both front_end back_end frontend_for_early_adopter].freeze
3
+ DISPLAY = %i[both front_end back_end frontend_for_early_adopter mini_app].freeze
4
4
 
5
5
  def self.prepended(base)
6
6
  base.const_set(:DISPLAY, DISPLAY)
7
7
 
8
8
  base.scope :available_on_frontend_for_early_adopter, -> { active.where(display_on: %i[both front_end frontend_for_early_adopter]) }
9
+
10
+ # override
11
+ base.scope :available_on_front_end, -> { active.where(display_on: %i[front_end both mini_app]) }
12
+ end
13
+
14
+ def mini_app?
15
+ display_on == 'mini_app'
9
16
  end
10
17
  end
11
18
  end
@@ -19,6 +19,9 @@ module SpreeCmCommissioner
19
19
  has_many :children, -> { order(:lft) }, class_name: 'SpreeCmCommissioner::Place', foreign_key: :parent_id, dependent: :destroy
20
20
  has_many :vendor_stops, class_name: 'SpreeCmCommissioner::VendorStop', dependent: :destroy, foreign_key: :stop_id
21
21
 
22
+ has_many :taxon_places, class_name: 'SpreeCmCommissioner::TaxonPlace', dependent: :destroy
23
+ has_many :taxons, through: :taxon_places
24
+
22
25
  def self.ransackable_attributes(auth_object = nil)
23
26
  super & %w[name code]
24
27
  end
@@ -2,10 +2,11 @@ module SpreeCmCommissioner
2
2
  module StoreDecorator
3
3
  def self.prepended(base)
4
4
  base.include SpreeCmCommissioner::StorePreference
5
+ base.include SpreeCmCommissioner::JsonPreferenceValidator
5
6
 
6
7
  base.has_one :default_notification_image, class_name: 'SpreeCmCommissioner::FeatureImage', dependent: :destroy, as: :viewable
7
8
  base.accepts_nested_attributes_for :default_notification_image, reject_if: :all_blank
8
- base.multi_tenant :tenant, class_name: 'SpreeCmCommissioner::Tenant'
9
+ base.has_one :tenant, class_name: 'SpreeCmCommissioner::Tenant'
9
10
  end
10
11
  end
11
12
  end
@@ -59,6 +59,7 @@ module SpreeCmCommissioner
59
59
 
60
60
  base.has_many :line_items, through: :products
61
61
  base.has_many :event_line_items, class_name: 'Spree::LineItem', foreign_key: :event_id
62
+ base.has_many :event_products, class_name: 'Spree::Product', foreign_key: :event_id
62
63
 
63
64
  base.has_many :event_blazer_queries, class_name: 'SpreeCmCommissioner::TaxonBlazerQuery'
64
65
  base.has_many :blazer_queries, through: :event_blazer_queries, class_name: 'Blazer::Query'
@@ -68,6 +69,9 @@ module SpreeCmCommissioner
68
69
 
69
70
  base.after_commit :send_transaction_email_to_organizers, on: :create
70
71
 
72
+ base.has_many :taxon_places, class_name: 'SpreeCmCommissioner::TaxonPlace', dependent: :destroy
73
+ base.has_many :places, through: :taxon_places
74
+
71
75
  def base.active_homepage_events
72
76
  joins(:homepage_section_relatables)
73
77
  .joins("INNER JOIN spree_taxons taxon ON taxon.id = cm_homepage_section_relatables.relatable_id
@@ -0,0 +1,12 @@
1
+ module SpreeCmCommissioner
2
+ class TaxonPlace < Base
3
+ self.inheritance_column = '_type_disabled'
4
+
5
+ belongs_to :taxon, class_name: 'Spree::Taxon', optional: false
6
+ belongs_to :place, class_name: 'SpreeCmCommissioner::Place', optional: false
7
+
8
+ validates :place_id, uniqueness: { scope: :taxon_id }
9
+
10
+ enum type: { venue: 0, nearby_place: 1 }
11
+ end
12
+ end
@@ -1,5 +1,8 @@
1
1
  module SpreeCmCommissioner
2
2
  class Tenant < SpreeCmCommissioner::Base
3
+ include SpreeCmCommissioner::TenantPreference
4
+ include SpreeCmCommissioner::JsonPreferenceValidator
5
+
3
6
  extend FriendlyId
4
7
  friendly_id :name, use: :history
5
8
 
@@ -9,6 +12,8 @@ module SpreeCmCommissioner
9
12
  through: :vendors,
10
13
  source: :payment_methods
11
14
 
15
+ validates :host, uniqueness: true, presence: true
16
+
12
17
  enum state: { enabled: 0, disabled: 1 }
13
18
 
14
19
  before_validation :generate_slug, if: -> { slug.blank? && name.present? }
@@ -1,7 +1,8 @@
1
- # rubocop:disable Metrics/MethodLength
1
+ require 'strong_password'
2
+
2
3
  module SpreeCmCommissioner
3
4
  module UserDecorator
4
- def self.prepended(base) # rubocop:disable Metrics/AbcSize
5
+ def self.prepended(base) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
5
6
  base.include SpreeCmCommissioner::UserNotification
6
7
  base.include SpreeCmCommissioner::UserIdentity
7
8
  base.include SpreeCmCommissioner::UserPreference
@@ -36,6 +37,8 @@ module SpreeCmCommissioner
36
37
  base.whitelisted_ransackable_attributes = %w[email first_name last_name gender phone_number]
37
38
 
38
39
  base.before_save :update_otp_enabled
40
+ base.attr_accessor :assigned_roles
41
+ base.validates_password_strength :password, if: -> { requires_strong_password? && password.present? }
39
42
 
40
43
  define_user_places(base)
41
44
 
@@ -88,6 +91,15 @@ module SpreeCmCommissioner
88
91
  [first_name, last_name].compact_blank.join(' ')
89
92
  end
90
93
 
94
+ def privileged_role?
95
+ assigned = assigned_roles || []
96
+ assigned.map(&:to_s).include?('admin')
97
+ end
98
+
99
+ def requires_strong_password?
100
+ admin? || privileged_role?
101
+ end
102
+
91
103
  def display_name
92
104
  return full_name if full_name.present?
93
105
  return first_name if first_name.present?
@@ -144,4 +156,3 @@ module SpreeCmCommissioner
144
156
  end
145
157
 
146
158
  Spree::User.prepend(SpreeCmCommissioner::UserDecorator) unless Spree::User.included_modules.include?(SpreeCmCommissioner::UserDecorator)
147
- # rubocop:enable Metrics/MethodLength
@@ -13,6 +13,9 @@ module SpreeCmCommissioner
13
13
  has_many :vehicle_photo, class_name: 'SpreeCmCommissioner::VehiclePhoto', as: :viewable, dependent: :destroy
14
14
  has_many :vehicle_seats, class_name: 'SpreeCmCommissioner::VehicleSeat', through: :vehicle_type
15
15
 
16
+ has_many :vehicle_option_types, class_name: 'SpreeCmCommissioner::VehicleOptionType', dependent: :destroy
17
+ has_many :option_value_vehicles, class_name: 'SpreeCmCommissioner::OptionValueVehicle', dependent: :destroy
18
+
16
19
  validates :code, uniqueness: { scope: :vendor_id }, presence: true
17
20
  validates :license_plate, uniqueness: {}, allow_blank: true
18
21
 
@@ -0,0 +1,6 @@
1
+ module SpreeCmCommissioner
2
+ class VehicleOptionType < ApplicationRecord
3
+ belongs_to :vehicle, class_name: 'SpreeCmCommissioner::Vehicle'
4
+ belongs_to :option_type, class_name: 'Spree::OptionType'
5
+ end
6
+ end
@@ -36,8 +36,12 @@ module SpreeCmCommissioner
36
36
  base.has_many :vendor_kind_option_values,
37
37
  through: :option_value_vendors, source: :option_value
38
38
 
39
- base.has_many :branches, class_name: 'SpreeCmCommissioner::Branch'
40
- base.has_many :stops, class_name: 'SpreeCmCommissioner::Place'
39
+ base.has_many :branches, lambda {
40
+ where(cm_vendor_places: { place_type: 0 })
41
+ }, through: :vendor_places, class_name: 'SpreeCmCommissioner::VendorPlace'
42
+ base.has_many :stops, -> { where(cm_vendor_places: { place_type: 1 }) }, through: :vendor_places, class_name: 'SpreeCmCommissioner::VendorPlace'
43
+ base.has_many :locations, -> { where(cm_vendor_places: { place_type: 2 }) },
44
+ through: :vendor_places, class_name: 'SpreeCmCommissioner::VendorPlace'
41
45
 
42
46
  base.has_many :places,
43
47
  through: :nearby_places, source: :place, class_name: 'SpreeCmCommissioner::Place'
@@ -118,7 +122,7 @@ module SpreeCmCommissioner
118
122
  end
119
123
 
120
124
  def selected_place_references
121
- places.pluck(:reference)
125
+ places.where.not(reference: [nil, '']).pluck(:reference)
122
126
  end
123
127
 
124
128
  def search_data
@@ -2,15 +2,23 @@ require_dependency 'spree_cm_commissioner'
2
2
 
3
3
  module SpreeCmCommissioner
4
4
  class VendorPlace < ApplicationRecord
5
+ enum place_type: { branch: 0, stop: 1, locations: 2 }
5
6
  acts_as_list scope: :vendor
6
7
 
7
- belongs_to :vendor, class_name: 'Spree::Vendor'
8
- belongs_to :place, class_name: 'SpreeCmCommissioner::Place'
8
+ belongs_to :vendor, class_name: 'Spree::Vendor', optional: false
9
+ belongs_to :place, class_name: 'SpreeCmCommissioner::Place', optional: false
10
+
11
+ validates :place_type, presence: true
12
+ validates :position, presence: true, numericality: { only_integer: true, greater_than: 0 }
9
13
 
10
14
  accepts_nested_attributes_for :place, allow_destroy: true
11
15
 
16
+ scope :branches, -> { where(place_type: :branch) }
17
+ scope :stops, -> { where(place_type: :stop) }
18
+ scope :locations, -> { where(place_type: :locations) }
19
+
12
20
  def selected
13
- vendor.selected_place_references.include?(place.reference)
21
+ vendor.selected_place_references.include?(place&.reference)
14
22
  end
15
23
  end
16
24
  end
@@ -1,18 +1,91 @@
1
1
  <!-- insert_bottom "[data-hook='admin_store_form_fields']" -->
2
2
 
3
3
  <% if @store.persisted? %>
4
- <div class="card mb-4">
5
- <div class="card-header">
6
- <h5 class="card-title mb-0 h6">
7
- <%= Spree.t(:preference).pluralize %>
8
- </h5>
9
- </div>
10
- <div class="card-body">
11
- <div id="preference-settings" data-hook class="form-group">
12
- <% unless preference_fields(@store, f).empty? %>
13
- <%= preference_fields(@store, f) %>
14
- <% end %>
4
+ <div class="card mb-4">
5
+ <div class="card-header">
6
+ <h5 class="card-title mb-0 h6">
7
+ <%= Spree.t(:preference).pluralize %>
8
+ </h5>
9
+ </div>
10
+ <div class="card-body">
11
+ <div id="preference-settings" data-hook class="form-group">
12
+ <div class="row">
13
+ <!-- SMS Sender ID -->
14
+ <div class="col-6">
15
+ <%= f.field_container :preferred_sms_sender_id do %>
16
+ <%= f.label :preferred_sms_sender_id, Spree.t(:sms_sender_id) %>
17
+ <%= f.text_field :preferred_sms_sender_id, class: 'form-control' %>
18
+ <%= f.error_message_on :preferred_sms_sender_id %>
19
+ <% end %>
20
+ </div>
21
+
22
+ <!-- Telegram Order Alert Chat ID -->
23
+ <div class="col-6">
24
+ <%= f.field_container :preferred_telegram_order_alert_chat_id do %>
25
+ <%= f.label :preferred_telegram_order_alert_chat_id, Spree.t(:telegram_order_alert_chat_id) %>
26
+ <%= f.text_field :preferred_telegram_order_alert_chat_id, class: 'form-control' %>
27
+ <%= f.error_message_on :preferred_telegram_order_alert_chat_id %>
28
+ <% end %>
29
+ </div>
30
+
31
+ <!-- Telegram Order Request Alert Chat ID -->
32
+ <div class="col-6">
33
+ <%= f.field_container :preferred_telegram_order_request_alert_chat_id do %>
34
+ <%= f.label :preferred_telegram_order_request_alert_chat_id, Spree.t(:telegram_order_request_alert_chat_id) %>
35
+ <%= f.text_field :preferred_telegram_order_request_alert_chat_id, class: 'form-control' %>
36
+ <%= f.error_message_on :preferred_telegram_order_request_alert_chat_id %>
37
+ <% end %>
38
+ </div>
39
+
40
+ <!-- Assetlinks -->
41
+ <div class="col-12">
42
+ <%= f.field_container :preferred_assetlinks do %>
43
+ <%= f.label :preferred_assetlinks, Spree.t(:assetlinks) %>
44
+ <%= f.text_area :preferred_assetlinks, class: 'form-control', rows: 5,
45
+ placeholder: 'example:
46
+ [
47
+ {
48
+ "relation": ["delegate_permission/common.handle_all_urls"],
49
+ "target": {
50
+ "namespace": "android_app",
51
+ "package_name": "com.yourapp.app",
52
+ "sha256_cert_fingerprints": [
53
+ "SHA256_CERTIFICATE_FINGERPRINT_HERE"
54
+ ]
55
+ }
56
+ }
57
+ ]' %>
58
+ <%= f.error_message_on :preferred_assetlinks %>
59
+ <% end %>
60
+ </div>
61
+
62
+ <!-- Apple App Site Association -->
63
+ <div class="col-12">
64
+ <%= f.field_container :preferred_apple_app_site_association do %>
65
+ <%= f.label :preferred_apple_app_site_association, Spree.t(:apple_app_site_association) %>
66
+ <%= f.text_area :preferred_apple_app_site_association, class: 'form-control', rows: 5,
67
+ placeholder: 'example:
68
+ {
69
+ "webcredentials": {
70
+ "apps": [
71
+ "TEAM_ID.com.yourapp.app"
72
+ ]
73
+ },
74
+ "applinks": {
75
+ "apps": [],
76
+ "details": [
77
+ {
78
+ "appID": "TEAM_ID.com.yourapp.app",
79
+ "paths": ["*"]
80
+ }
81
+ ]
82
+ }
83
+ }' %>
84
+ <%= f.error_message_on :preferred_apple_app_site_association %>
85
+ <% end %>
86
+ </div>
87
+ </div>
88
+ </div>
15
89
  </div>
16
90
  </div>
17
- </div>
18
91
  <% end %>
@@ -1,15 +1,14 @@
1
1
  <!-- insert_bottom "[data-hook='admin_variant_form_additional_fields']" -->
2
2
 
3
3
  <p>Guest Information Fields</p>
4
-
5
4
  <div class="form-check mb-3">
6
- <%= f.check_box :use_product_kyc, id: "toggleGuestInfo", class: 'form-check-input mr-2', checked: (@variant.kyc == nil) %>
5
+ <%= f.check_box :use_product_kyc, id: "toggleGuestInfo", class: 'form-check-input mr-2', checked: (@variant.kyc == @product.kyc) %>
7
6
  <label for="toggleGuestInfo" class="form-check-label">
8
- Use Product KYC
7
+ Use Product Guest Information
9
8
  </label>
10
9
  </div>
11
10
 
12
- <div id="guestInfoForm" <% if @variant.kyc == nil %>style="display: none;"<% end %>">
11
+ <div id="guestInfoForm" <% if @variant.kyc == @product.kyc %>style="display: none;"<% end %>">
13
12
  <small class="form-text text-muted mb-4">
14
13
  <%= raw I18n.t('kyc.variant_note') %>
15
14
  </small>
@@ -0,0 +1,12 @@
1
+ module SpreeCmCommissioner
2
+ class ReservationQuery
3
+ def initialize(vendor)
4
+ @vendor = vendor
5
+ end
6
+
7
+ def base_scope
8
+ vendor_id = @vendor&.id
9
+ SpreeCmCommissioner::Transit::OrderQueryHelper.transit_orders_for_vendor(vendor_id)
10
+ end
11
+ end
12
+ end
@@ -3,7 +3,7 @@ module Spree
3
3
  module Organizer
4
4
  class InviteGuestSerializer < BaseSerializer
5
5
  attributes :email, :quantity, :token, :invite_type, :claimed_status, :issued_to, :expiration_date,
6
- :claimed_at, :email_send_at, :created_at, :updated_at, :remark
6
+ :email_send_at, :created_at, :updated_at, :remark
7
7
  belongs_to :variant, serializer: SpreeCmCommissioner::V2::Storefront::EventVariantSerializer
8
8
  belongs_to :order, serializer: Spree::V2::Storefront::OrderSerializer
9
9
  belongs_to :event, serializer: Spree::V2::Storefront::TaxonSerializer
@@ -5,6 +5,7 @@ module Spree
5
5
  def self.prepended(base)
6
6
  base.has_many :vendors, serializer: ::Spree::V2::Storefront::VendorSerializer
7
7
  base.has_many :visible_products, serializer: ::Spree::V2::Storefront::ProductSerializer
8
+ base.has_many :places, serializer: ::Spree::V2::Storefront::PlaceSerializer
8
9
 
9
10
  base.has_one :category_icon, serializer: ::SpreeCmCommissioner::V2::Storefront::AssetSerializer
10
11
  base.has_one :app_banner, serializer: ::SpreeCmCommissioner::V2::Storefront::AssetSerializer
@@ -0,0 +1,8 @@
1
+ module Spree
2
+ module V2
3
+ module Tenant
4
+ class CartSerializer < Spree::V2::Storefront::CartSerializer
5
+ end
6
+ end
7
+ end
8
+ end
@@ -7,7 +7,7 @@ module SpreeCmCommissioner
7
7
  attributes :first_name, :last_name, :dob, :gender, :kyc_fields, :other_occupation, :created_at, :updated_at,
8
8
  :qr_data, :social_contact_platform, :social_contact, :available_social_contact_platforms,
9
9
  :age, :emergency_contact, :other_organization, :expectation, :upload_later, :address, :formatted_bib_number, :phone_number,
10
- :token
10
+ :token, :country_code, :contact
11
11
 
12
12
  # temporary, once app release after cm-app v1.9.1, we no longer need this.
13
13
  attribute :seat_number do |object|
@@ -0,0 +1,63 @@
1
+ module SpreeCmCommissioner
2
+ module Organizer
3
+ class ExportInviteGuestCsvService
4
+ attr_reader :invite_guest_id, :columns
5
+
6
+ def initialize(invite_guest_id, columns)
7
+ @invite_guest_id = invite_guest_id
8
+ @columns = (columns + %w[created_at ticket_url]).uniq
9
+ end
10
+
11
+ def call
12
+ CSV.generate(headers: true) do |csv|
13
+ csv << (['No.'] + headers)
14
+ guests.each_with_index do |guest, index|
15
+ csv << ([index + 1] + build_row(guest))
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def headers
23
+ columns.map(&:humanize).uniq
24
+ end
25
+
26
+ def build_row(guest)
27
+ columns.map { |column| fetch_value(guest, column) }
28
+ end
29
+
30
+ def fetch_value(guest, column)
31
+ column_mappings(guest)[column] || ''
32
+ end
33
+
34
+ def column_mappings(guest)
35
+ {
36
+ 'guest_name' => "#{guest.first_name} #{guest.last_name}".strip,
37
+ 'guest_phone_number' => guest.phone_number,
38
+ 'guest_gender' => guest.gender,
39
+ 'guest_dob' => guest.dob.to_s,
40
+ 'guest_occupation' => guest.occupation&.name || guest.other_occupation,
41
+ 'guest_nationality' => guest.nationality&.name,
42
+ 'guest_age' => guest.age.to_s,
43
+ 'guest_emergency_contact' => guest.emergency_contact,
44
+ 'guest_organization' => guest.other_organization,
45
+ 'guest_social_contact' => guest.social_contact,
46
+ 'guest_address' => guest.address,
47
+ 'guest_expectation' => guest.expectation,
48
+ 'entry_type' => guest.entry_type,
49
+ 'created_at' => guest.created_at.strftime('%Y-%m-%d %H:%M:%S'),
50
+ 'ticket_url' => invite_guest.ticket_url(guest.token)
51
+ }
52
+ end
53
+
54
+ def invite_guest
55
+ SpreeCmCommissioner::InviteGuest.find(invite_guest_id)
56
+ end
57
+
58
+ def guests
59
+ invite_guest.order.line_items.first.guests
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ class PaymentMethodTypeMapper
3
+ TYPES = {
4
+ 'vattanac_mini_app' => 'Spree::Gateway::VattanacMiniApp'
5
+ }.freeze
6
+
7
+ def self.call(type)
8
+ TYPES[type.to_s.downcase]
9
+ end
10
+ end
11
+ end