spree_cm_commissioner 2.0.0.pre.pre → 2.0.1.pre.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.env.example +3 -0
- data/Gemfile.lock +1 -1
- data/app/assets/images/cm-hangmeas-checkout_image.svg +63 -0
- data/app/assets/images/cm-hangmeas-failed.svg +56 -0
- data/app/assets/images/cm-hangmeas-loader.svg +50 -0
- data/app/assets/images/cm-hangmeas-success.svg +51 -0
- data/app/assets/javascripts/spree_cm_commissioner/backend.js +1 -0
- data/app/assets/javascripts/spree_cm_commissioner/tenant_payment_icon_fields.js +65 -0
- data/app/assets/stylesheets/spree_cm_commissioner/backend/commissioner_admin.css.scss +1 -0
- data/app/assets/stylesheets/spree_cm_commissioner/backend/tenant_payment_icon_fields.scss +60 -0
- data/app/controllers/concerns/spree_cm_commissioner/content_cachable.rb +2 -1
- data/app/controllers/spree/admin/event_blazer_queries_controller.rb +11 -4
- data/app/controllers/spree/admin/tenants_controller.rb +8 -0
- data/app/controllers/spree/admin/trip_blazer_queries_controller.rb +35 -0
- data/app/controllers/spree/api/v2/organizer/invite_crews_controller.rb +33 -0
- data/app/controllers/spree/api/v2/storefront/dynamic_field_options_controller.rb +5 -1
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +31 -5
- data/app/controllers/spree/api/v2/tenant/checkout_controller.rb +2 -0
- data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +1 -1
- data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +11 -0
- data/app/controllers/spree_cm_commissioner/well_known_controller.rb +31 -17
- data/app/interactors/spree_cm_commissioner/apple_app_site_association_fetcher.rb +27 -0
- data/app/interactors/spree_cm_commissioner/asset_links_fetcher.rb +27 -0
- data/app/interactors/spree_cm_commissioner/crew_invite_link_handler.rb +48 -0
- data/app/interactors/spree_cm_commissioner/telegram_chats_auto_finder.rb +144 -0
- data/app/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb +5 -1
- data/app/models/concerns/spree_cm_commissioner/event_check_in_flowable.rb +30 -0
- data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +2 -1
- data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +4 -0
- data/app/models/spree_cm_commissioner/blazer_queryable.rb +8 -0
- data/app/models/spree_cm_commissioner/crew_invite_link.rb +4 -0
- data/app/models/spree_cm_commissioner/dynamic_field.rb +17 -3
- data/app/models/spree_cm_commissioner/dynamic_field_option.rb +7 -1
- data/app/models/spree_cm_commissioner/guest.rb +1 -1
- data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +21 -3
- data/app/models/spree_cm_commissioner/invite.rb +4 -6
- data/app/models/spree_cm_commissioner/invite_team.rb +3 -1
- data/app/models/spree_cm_commissioner/pin_code.rb +3 -2
- data/app/models/spree_cm_commissioner/pin_code_telegram.rb +28 -0
- data/app/models/spree_cm_commissioner/place.rb +0 -1
- data/app/models/spree_cm_commissioner/product_decorator.rb +0 -2
- data/app/models/spree_cm_commissioner/promotion_category_decorator.rb +11 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +5 -2
- data/app/models/spree_cm_commissioner/telegram_chat.rb +6 -0
- data/app/models/spree_cm_commissioner/trip.rb +9 -13
- data/app/models/spree_cm_commissioner/trip_stop.rb +5 -23
- data/app/models/spree_cm_commissioner/user_taxon.rb +1 -0
- data/app/models/spree_cm_commissioner/variant_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +9 -9
- data/app/models/spree_cm_commissioner/vendor_place.rb +8 -3
- data/app/overrides/spree/admin/taxons/_form/check_in_flows.html.erb.deface +18 -0
- data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +2 -2
- data/app/queries/spree_cm_commissioner/guest_searcher_query.rb +45 -3
- data/app/queries/spree_cm_commissioner/trip_query.rb +56 -27
- data/app/serializers/spree/v2/organizer/invite_crews_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/operator/dashboard_crew_event_serializer.rb +4 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb +1 -3
- data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -3
- data/app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb +2 -1
- data/app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb +23 -15
- data/app/views/blazer/queries/_content.html.erb +8 -0
- data/app/views/spree/admin/tenants/_form.html.erb +109 -42
- data/config/initializers/spree_permitted_attributes.rb +2 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +4 -1
- data/db/migrate/20250616084219_add_description_to_cm_vendor_place.rb +5 -0
- data/db/migrate/20250630103536_create_cm_telegram_chats.rb +13 -0
- data/db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb +6 -0
- data/db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb +5 -0
- data/db/migrate/20250702091935_add_status_to_dynamic_field_option.rb +5 -0
- data/db/migrate/20250707032008_add_vendor_id_to_spree_category.rb +7 -0
- data/db/migrate/20250711092937_add_position_to_cm_dynamic_fields.rb +11 -0
- data/db/migrate/20250711093045_add_position_to_cm_dynamic_field_options.rb +11 -0
- data/db/migrate/20250714121508_rename_cm_taxon_blazer_query_to_blazer_queryables.rb +7 -0
- data/db/migrate/20250714124323_make_cm_blazer_queryables_polymorphic.rb +19 -0
- data/db/migrate/20250716022821_add_location_reference_to_cm_vendor_places.rb +5 -0
- data/db/migrate/20250716031743_drop_table_cm_vendor_stops.rb +5 -0
- data/db/migrate/20250717023824_add_vendor_reference_to_cm_trips.rb +5 -0
- data/db/migrate/20250717041414_add_location_place_reference_to_cm_trip_stops.rb +5 -0
- data/db/migrate/20250717042539_rename_cm_trip_stops_stop_id_column_to_stop_place_id.rb +7 -0
- data/db/migrate/20250717042707_rename_cm_trips_origin_and_destination_to_origin_place_and_destination_place.rb +11 -0
- data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +9 -3
- data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +6 -3
- data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +11 -3
- data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +3 -2
- data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +10 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +13 -1
- data/lib/spree_cm_commissioner/trip_query_result.rb +8 -0
- data/lib/spree_cm_commissioner/trip_result.rb +5 -3
- data/lib/spree_cm_commissioner/version.rb +1 -1
- metadata +39 -5
- data/app/models/spree_cm_commissioner/taxon_blazer_query.rb +0 -8
- data/app/models/spree_cm_commissioner/vendor_stop.rb +0 -9
- data/app/queries/spree_cm_commissioner/vendor_stop_place_query.rb +0 -54
@@ -1,15 +1,18 @@
|
|
1
1
|
module SpreeCmCommissioner
|
2
2
|
class Trip < Base
|
3
|
-
include SpreeCmCommissioner::RouteType
|
4
|
-
|
5
3
|
attr_accessor :hours, :minutes, :seconds
|
6
4
|
|
7
5
|
before_validation :convert_duration_to_seconds
|
8
6
|
|
7
|
+
belongs_to :vendor, class_name: 'Spree::Vendor', inverse_of: :trips, optional: false
|
9
8
|
belongs_to :product, class_name: 'Spree::Product', inverse_of: :trip, optional: false
|
10
9
|
belongs_to :vehicle, class_name: 'SpreeCmCommissioner::Vehicle', optional: false
|
11
|
-
|
12
|
-
belongs_to :
|
10
|
+
|
11
|
+
belongs_to :origin_place, class_name: 'SpreeCmCommissioner::Place', optional: false
|
12
|
+
belongs_to :destination_place, class_name: 'SpreeCmCommissioner::Place', optional: false
|
13
|
+
|
14
|
+
has_many :trip_blazer_queries, as: :queryable, class_name: 'SpreeCmCommissioner::BlazerQueryable'
|
15
|
+
has_many :blazer_queries, through: :trip_blazer_queries, source: :blazer_query, class_name: 'Blazer::Query'
|
13
16
|
|
14
17
|
has_many :trip_stops, class_name: 'SpreeCmCommissioner::TripStop', dependent: :destroy
|
15
18
|
has_many :variants, through: :product
|
@@ -19,9 +22,7 @@ module SpreeCmCommissioner
|
|
19
22
|
validates :duration, numericality: { greater_than: 0 }
|
20
23
|
validate :origin_and_destination_cannot_be_the_same
|
21
24
|
|
22
|
-
accepts_nested_attributes_for :trip_stops, allow_destroy: true
|
23
|
-
|
24
|
-
after_create :create_trip_stops
|
25
|
+
accepts_nested_attributes_for :trip_stops, :product, allow_destroy: true
|
25
26
|
|
26
27
|
def convert_duration_to_seconds
|
27
28
|
return if hours.blank? && minutes.blank? && seconds.blank?
|
@@ -29,11 +30,6 @@ module SpreeCmCommissioner
|
|
29
30
|
self.duration = (hours.to_i * 3600) + (minutes.to_i * 60) + seconds.to_i
|
30
31
|
end
|
31
32
|
|
32
|
-
def create_trip_stops
|
33
|
-
trip_stops.find_or_create_by(stop_type: :boarding, stop_id: origin_id)
|
34
|
-
trip_stops.find_or_create_by(stop_type: :drop_off, stop_id: destination_id)
|
35
|
-
end
|
36
|
-
|
37
33
|
def duration_in_hms
|
38
34
|
return { hours: 0, minutes: 0, seconds: 0 } if duration.nil?
|
39
35
|
|
@@ -52,7 +48,7 @@ module SpreeCmCommissioner
|
|
52
48
|
private
|
53
49
|
|
54
50
|
def origin_and_destination_cannot_be_the_same
|
55
|
-
return unless
|
51
|
+
return unless origin_place_id == destination_place_id
|
56
52
|
|
57
53
|
errors.add(:base, 'Origin and destination cannot be the same')
|
58
54
|
end
|
@@ -3,33 +3,15 @@ module SpreeCmCommissioner
|
|
3
3
|
acts_as_list column: :sequence, scope: :trip_id
|
4
4
|
enum :stop_type, { boarding: 0, drop_off: 1 }
|
5
5
|
|
6
|
-
belongs_to :trip, class_name: 'SpreeCmCommissioner::Trip'
|
7
|
-
belongs_to :
|
6
|
+
belongs_to :trip, class_name: 'SpreeCmCommissioner::Trip', optional: false
|
7
|
+
belongs_to :stop_place, class_name: 'SpreeCmCommissioner::Place', optional: false
|
8
|
+
belongs_to :location_place, class_name: 'SpreeCmCommissioner::Place', optional: false
|
8
9
|
|
9
10
|
before_validation :set_stop_name
|
10
|
-
|
11
|
-
after_commit :create_vendor_stop
|
12
|
-
validates :stop_id, uniqueness: { scope: :trip_id }
|
11
|
+
validates :stop_place_id, uniqueness: { scope: :trip_id }
|
13
12
|
|
14
13
|
def set_stop_name
|
15
|
-
self.stop_name =
|
16
|
-
end
|
17
|
-
|
18
|
-
def create_vendor_stop
|
19
|
-
vendor_stop = vendor.vendor_stops.where(stop_id: stop_id, stop_type: stop_type).first_or_create
|
20
|
-
vendor_stop.update(trip_count: vendor_stop.trip_count.to_i + 1)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def decrement_trip_count
|
26
|
-
vendor.vendor_stops.where(stop_id: stop_id, stop_type: stop_type).find_each do |vendor_stop|
|
27
|
-
vendor_stop.update(trip_count: [vendor_stop.trip_count - 1, 0].max)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def vendor
|
32
|
-
Spree::Product.find(trip&.product_id).vendor
|
14
|
+
self.stop_name = stop_place.name if stop_place.present?
|
33
15
|
end
|
34
16
|
end
|
35
17
|
end
|
@@ -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
|
@@ -101,6 +101,7 @@ module SpreeCmCommissioner
|
|
101
101
|
|
102
102
|
def update_vendor_price
|
103
103
|
return unless vendor.present? && product_type == vendor&.primary_product_type
|
104
|
+
return if price.blank?
|
104
105
|
|
105
106
|
vendor.update(min_price: price) if vendor.min_price.nil? || price < vendor.min_price
|
106
107
|
vendor.update(max_price: price) if vendor.max_price.nil? || price > vendor.max_price
|
@@ -36,9 +36,9 @@ 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, -> {
|
40
|
-
base.has_many :stops, -> {
|
41
|
-
base.has_many :locations, -> {
|
39
|
+
base.has_many :branches, -> { branch }, class_name: 'SpreeCmCommissioner::VendorPlace'
|
40
|
+
base.has_many :stops, -> { stop }, class_name: 'SpreeCmCommissioner::VendorPlace'
|
41
|
+
base.has_many :locations, -> { location }, class_name: 'SpreeCmCommissioner::VendorPlace'
|
42
42
|
|
43
43
|
base.has_many :branch_places, through: :branches, class_name: 'SpreeCmCommissioner::Place', source: :place
|
44
44
|
base.has_many :stop_places, through: :stops, class_name: 'SpreeCmCommissioner::Place', source: :place
|
@@ -47,11 +47,6 @@ module SpreeCmCommissioner
|
|
47
47
|
base.has_many :places,
|
48
48
|
through: :nearby_places, source: :place, class_name: 'SpreeCmCommissioner::Place'
|
49
49
|
|
50
|
-
base.has_many :vendor_stops, class_name: 'SpreeCmCommissioner::VendorStop', dependent: :destroy
|
51
|
-
base.has_many :boarding_points, -> { where(cm_vendor_stops: { stop_type: 0 }) },
|
52
|
-
through: :vendor_stops, source: :stop, class_name: 'SpreeCmCommissioner::Place'
|
53
|
-
base.has_many :drop_off_points, -> { where(cm_vendor_stops: { stop_type: 1 }) },
|
54
|
-
through: :vendor_stops, source: :stop, class_name: 'SpreeCmCommissioner::Place'
|
55
50
|
base.has_many :dynamic_fields, class_name: 'SpreeCmCommissioner::DynamicField', foreign_key: :vendor_id, dependent: :destroy
|
56
51
|
|
57
52
|
base.has_one :logo, as: :viewable, dependent: :destroy, class_name: 'SpreeCmCommissioner::VendorLogo'
|
@@ -79,12 +74,17 @@ module SpreeCmCommissioner
|
|
79
74
|
base.has_many :invoices, class_name: 'SpreeCmCommissioner::Invoice', dependent: :destroy
|
80
75
|
base.has_many :subscriptions, through: :customers, class_name: 'SpreeCmCommissioner::Subscription'
|
81
76
|
base.has_many :subscription_orders, through: :subscriptions, class_name: 'Spree::Order', source: :orders
|
77
|
+
base.has_many :promotion_categories, class_name: 'Spree::PromotionCategory', foreign_key: :vendor_id, dependent: :destroy
|
82
78
|
|
83
79
|
base.has_many :homepage_section_relatables,
|
80
|
+
as: :relatable,
|
84
81
|
class_name: 'SpreeCmCommissioner::HomepageSectionRelatable',
|
85
|
-
dependent: :destroy,
|
82
|
+
dependent: :destroy,
|
83
|
+
inverse_of: :relatable
|
86
84
|
|
87
85
|
base.has_many :vehicles, class_name: 'SpreeCmCommissioner::Vehicle', dependent: :destroy
|
86
|
+
base.has_many :trips, class_name: 'SpreeCmCommissioner::Trip', dependent: :destroy
|
87
|
+
|
88
88
|
base.validates :account_name, :account_number, presence: true, if: lambda {
|
89
89
|
payment_qrcode.present? && Spree::Store.default.code.include?('billing')
|
90
90
|
}
|
@@ -5,17 +5,22 @@ module SpreeCmCommissioner
|
|
5
5
|
|
6
6
|
belongs_to :vendor, class_name: 'Spree::Vendor', optional: false
|
7
7
|
belongs_to :place, class_name: 'SpreeCmCommissioner::Place', optional: false
|
8
|
+
belongs_to :location, class_name: 'SpreeCmCommissioner::VendorPlace', optional: true
|
9
|
+
|
10
|
+
has_many :branches, -> { branch }, class_name: 'SpreeCmCommissioner::VendorPlace'
|
11
|
+
has_many :stops, -> { stop }, class_name: 'SpreeCmCommissioner::VendorPlace'
|
8
12
|
|
9
13
|
validates :place_type, presence: true
|
10
|
-
validates :
|
14
|
+
validates :place_id, uniqueness: { scope: %i[vendor_id place_type] }
|
15
|
+
validates :location, presence: true, if: -> { branch? || stop? }
|
16
|
+
|
17
|
+
accepts_nested_attributes_for :place, allow_destroy: true
|
11
18
|
|
12
19
|
# include place when using these delegate to avoid N+1
|
13
20
|
def display_name
|
14
21
|
place&.name
|
15
22
|
end
|
16
23
|
|
17
|
-
accepts_nested_attributes_for :place, allow_destroy: true
|
18
|
-
|
19
24
|
def selected
|
20
25
|
vendor.selected_place_references.include?(place&.reference)
|
21
26
|
end
|
@@ -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 %> %>
|
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
<p>Guest Information Fields</p>
|
4
4
|
<div class="form-check mb-3">
|
5
|
-
<%= f.check_box :use_product_kyc, id: "toggleGuestInfo", class: 'form-check-input mr-2', checked:
|
5
|
+
<%= f.check_box :use_product_kyc, id: "toggleGuestInfo", class: 'form-check-input mr-2', checked: @variant.kyc.nil? %>
|
6
6
|
<label for="toggleGuestInfo" class="form-check-label">
|
7
7
|
Use Product Guest Information
|
8
8
|
</label>
|
9
9
|
</div>
|
10
10
|
|
11
|
-
<div id="guestInfoForm" <% if @variant.kyc
|
11
|
+
<div id="guestInfoForm" <% if @variant.kyc.nil? %>style="display: none;"<% end %>">
|
12
12
|
<small class="form-text text-muted mb-4">
|
13
13
|
<%= raw I18n.t('kyc.variant_note') %>
|
14
14
|
</small>
|
@@ -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.
|
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
|
|
@@ -7,8 +7,7 @@ module SpreeCmCommissioner
|
|
7
7
|
def initialize(origin_id:, destination_id:, date:, params: {})
|
8
8
|
@origin_id = origin_id
|
9
9
|
@destination_id = destination_id
|
10
|
-
@date = date
|
11
|
-
@date = Time.zone.now if date.to_date == Time.zone.now.to_date
|
10
|
+
@date = date.to_date == Time.zone.now.to_date ? Time.zone.now : Time.zone.parse(date.to_s)
|
12
11
|
@params = params
|
13
12
|
end
|
14
13
|
|
@@ -20,26 +19,29 @@ module SpreeCmCommissioner
|
|
20
19
|
direct_results + connected_results
|
21
20
|
end
|
22
21
|
|
23
|
-
def direct_trips
|
24
|
-
result = Spree::
|
25
|
-
.select('
|
22
|
+
def direct_trips # rubocop:disable Metrics/MethodLength
|
23
|
+
result = Spree::Product
|
24
|
+
.select('
|
26
25
|
vendors.id AS vendor_id,
|
27
26
|
vendors.name AS vendor_name,
|
28
|
-
|
29
|
-
|
27
|
+
spree_products.name AS route_name,
|
28
|
+
spree_products.short_name AS short_name,
|
30
29
|
boarding.stop_id AS origin_id,
|
31
30
|
drop_off.stop_id AS destination_id,
|
32
31
|
boarding.stop_name AS origin,
|
33
32
|
drop_off.stop_name AS destination,
|
33
|
+
spree_products.id AS trip_id,
|
34
34
|
trips.departure_time AS departure_time,
|
35
35
|
trips.duration AS duration,
|
36
|
-
trips.vehicle_id AS vehicle_id
|
36
|
+
trips.vehicle_id AS vehicle_id,
|
37
|
+
COALESCE(iv.quantity_available, 0) AS quantity_available,
|
38
|
+
COALESCE(iv.max_capacity, 0) AS max_capacity'
|
37
39
|
)
|
38
|
-
.joins('INNER JOIN
|
39
|
-
.joins('INNER JOIN
|
40
|
-
.joins('INNER JOIN cm_trip_stops AS
|
41
|
-
.joins('INNER JOIN
|
42
|
-
.joins(
|
40
|
+
.joins('INNER JOIN cm_trips AS trips ON trips.product_id = spree_products.id')
|
41
|
+
.joins('INNER JOIN cm_trip_stops AS boarding ON boarding.trip_id = trips.id AND boarding.stop_type = 0')
|
42
|
+
.joins('INNER JOIN cm_trip_stops AS drop_off ON drop_off.trip_id = trips.id AND drop_off.stop_type = 1')
|
43
|
+
.joins('INNER JOIN spree_vendors AS vendors ON vendors.id = spree_products.vendor_id')
|
44
|
+
.joins("LEFT JOIN (#{product_inventory_totals.to_sql}) iv ON spree_products.id = iv.product_id")
|
43
45
|
|
44
46
|
result = result.where(vendors: { id: params[:vendor_id] }) if params[:vendor_id].present?
|
45
47
|
result = result.where('boarding.stop_id = ? AND drop_off.stop_id = ?', origin_id, destination_id)
|
@@ -47,9 +49,10 @@ module SpreeCmCommissioner
|
|
47
49
|
date.strftime('%H:%M:%S'),
|
48
50
|
date.end_of_day.strftime('%H:%M:%S')
|
49
51
|
)
|
52
|
+
|
50
53
|
result.map do |trip|
|
51
54
|
trip_result_options = {
|
52
|
-
trip_id: trip[:
|
55
|
+
trip_id: trip[:trip_id],
|
53
56
|
vendor_id: trip[:vendor_id],
|
54
57
|
vendor_name: trip[:vendor_name],
|
55
58
|
route_name: trip[:route_name],
|
@@ -61,7 +64,9 @@ module SpreeCmCommissioner
|
|
61
64
|
destination: trip[:destination],
|
62
65
|
vehicle_id: trip[:vehicle_id],
|
63
66
|
departure_time: parse_time(trip[:departure_time]),
|
64
|
-
duration: trip[:duration]
|
67
|
+
duration: trip[:duration],
|
68
|
+
quantity_available: trip[:quantity_available].to_i,
|
69
|
+
max_capacity: trip[:max_capacity].to_i
|
65
70
|
}
|
66
71
|
SpreeCmCommissioner::TripResult.new(trip_result_options)
|
67
72
|
end
|
@@ -69,16 +74,18 @@ module SpreeCmCommissioner
|
|
69
74
|
|
70
75
|
def connected_trips # rubocop:disable Metrics/MethodLength
|
71
76
|
result = SpreeCmCommissioner::TripConnection
|
72
|
-
.joins(
|
77
|
+
.joins("
|
73
78
|
INNER JOIN cm_trips trip1 ON trip1.id = cm_trip_connections.from_trip_id
|
74
79
|
INNER JOIN cm_trips trip2 ON trip2.id = cm_trip_connections.to_trip_id
|
75
|
-
INNER JOIN spree_products AS
|
76
|
-
INNER JOIN spree_products AS
|
80
|
+
INNER JOIN spree_products AS product1 ON product1.id = trip1.product_id
|
81
|
+
INNER JOIN spree_products AS product2 ON product2.id = trip2.product_id
|
77
82
|
INNER JOIN cm_trip_stops trip1_origin ON trip1_origin.trip_id = trip1.id AND trip1_origin.stop_type = 0
|
78
83
|
INNER JOIN cm_trip_stops trip2_origin ON trip2_origin.trip_id = trip2.id AND trip2_origin.stop_type = 0
|
79
84
|
INNER JOIN cm_trip_stops trip2_destination ON trip2_destination.trip_id = trip2.id AND trip2_destination.stop_type = 1
|
80
|
-
INNER JOIN spree_vendors AS vendor1 ON vendor1.id =
|
81
|
-
INNER JOIN spree_vendors AS vendor2 ON vendor2.id =
|
85
|
+
INNER JOIN spree_vendors AS vendor1 ON vendor1.id = product1.vendor_id
|
86
|
+
INNER JOIN spree_vendors AS vendor2 ON vendor2.id = product2.vendor_id
|
87
|
+
LEFT JOIN (#{product_inventory_totals.to_sql}) AS iv1 ON iv1.product_id = product1.id
|
88
|
+
LEFT JOIN (#{product_inventory_totals.to_sql}) AS iv2 ON iv2.product_id = product2.id"
|
82
89
|
)
|
83
90
|
.select('cm_trip_connections.id AS id,
|
84
91
|
trip1.id AS trip1_id,
|
@@ -86,8 +93,9 @@ module SpreeCmCommissioner
|
|
86
93
|
trip1.destination_id AS trip1_destination_id,
|
87
94
|
trip1.departure_time AS trip1_departure_time,
|
88
95
|
trip1.duration AS trip1_duration,
|
89
|
-
|
90
|
-
|
96
|
+
product1.id AS trip1_id,
|
97
|
+
product1.short_name AS route1_short_name,
|
98
|
+
product1.name AS route1_name,
|
91
99
|
trip1.vehicle_id AS trip1_vehicle,
|
92
100
|
vendor1.name AS trip1_vendor_name,
|
93
101
|
trip2.id AS trip2_id,
|
@@ -96,12 +104,17 @@ module SpreeCmCommissioner
|
|
96
104
|
trip2.departure_time AS trip2_departure_time,
|
97
105
|
trip2.duration AS trip2_duration,
|
98
106
|
trip2.vehicle_id AS trip2_vehicle,
|
99
|
-
|
100
|
-
|
107
|
+
product2.id AS trip2_id,
|
108
|
+
product2.short_name AS route2_short_name,
|
109
|
+
product2.name AS route2_name,
|
101
110
|
trip1_origin.stop_name AS trip1_origin,
|
102
111
|
trip2_origin.stop_name AS trip2_origin,
|
103
112
|
trip2_destination.stop_name AS trip2_destination,
|
104
|
-
vendor2.name AS trip2_vendor_name
|
113
|
+
vendor2.name AS trip2_vendor_name,
|
114
|
+
COALESCE(iv1.quantity_available, 0) as trip1_quantity_available,
|
115
|
+
COALESCE(iv2.quantity_available, 0) as trip2_quantity_available,
|
116
|
+
COALESCE(iv1.max_capacity, 0) as trip1_max_capacity,
|
117
|
+
COALESCE(iv2.max_capacity, 0) as trip2_max_capacity'
|
105
118
|
).where('trip1_origin.stop_id = ? AND trip2_destination.stop_id = ?', origin_id, destination_id)
|
106
119
|
result = result.where('vendor1.id = ? OR vendor2.id = ?', params[:vendor_id], params[:vendor_id]) if params[:vendor_id].present?
|
107
120
|
result = result.where('trip1.departure_time > ? AND trip1.departure_time <= ?', date.strftime('%H:%M:%S'),
|
@@ -112,6 +125,18 @@ module SpreeCmCommissioner
|
|
112
125
|
build_trip_query_result(result)
|
113
126
|
end
|
114
127
|
|
128
|
+
def product_inventory_totals
|
129
|
+
Spree::Product
|
130
|
+
.select(
|
131
|
+
'spree_products.id AS product_id,
|
132
|
+
SUM(cm_inventory_items.max_capacity) AS max_capacity,
|
133
|
+
SUM(cm_inventory_items.quantity_available) AS quantity_available'
|
134
|
+
)
|
135
|
+
.joins(variants: :inventory_items)
|
136
|
+
.where(cm_inventory_items: { inventory_date: date.to_date })
|
137
|
+
.group('spree_products.id')
|
138
|
+
end
|
139
|
+
|
115
140
|
private
|
116
141
|
|
117
142
|
def build_trip_query_result(connections)
|
@@ -127,7 +152,9 @@ module SpreeCmCommissioner
|
|
127
152
|
short_name: trip[:route1_short_name],
|
128
153
|
vehicle_id: trip[:trip1_vehicle],
|
129
154
|
origin: trip[:trip1_origin],
|
130
|
-
destination: trip[:trip2_origin]
|
155
|
+
destination: trip[:trip2_origin],
|
156
|
+
quantity_available: trip[:trip1_quantity_available].to_i,
|
157
|
+
max_capacity: trip[:trip1_max_capacity].to_i
|
131
158
|
}
|
132
159
|
to_trip = {
|
133
160
|
trip_id: trip[:trip2_id],
|
@@ -140,7 +167,9 @@ module SpreeCmCommissioner
|
|
140
167
|
short_name: trip[:route2_short_name],
|
141
168
|
vehicle_id: trip[:trip2_vehicle],
|
142
169
|
origin: trip[:trip2_origin],
|
143
|
-
destination: trip[:trip2_destination]
|
170
|
+
destination: trip[:trip2_destination],
|
171
|
+
quantity_available: trip[:trip2_quantity_available].to_i,
|
172
|
+
max_capacity: trip[:trip2_max_capacity].to_i
|
144
173
|
}
|
145
174
|
data = [SpreeCmCommissioner::TripResult.new(from_trip),
|
146
175
|
SpreeCmCommissioner::TripResult.new(to_trip)
|
@@ -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,10 @@ module SpreeCmCommissioner
|
|
2
2
|
module V2
|
3
3
|
module Operator
|
4
4
|
class DashboardCrewEventSerializer < BaseSerializer
|
5
|
-
attributes :id, :name, :permalink,
|
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
|
@@ -2,9 +2,7 @@ module SpreeCmCommissioner
|
|
2
2
|
module V2
|
3
3
|
module Storefront
|
4
4
|
class DynamicFieldOptionSerializer < BaseSerializer
|
5
|
-
|
6
|
-
|
7
|
-
attributes :id, :value, :dynamic_field_id, :created_at, :updated_at
|
5
|
+
attributes :id, :value, :dynamic_field_id, :status, :created_at, :updated_at, :position
|
8
6
|
end
|
9
7
|
end
|
10
8
|
end
|
@@ -2,9 +2,7 @@ module SpreeCmCommissioner
|
|
2
2
|
module V2
|
3
3
|
module Storefront
|
4
4
|
class DynamicFieldSerializer < BaseSerializer
|
5
|
-
|
6
|
-
|
7
|
-
attributes :id, :label, :data_type, :vendor_id, :created_at, :updated_at
|
5
|
+
attributes :id, :label, :data_type, :vendor_id, :multiple_select, :created_at, :updated_at, :position
|
8
6
|
|
9
7
|
has_many :dynamic_field_options, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
|
10
8
|
end
|
@@ -4,9 +4,10 @@ module SpreeCmCommissioner
|
|
4
4
|
class GuestDynamicFieldSerializer < BaseSerializer
|
5
5
|
set_type :guest_dynamic_field
|
6
6
|
|
7
|
-
attributes :id, :value, :guest_id, :dynamic_field_id, :created_at, :updated_at
|
7
|
+
attributes :id, :value, :guest_id, :dynamic_field_id, :dynamic_field_option_id, :created_at, :updated_at
|
8
8
|
|
9
9
|
belongs_to :dynamic_field, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldSerializer
|
10
|
+
belongs_to :dynamic_field_option, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
@@ -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(
|
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
|
-
|
51
|
-
|
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:
|
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
|
@@ -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
|
|