spree_cm_commissioner 1.17.0.pre.pre → 1.17.0.pre.pre2

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: 6cc0c166a073d01107caea18b4b7f2381d12b9372ac67aa80b570687aaf59702
4
- data.tar.gz: 0d736865e66226bed4f07171d02879c6d009d760595d88f6f63605e57bc228a6
3
+ metadata.gz: bd0a9d4b3819bd12ab5e38ffd050cf46ca5b8a937965a25ae911f9208b26586a
4
+ data.tar.gz: a17a1eea391cdf4c4c2c17d300ee275ab70b67dbc87b4448cbc4a2a6cae1c533
5
5
  SHA512:
6
- metadata.gz: e55841d41f47a5aedd68cb9c81309f356f1731d24c1771d8955f6d20d0cb8050f5aefe867bbe3d1501b4fb421aca87daea26a9314281efda5d2b89792f332c63
7
- data.tar.gz: 2f6b56fb52a8cf35206c8b24c99d0b991fbed3343c8ca56377f53febc7080c25af53ff1d839ae63c6bfa6ca6a148ffcb427c88fce10e58f60892d536106a14bb
6
+ metadata.gz: 45451b1d44bf6820463098e3c2a37cfd113753206b1ccbc13247a7f3db577be706fff5b1dd54e528036e6120dacfb4d9472672f3f196d8866dbdfff7557bbdde
7
+ data.tar.gz: d52c8b30b4e67599eac1eba6f75025c6ee01c6967caaebd7874e22fa71ca7202a1927facd4d8c3ad0e8da256ece71e3977b83a3ea56292e0a740c0b56bc05566
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (1.17.0.pre.pre)
37
+ spree_cm_commissioner (1.17.0.pre.pre2)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -572,6 +572,10 @@ 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)
575
579
  noticed (1.6.3)
576
580
  http (>= 4.0.0)
577
581
  rails (>= 5.2.0)
@@ -0,0 +1,30 @@
1
+ module SpreeCmCommissioner
2
+ module EventCheckInFlowable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ preference :group_check_in_enabled, :boolean, default: true
7
+ preference :individual_check_in_enabled, :boolean, default: true
8
+
9
+ before_validation :validate_at_least_one_check_in_flow_presence
10
+ end
11
+
12
+ def check_in_flows
13
+ flows = []
14
+ flows << 'group' if group_check_in_enabled?
15
+ flows << 'individual' if individual_check_in_enabled?
16
+ flows
17
+ end
18
+
19
+ def group_check_in_enabled? = preferred_group_check_in_enabled
20
+ def individual_check_in_enabled? = preferred_individual_check_in_enabled
21
+
22
+ private
23
+
24
+ def validate_at_least_one_check_in_flow_presence
25
+ return if check_in_flows.any?
26
+
27
+ errors.add(:check_in_flows, 'must have at least one flow selected')
28
+ end
29
+ end
30
+ end
@@ -51,7 +51,7 @@ module SpreeCmCommissioner
51
51
  validates :seat_number, uniqueness: { scope: :event_id }, allow_nil: true, if: -> { event_id.present? }
52
52
  validates :bib_index, uniqueness: true, allow_nil: true
53
53
 
54
- self.whitelisted_ransackable_associations = %w[id_card event]
54
+ self.whitelisted_ransackable_associations = %w[id_card event line_item]
55
55
  self.whitelisted_ransackable_attributes = %w[first_name last_name phone_number gender contact occupation_id card_type created_at check_in_status]
56
56
 
57
57
  def self.csv_importable_columns
@@ -4,6 +4,7 @@ module SpreeCmCommissioner
4
4
  base.include SpreeCmCommissioner::TaxonKind
5
5
  base.include SpreeCmCommissioner::Transit::TaxonBitwise
6
6
  base.include SpreeCmCommissioner::ParticipationTypeBitwise
7
+ base.include SpreeCmCommissioner::EventCheckInFlowable
7
8
 
8
9
  base.preference :background_color, :string
9
10
  base.preference :foreground_color, :string
@@ -2,5 +2,6 @@ module SpreeCmCommissioner
2
2
  class UserTaxon < Base
3
3
  belongs_to :user, class_name: Spree.user_class.to_s, optional: false
4
4
  belongs_to :taxon, class_name: 'Spree::Taxon', optional: false
5
+ has_many :invite_user_taxons, class_name: 'SpreeCmCommissioner::InviteUserTaxon', dependent: :destroy
5
6
  end
6
7
  end
@@ -1,8 +1,6 @@
1
- require_dependency 'spree_cm_commissioner'
2
-
3
1
  module SpreeCmCommissioner
4
- class VendorPlace < ApplicationRecord
5
- enum place_type: { branch: 0, stop: 1, locations: 2 }
2
+ class VendorPlace < Base
3
+ enum place_type: { location: 0, branch: 1, stop: 2 }
6
4
  acts_as_list scope: :vendor
7
5
 
8
6
  belongs_to :vendor, class_name: 'Spree::Vendor', optional: false
@@ -13,9 +11,9 @@ module SpreeCmCommissioner
13
11
 
14
12
  accepts_nested_attributes_for :place, allow_destroy: true
15
13
 
16
- scope :branches, -> { where(place_type: :branch) }
17
- scope :stops, -> { where(place_type: :stop) }
18
- scope :locations, -> { where(place_type: :locations) }
14
+ scope :branches, -> { where(place_type: :branch) }
15
+ scope :stops, -> { where(place_type: :stop) }
16
+ scope :locations, -> { where(place_type: :location) }
19
17
 
20
18
  def selected
21
19
  vendor.selected_place_references.include?(place&.reference)
@@ -0,0 +1,18 @@
1
+ <!-- insert_before "erb[loud]:contains('field_container :hide_from_nav')" -->
2
+
3
+ <%# Sections don't use video banner, so we hide the form here to avoid confusing admin. %>
4
+
5
+ <%= f.field_container :preferred_group_check_in_enabled, class: ['custom-control', 'custom-checkbox', 'my-4'] do %>
6
+ <%= f.check_box :preferred_group_check_in_enabled, class: 'custom-control-input' %>
7
+ <%= f.label :preferred_group_check_in_enabled, Spree.t(:enable_group_check_in), class: 'custom-control-label' %>
8
+ <%= f.error_message_on :preferred_group_check_in_enabled %>
9
+ <small class="form-text text-muted">
10
+ Enabled by default for most events where users can purchase multiple tickets or use group scanning. For large events (like PSK, ASK, etc.) or invitation-based events, you should disable this to ensure each ticket or invitation is scanned individually.
11
+ </small>
12
+ <% end if @taxon.event? && @taxon.depth == 1 %> %>
13
+
14
+ <%= f.field_container :preferred_individual_check_in_enabled, class: ['custom-control', 'custom-checkbox', 'my-4'] do %>
15
+ <%= f.check_box :preferred_individual_check_in_enabled, class: 'custom-control-input' %>
16
+ <%= f.label :preferred_individual_check_in_enabled, Spree.t(:enable_individual_check_in), class: 'custom-control-label' %>
17
+ <%= f.error_message_on :preferred_individual_check_in_enabled %>
18
+ <% end if @taxon.event? && @taxon.depth == 1 %> %>
@@ -8,20 +8,36 @@ module SpreeCmCommissioner
8
8
 
9
9
  def event_id = params[:event_id]
10
10
 
11
- def call
11
+ def call # rubocop:disable Metrics/PerceivedComplexity
12
12
  return SpreeCmCommissioner::Guest.none if event_id.blank?
13
13
 
14
- if params[:qr_data].present?
14
+ if params[:qr_data].present? && order_qr_data?
15
+ search_by_order_qr
16
+ elsif params[:qr_data].present? && line_item_qr_data?
17
+ search_by_line_item_qr
18
+ elsif params[:qr_data].present? && guest_qr_data?
15
19
  search_by_guest_qr
16
20
  elsif params[:term].present?
17
21
  search_by_term
22
+ elsif params[:ids].present?
23
+ SpreeCmCommissioner::Guest.complete_or_canceled.where(event_id: event_id, id: params[:ids])
18
24
  else
19
- SpreeCmCommissioner::Guest.none
25
+ SpreeCmCommissioner::Guest.complete_or_canceled.where(event_id: event_id)
20
26
  end
21
27
  end
22
28
 
23
29
  private
24
30
 
31
+ def search_by_order_qr
32
+ order = Spree::Order.complete_or_canceled.search_by_qr_data!(params[:qr_data])
33
+ order.guests.where(event_id: event_id)
34
+ end
35
+
36
+ def search_by_line_item_qr
37
+ line_item = Spree::LineItem.complete_or_canceled.search_by_qr_data!(params[:qr_data])
38
+ line_item.guests.where(event_id: event_id)
39
+ end
40
+
25
41
  def search_by_guest_qr
26
42
  SpreeCmCommissioner::Guest.complete_or_canceled.where(
27
43
  token: params[:qr_data],
@@ -29,6 +45,32 @@ module SpreeCmCommissioner
29
45
  )
30
46
  end
31
47
 
48
+ def order_qr_data?
49
+ matches = construct_matches
50
+ matches&.size == 2
51
+ end
52
+
53
+ def line_item_qr_data?
54
+ matches = construct_matches
55
+ matches&.size == 3
56
+ end
57
+
58
+ def guest_qr_data?
59
+ matches = construct_matches
60
+ matches.nil?
61
+ end
62
+
63
+ def construct_matches
64
+ qr_data = params[:qr_data]
65
+ return nil unless qr_data
66
+
67
+ if qr_data =~ /-L\d+$/
68
+ qr_data.match(/(R\d+)-([A-Za-z0-9_\-]+)-(L\d+)/)&.captures
69
+ else
70
+ qr_data.match(/(R\d+)-([A-Za-z0-9_\-]+)/)&.captures
71
+ end
72
+ end
73
+
32
74
  def search_by_term
33
75
  terms = params[:term].split.map { |term| "%#{term.downcase}%" }
34
76
 
@@ -2,7 +2,10 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Operator
4
4
  class DashboardCrewEventSerializer < BaseSerializer
5
- attributes :id, :name, :permalink, :from_date, :to_date, :updated_at
5
+ attributes :id, :name, :permalink,
6
+ :from_date, :to_date,
7
+ :check_in_flows,
8
+ :updated_at
6
9
 
7
10
  has_many :children_classifications, serializer: :classification
8
11
  has_one :category_icon, serializer: SpreeCmCommissioner::V2::Storefront::AssetSerializer
@@ -1,11 +1,12 @@
1
1
  module SpreeCmCommissioner
2
2
  module Organizer
3
3
  class ExportGuestCsvService
4
- attr_reader :event_id, :columns
4
+ attr_reader :event_id, :columns, :filters
5
5
 
6
- def initialize(event_id, columns)
6
+ def initialize(event_id, columns, filters = {})
7
7
  @event_id = event_id
8
8
  @columns = columns
9
+ @filters = filters
9
10
  end
10
11
 
11
12
  def call
@@ -18,7 +19,7 @@ module SpreeCmCommissioner
18
19
  private
19
20
 
20
21
  def headers
21
- columns.map(&:humanize).uniq
22
+ columns.map { |col| col.titleize(keep_id_suffix: true) }.uniq
22
23
  end
23
24
 
24
25
  def build_row(guest)
@@ -28,10 +29,8 @@ module SpreeCmCommissioner
28
29
  def fetch_value(guest, column)
29
30
  if guest_field?(column)
30
31
  fetch_guest_value(guest, column)
31
- elsif option_type_field?(column)
32
- fetch_option_value(guest, column)
33
32
  else
34
- ''
33
+ fetch_option_value(guest, column)
35
34
  end
36
35
  end
37
36
 
@@ -39,19 +38,21 @@ module SpreeCmCommissioner
39
38
  SpreeCmCommissioner::KycBitwise::ORDERED_BIT_FIELDS.include?(column.to_sym)
40
39
  end
41
40
 
42
- def option_type_field?(column)
43
- Spree::OptionType.exists?(name: column)
44
- end
45
-
46
41
  def fetch_guest_value(guest, column)
47
42
  column_mappings(guest)[column] || ''
48
43
  end
49
44
 
50
- def fetch_option_value(guest, option_type_name)
51
- return guest.formatted_bib_number if option_type_name == 'bib-prefix'
45
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
46
+ def fetch_option_value(guest, column_name)
47
+ return guest.formatted_bib_number if column_name == 'bib-prefix'
48
+ return guest.line_item&.number if column_name == 'item_id'
49
+ return guest.line_item&.order&.number if column_name == 'order_id'
50
+ return guest.created_at if column_name == 'created_at'
51
+ return guest.updated_at if column_name == 'updated_at'
52
52
 
53
- guest.line_item&.variant&.find_option_value_name_for(option_type_name: option_type_name)
53
+ guest.line_item&.variant&.find_option_value_name_for(option_type_name: column_name) || ''
54
54
  end
55
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
55
56
 
56
57
  def column_mappings(guest)
57
58
  {
@@ -77,12 +78,19 @@ module SpreeCmCommissioner
77
78
  end
78
79
 
79
80
  def guests_with_associations
80
- event.guests.includes(
81
+ scope = event.guests.includes(
81
82
  :occupation,
82
83
  :nationality,
83
84
  :id_card,
84
85
  line_item: { variant: { option_values: :option_type } }
85
- )
86
+ ).complete
87
+ scope = scope.where('cm_guests.created_at >= ?', formatted_date_time(filters[:from_date])) if filters[:from_date].present?
88
+ scope = scope.where('cm_guests.created_at <= ?', formatted_date_time(filters[:to_date])) if filters[:to_date].present?
89
+ scope
90
+ end
91
+
92
+ def formatted_date_time(date)
93
+ Time.zone.parse(date.to_s).strftime('%Y-%m-%d %H:%M:%S %z')
86
94
  end
87
95
 
88
96
  def event
@@ -31,6 +31,8 @@ module Spree
31
31
  subtitle
32
32
  preferred_background_color
33
33
  preferred_foreground_color
34
+ preferred_group_check_in_enabled
35
+ preferred_individual_check_in_enabled
34
36
  show_badge_status
35
37
  purchasable_on
36
38
  available_on
@@ -14,8 +14,8 @@ FactoryBot.define do
14
14
  place_type { :stop }
15
15
  end
16
16
 
17
- trait :locations do
18
- place_type { :locations }
17
+ trait :location do
18
+ place_type { :location }
19
19
  end
20
20
  end
21
21
  end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '1.17.0-pre'.freeze
2
+ VERSION = '1.17.0-pre2'.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.17.0.pre.pre
4
+ version: 1.17.0.pre.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-27 00:00:00.000000000 Z
11
+ date: 2025-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -1179,6 +1179,7 @@ files:
1179
1179
  - app/mailers/spree_cm_commissioner/pin_code_mailer.rb
1180
1180
  - app/mailers/spree_cm_commissioner/team_invite_mailer.rb
1181
1181
  - app/models/.gitkeep
1182
+ - app/models/concerns/spree_cm_commissioner/event_check_in_flowable.rb
1182
1183
  - app/models/concerns/spree_cm_commissioner/homepage_section_bitwise.rb
1183
1184
  - app/models/concerns/spree_cm_commissioner/json_preference_validator.rb
1184
1185
  - app/models/concerns/spree_cm_commissioner/kyc_bitwise.rb
@@ -1484,6 +1485,7 @@ files:
1484
1485
  - app/overrides/spree/admin/taxons/_form/assets_form.html.erb.deface
1485
1486
  - app/overrides/spree/admin/taxons/_form/available_on.html.erb.deface
1486
1487
  - app/overrides/spree/admin/taxons/_form/background_color_and_foreground_color.html.erb.deface
1488
+ - app/overrides/spree/admin/taxons/_form/check_in_flows.html.erb.deface
1487
1489
  - app/overrides/spree/admin/taxons/_form/custom_redirect_url.html.erb.deface
1488
1490
  - app/overrides/spree/admin/taxons/_form/hide_video_banner.html.erb.deface
1489
1491
  - app/overrides/spree/admin/taxons/_form/kind_html.erb.deface