spree_cm_commissioner 2.5.1.pre.pre2 → 2.5.1.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 +4 -4
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/api/chatrace/guests_controller.rb +37 -20
- data/app/controllers/spree/api/v2/operator/check_in_bulks_controller.rb +9 -0
- data/app/controllers/spree/api/v2/storefront/account/qr_data_controller.rb +30 -0
- data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +1 -1
- data/app/controllers/spree/api/v2/storefront/transit/draft_orders_controller.rb +4 -4
- data/app/controllers/spree/transit/trips_controller.rb +3 -3
- data/app/finders/spree_cm_commissioner/places/find_with_route.rb +12 -12
- data/app/finders/spree_cm_commissioner/routes/find_popular.rb +35 -20
- data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +4 -11
- data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +1 -10
- data/app/{services/spree_cm_commissioner/transit_order/create.rb → interactors/spree_cm_commissioner/transit/draft_order_creator.rb} +16 -13
- data/app/interactors/spree_cm_commissioner/trip_clone_creator.rb +3 -4
- data/app/interactors/spree_cm_commissioner/trip_stops_creator.rb +2 -2
- data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +2 -2
- data/app/jobs/spree_cm_commissioner/transit/route_fulfilled_order_count_incrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_order_count_incrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_previous_trip_count_decrementer_job.rb +13 -0
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_decrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_incrementer_job.rb +10 -0
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +16 -11
- data/app/models/concerns/spree_cm_commissioner/route_order_countable.rb +2 -2
- data/app/models/concerns/spree_cm_commissioner/route_trip_count_callbacks.rb +48 -0
- data/app/models/concerns/spree_cm_commissioner/user_identity.rb +0 -6
- data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +4 -0
- data/app/models/spree_cm_commissioner/guest.rb +4 -4
- data/app/models/spree_cm_commissioner/place.rb +8 -5
- data/app/models/spree_cm_commissioner/product_decorator.rb +0 -1
- data/app/models/spree_cm_commissioner/route.rb +5 -46
- data/app/models/spree_cm_commissioner/trip.rb +33 -8
- data/app/models/spree_cm_commissioner/trip_connection.rb +36 -0
- data/app/models/spree_cm_commissioner/trip_stop.rb +2 -16
- data/app/models/spree_cm_commissioner/user_decorator.rb +30 -18
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -3
- data/app/models/spree_cm_commissioner/vendor_route.rb +9 -0
- data/app/queries/spree_cm_commissioner/guest_searcher_query.rb +25 -2
- data/app/queries/spree_cm_commissioner/trip_query.rb +2 -2
- data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +2 -1
- data/app/serializers/spree_cm_commissioner/v2/operator/guest_serializer.rb +1 -0
- data/app/serializers/spree_cm_commissioner/v2/operator/line_item_serializer.rb +2 -2
- data/app/serializers/spree_cm_commissioner/v2/operator/{line_item_order_serializer.rb → order_serializer.rb} +1 -2
- data/app/serializers/spree_cm_commissioner/v2/operator/user_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/operator/variant_serializer.rb +9 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_serializer.rb +1 -3
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_stop_serializer.rb +1 -1
- data/app/services/spree_cm_commissioner/{route_metrics/update_route_metrics.rb → routes/base_update_order_metrics.rb} +16 -11
- data/app/services/spree_cm_commissioner/routes/decrement_previous_trip_count.rb +30 -0
- data/app/services/spree_cm_commissioner/routes/decrement_trip_count.rb +33 -0
- data/app/services/spree_cm_commissioner/{route_metrics/increase_fulfilled_order_count.rb → routes/increment_fulfilled_order_count.rb} +3 -3
- data/app/services/spree_cm_commissioner/{route_metrics/increase_order_count.rb → routes/increment_order_count.rb} +3 -3
- data/app/services/spree_cm_commissioner/routes/increment_trip_count.rb +33 -0
- data/app/services/spree_cm_commissioner/seeds/user_usernames.rb +86 -0
- data/app/services/spree_cm_commissioner/users/qr_data/extract_login.rb +18 -0
- data/app/services/spree_cm_commissioner/users/qr_data/generate.rb +14 -0
- data/app/services/spree_cm_commissioner/users/qr_data/invalidate.rb +19 -0
- data/app/services/spree_cm_commissioner/users/qr_data/verify.rb +33 -0
- data/app/services/spree_cm_commissioner/users/username/generate.rb +68 -0
- data/app/views/spree/transit/trip_stops/index.html.erb +2 -4
- data/app/views/spree_cm_commissioner/guest_mailer/send_ticket_to_guest.html.erb +1 -0
- data/config/initializers/spree_permitted_attributes.rb +1 -11
- data/config/routes.rb +2 -6
- data/db/migrate/20260126110528_seed_user_initial_usernames.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/route_factory.rb +6 -7
- data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +1 -4
- data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +1 -3
- data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -2
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +0 -22
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +0 -4
- metadata +29 -38
- data/app/controllers/spree/api/v2/tenant/popular_route_places_controller.rb +0 -60
- data/app/controllers/spree/api/v2/tenant/routes_controller.rb +0 -50
- data/app/controllers/spree/api/v2/tenant/transit/draft_orders_controller.rb +0 -46
- data/app/finders/spree_cm_commissioner/route_metrics/find_popular.rb +0 -44
- data/app/finders/spree_cm_commissioner/routes/find.rb +0 -94
- data/app/jobs/spree_cm_commissioner/route_metrics/decrease_trip_count_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_fulfilled_order_count_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_order_count_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_trip_count_job.rb +0 -10
- data/app/models/spree_cm_commissioner/route_metric.rb +0 -21
- data/app/models/spree_cm_commissioner/route_photo.rb +0 -12
- data/app/serializers/spree/v2/tenant/transit_cart_serializer.rb +0 -11
- data/app/serializers/spree_cm_commissioner/v2/storefront/transit_line_item_serializer.rb +0 -17
- data/app/services/spree_cm_commissioner/route_metrics/decrease_trip_count.rb +0 -31
- data/app/services/spree_cm_commissioner/route_metrics/increase_trip_count.rb +0 -31
- data/app/services/spree_cm_commissioner/routes/create.rb +0 -51
- data/app/services/spree_cm_commissioner/routes/update.rb +0 -25
- data/app/services/spree_cm_commissioner/trips/create_single_leg.rb +0 -123
- data/app/services/spree_cm_commissioner/trips/service_calendars/create_or_update.rb +0 -54
- data/app/services/spree_cm_commissioner/trips/update_single_leg.rb +0 -88
- data/app/services/spree_cm_commissioner/trips/variants/create.rb +0 -103
- data/db/migrate/20251224033103_migrate_cm_routes_to_cm_route_metrics.rb +0 -17
- data/db/migrate/20251224033910_migrate_cm_vendor_routes_to_cm_routes.rb +0 -30
- data/db/migrate/20260105072450_migrate_cm_trip_stops_to_support_trip_connection.rb +0 -12
- data/db/migrate/20260108101406_add_allow_booking_to_cm_trips.rb +0 -5
- data/lib/spree_cm_commissioner/test_helper/factories/route_metric_factory.rb +0 -12
- data/lib/spree_cm_commissioner/test_helper/factories/route_photo_factory.rb +0 -5
- data/lib/spree_cm_commissioner/transit/route_stop.rb +0 -61
- data/lib/spree_cm_commissioner/transit/route_stop_collection.rb +0 -175
- data/lib/spree_cm_commissioner/transit/trip_form.rb +0 -81
- data/lib/spree_cm_commissioner/transit/trip_stop_form.rb +0 -61
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2ee953cf63ab26a979ddaa919500a3f7da95e812f8dc20557cb54411047821b6
|
|
4
|
+
data.tar.gz: bb72deade157e1dde753706bc7a9ad4dbfd329ebb0fc7290074983bdc3d17eca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e4db3651d96a7e492cc13d3755ba0ec2f8474f49cbe5918e1af02855dba9d74786feacf7215806f3fb744919a710378ff25551829319ec96740d1d42f3d19d02
|
|
7
|
+
data.tar.gz: 5f28bd001f3cc004058ccbdb253dd9b7614aa6ecdef0673da30ba03492abd900dfe3c48b2af18cfccd2c8f228c9753e0c9c3c51f896be6e13b5d6e23cc478c54
|
data/Gemfile.lock
CHANGED
|
@@ -27,32 +27,52 @@ module Spree
|
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def serialize_resource(guest)
|
|
31
|
+
guest_auto_payload(guest)
|
|
32
|
+
.merge(default_payload(guest))
|
|
33
|
+
.merge(dynamic_field_key_value(guest))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# In API Response eg: "field_17": "chhunlin", "field_18": "on",......
|
|
30
39
|
def dynamic_field_key_value(guest)
|
|
31
40
|
guest.guest_dynamic_fields
|
|
32
41
|
.includes(:dynamic_field)
|
|
33
42
|
.to_h do |gdf|
|
|
34
|
-
|
|
35
|
-
.parameterize
|
|
36
|
-
.underscore
|
|
43
|
+
label = "field_#{gdf.dynamic_field.id}"
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
value = gdf.value.strip
|
|
46
|
+
|
|
47
|
+
[label, value]
|
|
39
48
|
end
|
|
40
49
|
end
|
|
41
50
|
|
|
42
|
-
|
|
51
|
+
EXCLUDED_GUEST_COLUMNS = %w[
|
|
52
|
+
id created_at updated_at occupation_id event_id nationality_id
|
|
53
|
+
preferences upload_later social_contact_platform user_id
|
|
54
|
+
bib_number bib_prefix bib_index public_metadata private_metadata
|
|
55
|
+
seat_number intel_phone_number block_id saved_guest_id
|
|
56
|
+
data_fill_stage_phase
|
|
57
|
+
].freeze
|
|
58
|
+
|
|
59
|
+
def guest_base_columns
|
|
60
|
+
SpreeCmCommissioner::Guest.column_names - EXCLUDED_GUEST_COLUMNS
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def guest_auto_payload(guest)
|
|
64
|
+
guest_base_columns.index_with do |column|
|
|
65
|
+
guest.public_send(column)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def default_payload(guest) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
43
70
|
order = guest.line_item.order
|
|
44
71
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
last_name: guest.last_name,
|
|
49
|
-
dob: guest.dob,
|
|
50
|
-
gender: guest.gender,
|
|
51
|
-
age: guest.age,
|
|
72
|
+
{
|
|
73
|
+
guest_nationality: guest.nationality&.name,
|
|
74
|
+
guest_id_card_type: guest.id_card&.card_type,
|
|
52
75
|
occupation: guest.occupation&.name || guest.other_occupation,
|
|
53
|
-
entry_type: guest.entry_type,
|
|
54
|
-
organization: guest.other_organization,
|
|
55
|
-
expectation: guest.expectation,
|
|
56
76
|
telegram_user_id: guest.preferred_telegram_user_id,
|
|
57
77
|
telegram_user_verified_at: guest.preferred_telegram_user_verified_at,
|
|
58
78
|
order_number: order.number,
|
|
@@ -63,13 +83,10 @@ module Spree
|
|
|
63
83
|
checked_in_at: guest.earliest_check_in&.created_at,
|
|
64
84
|
qr_data: guest.qr_data,
|
|
65
85
|
order_qr_data: order.qr_data,
|
|
66
|
-
country_code: guest.country_code,
|
|
67
|
-
line_item_id: guest.line_item_id,
|
|
68
86
|
order_token: order.token,
|
|
69
|
-
bib: guest.formatted_bib_number
|
|
87
|
+
bib: guest.formatted_bib_number,
|
|
88
|
+
line_item_option_text: guest.line_item&.options_text
|
|
70
89
|
}
|
|
71
|
-
|
|
72
|
-
base_payload.merge(dynamic_field_key_value(guest))
|
|
73
90
|
end
|
|
74
91
|
end
|
|
75
92
|
end
|
|
@@ -8,6 +8,15 @@ module Spree
|
|
|
8
8
|
def create
|
|
9
9
|
spree_authorize! :create, model_class
|
|
10
10
|
|
|
11
|
+
# Optional QR data from a scanned user QR code.
|
|
12
|
+
# - If provided, the system will validate the QR data before check-in.
|
|
13
|
+
# - If omitted, check-in proceeds normally (e.g. manual search by operator).
|
|
14
|
+
# This is only for validating scanned QR codes; operators can always check in guests without it.
|
|
15
|
+
if params[:scanned_user_qr_data].present?
|
|
16
|
+
result = SpreeCmCommissioner::Users::QrData::Verify.call(qr_data: params[:scanned_user_qr_data])
|
|
17
|
+
return render_error_payload(result.error) if result.failure?
|
|
18
|
+
end
|
|
19
|
+
|
|
11
20
|
check_ins = []
|
|
12
21
|
|
|
13
22
|
if params[:check_ins].present?
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Storefront
|
|
5
|
+
module Account
|
|
6
|
+
class QrDataController < ::Spree::Api::V2::ResourceController
|
|
7
|
+
before_action :require_spree_current_user
|
|
8
|
+
|
|
9
|
+
# override
|
|
10
|
+
# invalidate existing QR data and return new QR data with user info.
|
|
11
|
+
def update
|
|
12
|
+
result = SpreeCmCommissioner::Users::QrData::Invalidate.call(user: spree_current_user)
|
|
13
|
+
|
|
14
|
+
if result.success?
|
|
15
|
+
render_serialized_payload { serialize_resource(result.value) }
|
|
16
|
+
else
|
|
17
|
+
render_error_payload(result.error)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# override
|
|
22
|
+
def resource_serializer
|
|
23
|
+
Spree::V2::Storefront::UserSerializer
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -15,7 +15,7 @@ module Spree
|
|
|
15
15
|
@outbound_legs = params[:outbound_legs].is_a?(Array) && params[:outbound_legs].any? ? build_legs(:outbound, params[:outbound_legs]) : []
|
|
16
16
|
@inbound_legs = params[:inbound_legs].is_a?(Array) && params[:inbound_legs].any? ? build_legs(:inbound, params[:inbound_legs]) : []
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
context = SpreeCmCommissioner::Transit::DraftOrderCreator.call(
|
|
19
19
|
outbound_date: params[:outbound_date]&.to_date,
|
|
20
20
|
inbound_date: params[:inbound_date]&.to_date,
|
|
21
21
|
outbound_legs: @outbound_legs,
|
|
@@ -23,10 +23,10 @@ module Spree
|
|
|
23
23
|
user: spree_current_user
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
-
if
|
|
27
|
-
render_serialized_payload { serialize_resource(
|
|
26
|
+
if context.success?
|
|
27
|
+
render_serialized_payload { serialize_resource(context.order) }
|
|
28
28
|
else
|
|
29
|
-
render_error_payload(
|
|
29
|
+
render_error_payload(context.message)
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -48,13 +48,13 @@ module Spree
|
|
|
48
48
|
boarding_points_attributes = (cm_params.delete('boarding_points') || []).compact_blank
|
|
49
49
|
.map do |point_id|
|
|
50
50
|
trip_stop = trip_stops.delete(point_id.to_i)
|
|
51
|
-
{ stop_id: point_id,
|
|
51
|
+
{ stop_id: point_id, stop_type: 'boarding', id: trip_stop.try(:id) }
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
drop_off_points_attributes = (cm_params.delete('drop_off_points') || []).compact_blank
|
|
55
55
|
.map do |point_id|
|
|
56
56
|
trip_stop = trip_stops.delete(point_id.to_i)
|
|
57
|
-
{ stop_id: point_id,
|
|
57
|
+
{ stop_id: point_id, stop_type: 'drop_off', id: trip_stop.try(:id) }
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
trip_stops.each_value do |trip_stop|
|
|
@@ -74,7 +74,7 @@ module Spree
|
|
|
74
74
|
:origin_id, :destination_id, :vehicle_id, :hours, :minutes, :seconds,
|
|
75
75
|
'departure_time(1i)', 'departure_time(2i)', 'departure_time(3i)',
|
|
76
76
|
'departure_time(4i)', 'departure_time(5i)', :product_id,
|
|
77
|
-
trip_stops_attributes: %i[stop_id
|
|
77
|
+
trip_stops_attributes: %i[stop_id stop_type _destroy id]
|
|
78
78
|
)
|
|
79
79
|
end
|
|
80
80
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
# Finds places connected via
|
|
1
|
+
# Finds places connected via routes with optional filtering.
|
|
2
2
|
#
|
|
3
3
|
# @param place_type [String] Required. 'origin' or 'destination'
|
|
4
4
|
# @param place_id [Integer] Optional. Filter by connected place ID
|
|
5
5
|
# @param query [String] Optional. Filter by place name (case-insensitive)
|
|
6
|
-
# @param route_type [Symbol, String] Optional. Filter by route type from
|
|
6
|
+
# @param route_type [Symbol, String] Optional. Filter by route type from associated trips (e.g., :ferry, :bus)
|
|
7
7
|
#
|
|
8
8
|
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Place>]
|
|
9
9
|
#
|
|
10
10
|
# Modes:
|
|
11
11
|
# - place_id only: returns connected places (origins TO or destinations FROM given place)
|
|
12
12
|
# - query only: filters by name
|
|
13
|
-
# - route_type only: filters by route
|
|
13
|
+
# - route_type only: filters by trip route types on those routes
|
|
14
14
|
# - combinations: connected places filtered by name and/or route type
|
|
15
|
-
# - neither: all origins/destinations in
|
|
15
|
+
# - neither: all origins/destinations in routes
|
|
16
16
|
#
|
|
17
|
-
# @example Origins with ferry
|
|
17
|
+
# @example Origins with ferry trips to place 123
|
|
18
18
|
# FindWithRoute.new(place_type: 'origin', place_id: 123, route_type: :ferry).execute
|
|
19
19
|
#
|
|
20
20
|
# @example Destinations filtered by query and route type
|
|
@@ -46,14 +46,14 @@ module SpreeCmCommissioner
|
|
|
46
46
|
def scope
|
|
47
47
|
return SpreeCmCommissioner::Place.none unless valid_place_type?
|
|
48
48
|
|
|
49
|
-
base_scope = origin? ? SpreeCmCommissioner::Place.
|
|
49
|
+
base_scope = origin? ? SpreeCmCommissioner::Place.with_routes_as_origin : SpreeCmCommissioner::Place.with_routes_as_destination
|
|
50
50
|
|
|
51
51
|
return base_scope if place_id.blank?
|
|
52
52
|
|
|
53
53
|
if origin?
|
|
54
|
-
base_scope.where(
|
|
54
|
+
base_scope.where(routes_as_origin: { destination_place_id: place_id })
|
|
55
55
|
else
|
|
56
|
-
base_scope.where(
|
|
56
|
+
base_scope.where(routes_as_destination: { origin_place_id: place_id })
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -62,10 +62,10 @@ module SpreeCmCommissioner
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def apply_route_type_filter(result)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
trips_association = origin? ? :trips_as_origin : :trips_as_destination
|
|
66
|
+
result.joins(trips_association)
|
|
67
|
+
.where(cm_trips: { route_type: route_type.to_sym })
|
|
68
|
+
.distinct
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def origin?
|
|
@@ -1,31 +1,46 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
1
|
+
# Finds routes ordered by popularity based on order metrics.
|
|
2
|
+
#
|
|
3
|
+
# Routes are sorted by:
|
|
4
|
+
# 1. fulfilled_order_count (completed orders) - DESC
|
|
5
|
+
# 2. order_count (total orders including incomplete) - DESC
|
|
6
|
+
#
|
|
7
|
+
# @param route_type [Symbol, String] Optional. Filter by route type from associated trips (e.g., :ferry, :bus)
|
|
8
|
+
#
|
|
9
|
+
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Route>] Routes with origin and destination places loaded,
|
|
10
|
+
# ordered from most to least popular
|
|
11
|
+
#
|
|
12
|
+
# @example Get all popular routes
|
|
13
|
+
# finder = SpreeCmCommissioner::Routes::FindPopular.new
|
|
14
|
+
# finder.execute # => Returns all routes sorted by fulfillment and order counts
|
|
15
|
+
#
|
|
16
|
+
# @example Get popular ferry routes
|
|
17
|
+
# finder = SpreeCmCommissioner::Routes::FindPopular.new
|
|
18
|
+
# finder.execute(route_type: :ferry) # => Returns ferry routes sorted by popularity
|
|
19
|
+
#
|
|
20
|
+
# @example Get popular bus routes
|
|
21
|
+
# finder = SpreeCmCommissioner::Routes::FindPopular.new
|
|
22
|
+
# finder.execute(route_type: :bus) # => Returns bus routes sorted by popularity
|
|
6
23
|
|
|
7
24
|
module SpreeCmCommissioner
|
|
8
25
|
module Routes
|
|
9
26
|
class FindPopular
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
@tenant = tenant
|
|
13
|
-
@route_type = route_type
|
|
14
|
-
@limit = limit.to_i
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def execute
|
|
18
|
-
scope = SpreeCmCommissioner::Route.includes(:origin_place, :destination_place, :route_photos)
|
|
19
|
-
scope = scope.where(vendor_id: vendor.id) if vendor.present?
|
|
20
|
-
scope = scope.where(tenant_id: tenant.id) if tenant.present?
|
|
21
|
-
scope = scope.where(route_type: route_type.to_sym) if route_type.present?
|
|
22
|
-
scope.order(fulfilled_order_count: :desc, order_count: :desc)
|
|
23
|
-
.limit(limit)
|
|
27
|
+
def execute(route_type: nil, query: nil)
|
|
28
|
+
scope(route_type: route_type, query: query)
|
|
24
29
|
end
|
|
25
30
|
|
|
26
31
|
private
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
def scope(route_type:, query:)
|
|
34
|
+
includes_associations = %i[origin_place destination_place]
|
|
35
|
+
includes_associations << :trips if route_type.present?
|
|
36
|
+
result = SpreeCmCommissioner::Route.includes(*includes_associations)
|
|
37
|
+
|
|
38
|
+
result = result.joins(:trips).where(cm_trips: { route_type: route_type.to_sym }) if route_type.present?
|
|
39
|
+
|
|
40
|
+
result = result.where('cm_routes.route_name ILIKE ?', "%#{query}%") if query.present?
|
|
41
|
+
|
|
42
|
+
result.distinct.order(fulfilled_order_count: :desc, order_count: :desc)
|
|
43
|
+
end
|
|
29
44
|
end
|
|
30
45
|
end
|
|
31
46
|
end
|
|
@@ -33,18 +33,11 @@ module SpreeCmCommissioner
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
# Returns dates for which inventory should be generated, based on calendar or default period.
|
|
37
36
|
def inventory_dates_for(variant)
|
|
38
|
-
|
|
37
|
+
start_date = Time.zone.tomorrow
|
|
38
|
+
end_date = Time.zone.today + pre_inventory_days_for(variant)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
calendar.start_date.upto(calendar.end_date).select { |date| calendar.service_available?(date) }
|
|
42
|
-
else
|
|
43
|
-
start_date = Time.zone.tomorrow
|
|
44
|
-
end_date = Time.zone.today + pre_inventory_days_for(variant)
|
|
45
|
-
|
|
46
|
-
start_date.upto(end_date).to_a
|
|
47
|
-
end
|
|
40
|
+
(start_date..end_date)
|
|
48
41
|
end
|
|
49
42
|
|
|
50
43
|
def inventory_exist?(variant, inventory_date)
|
|
@@ -75,7 +68,7 @@ module SpreeCmCommissioner
|
|
|
75
68
|
def variants
|
|
76
69
|
scope = Spree::Variant.active.with_permanent_stock.where(is_master: false)
|
|
77
70
|
scope = scope.where(id: variant_ids) if variant_ids.present?
|
|
78
|
-
scope
|
|
71
|
+
scope
|
|
79
72
|
end
|
|
80
73
|
end
|
|
81
74
|
end
|
|
@@ -8,8 +8,7 @@ module SpreeCmCommissioner
|
|
|
8
8
|
|
|
9
9
|
return context.fail!(message: Spree.t(:doesnt_track_inventory)) unless variant.track_inventory?
|
|
10
10
|
|
|
11
|
-
stock_location =
|
|
12
|
-
|
|
11
|
+
stock_location = Spree::StockLocation.find(stock_location_id)
|
|
13
12
|
stock_movement = stock_location.stock_movements.build(stock_movement_params)
|
|
14
13
|
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
|
|
15
14
|
|
|
@@ -23,14 +22,6 @@ module SpreeCmCommissioner
|
|
|
23
22
|
|
|
24
23
|
private
|
|
25
24
|
|
|
26
|
-
def resolve_stock_location(variant, stock_location_id = nil)
|
|
27
|
-
if stock_location_id.present?
|
|
28
|
-
Spree::StockLocation.find(stock_location_id)
|
|
29
|
-
else
|
|
30
|
-
variant.vendor.stock_locations.first || variant.vendor.send(:create_stock_location)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
25
|
def adjust_inventory_items_async(variant_id, quantity)
|
|
35
26
|
args = { variant_id: variant_id, quantity: quantity }
|
|
36
27
|
CmAppLogger.log(label: "#{self.class.name}#adjust_inventory_items_async", data: args) do
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DraftOrderCreator creates a new order for a entire journey, including outbound and (if present) inbound directions.
|
|
2
2
|
#
|
|
3
3
|
# Attributes:
|
|
4
4
|
# - outbound_date: [Date] The date of outbound transit
|
|
@@ -12,22 +12,25 @@
|
|
|
12
12
|
#
|
|
13
13
|
# Note: inbound_legs and inbound_date are optional; the order may represent a one-way (outbound only) journey.
|
|
14
14
|
module SpreeCmCommissioner
|
|
15
|
-
module
|
|
16
|
-
class
|
|
17
|
-
|
|
15
|
+
module Transit
|
|
16
|
+
class DraftOrderCreator < BaseInteractor
|
|
17
|
+
delegate :outbound_date,
|
|
18
|
+
:inbound_date,
|
|
19
|
+
:outbound_legs,
|
|
20
|
+
:inbound_legs,
|
|
21
|
+
:user, to: :context
|
|
18
22
|
|
|
19
|
-
def call
|
|
20
|
-
return
|
|
23
|
+
def call
|
|
24
|
+
return context.fail!(message: 'Outbound legs are missing') if outbound_legs.blank?
|
|
21
25
|
|
|
22
26
|
begin
|
|
23
|
-
order = create_order!
|
|
24
|
-
success(order: order)
|
|
27
|
+
context.order = create_order!
|
|
25
28
|
rescue StandardError => e
|
|
26
|
-
|
|
29
|
+
context.fail!(message: e.message)
|
|
27
30
|
end
|
|
28
31
|
end
|
|
29
32
|
|
|
30
|
-
def create_order!
|
|
33
|
+
def create_order!
|
|
31
34
|
order = Spree::Order.new(state: 'cart', use_billing: true, user: user)
|
|
32
35
|
|
|
33
36
|
outbound_line_items = build_line_items_for_legs!(order: order, legs: outbound_legs, initial_date: outbound_date)
|
|
@@ -109,10 +112,10 @@ module SpreeCmCommissioner
|
|
|
109
112
|
|
|
110
113
|
def insert_saved_guests_per_line_items_leg(line_items)
|
|
111
114
|
line_items.flat_map(&:guests).each_with_index do |guest, index|
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
context.saved_guests ||= []
|
|
116
|
+
context.saved_guests << SpreeCmCommissioner::SavedGuest.new if context.saved_guests[index].blank?
|
|
114
117
|
|
|
115
|
-
guest.saved_guest =
|
|
118
|
+
guest.saved_guest = context.saved_guests[index]
|
|
116
119
|
end
|
|
117
120
|
|
|
118
121
|
line_items
|
|
@@ -91,10 +91,9 @@ module SpreeCmCommissioner
|
|
|
91
91
|
stop_params = params.dig(:trip_stops_attributes, index.to_s)
|
|
92
92
|
return unless stop_params
|
|
93
93
|
|
|
94
|
-
cloned_stop.departure_time
|
|
95
|
-
cloned_stop.arrival_time
|
|
96
|
-
cloned_stop.
|
|
97
|
-
cloned_stop.allow_drop_off = stop_params[:allow_drop_off] if stop_params.key?(:allow_drop_off)
|
|
94
|
+
cloned_stop.departure_time = parse_time(stop_params[:departure_time])
|
|
95
|
+
cloned_stop.arrival_time = parse_time(stop_params[:arrival_time])
|
|
96
|
+
cloned_stop.stop_type = stop_params[:stop_type].presence
|
|
98
97
|
cloned_stop.location_place_id = stop_params[:location_place_id].presence
|
|
99
98
|
end
|
|
100
99
|
|
|
@@ -26,7 +26,7 @@ module SpreeCmCommissioner
|
|
|
26
26
|
trip: trip,
|
|
27
27
|
stop_place: origin_place,
|
|
28
28
|
location_place: origin_place,
|
|
29
|
-
|
|
29
|
+
stop_type: :boarding
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
attributes[:departure_time] = departure_time
|
|
@@ -42,7 +42,7 @@ module SpreeCmCommissioner
|
|
|
42
42
|
trip: trip,
|
|
43
43
|
stop_place: destination_place,
|
|
44
44
|
location_place: destination_place,
|
|
45
|
-
|
|
45
|
+
stop_type: :drop_off
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
attributes[:arrival_time] = departure_time + duration_seconds.seconds
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module SpreeCmCommissioner
|
|
2
2
|
module Stock
|
|
3
3
|
class PermanentInventoryItemsGeneratorJob < ApplicationUniqueJob
|
|
4
|
-
def perform
|
|
5
|
-
SpreeCmCommissioner::Stock::PermanentInventoryItemsGenerator.call
|
|
4
|
+
def perform
|
|
5
|
+
SpreeCmCommissioner::Stock::PermanentInventoryItemsGenerator.call
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteFulfilledOrderCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
order = Spree::Order.find(options[:order_id])
|
|
6
|
+
SpreeCmCommissioner::Routes::IncrementFulfilledOrderCount.call(order: order)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteOrderCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
order = Spree::Order.find(options[:order_id])
|
|
6
|
+
SpreeCmCommissioner::Routes::IncrementOrderCount.call(order: order)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Perform the previous-route decrement outside the Trip transaction.
|
|
2
|
+
|
|
3
|
+
module SpreeCmCommissioner
|
|
4
|
+
module Transit
|
|
5
|
+
class RoutePreviousTripCountDecrementerJob < ApplicationUniqueJob
|
|
6
|
+
queue_as :default
|
|
7
|
+
|
|
8
|
+
def perform(options = {})
|
|
9
|
+
SpreeCmCommissioner::Routes::DecrementPreviousTripCount.call(previous_route_id: options[:previous_route_id])
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteTripCountDecrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
trip = SpreeCmCommissioner::Trip.find(options[:trip_id])
|
|
6
|
+
SpreeCmCommissioner::Routes::DecrementTripCount.call(trip: trip)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteTripCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
trip = SpreeCmCommissioner::Trip.find(options[:trip_id])
|
|
6
|
+
SpreeCmCommissioner::Routes::IncrementTripCount.call(trip: trip)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -9,7 +9,7 @@ module SpreeCmCommissioner
|
|
|
9
9
|
state_machine.before_transition to: :payment, do: :ensure_blocks_held
|
|
10
10
|
|
|
11
11
|
state_machine.before_transition to: :complete, do: :request, if: :need_confirmation?
|
|
12
|
-
state_machine.before_transition to: :complete, do: :
|
|
12
|
+
state_machine.before_transition to: :complete, do: :finalize_guests_and_bibs
|
|
13
13
|
state_machine.before_transition to: :complete, do: :generate_completion_steps!, if: :product_completion_steps_exist?
|
|
14
14
|
|
|
15
15
|
state_machine.after_transition to: :complete, do: :precalculate_conversion
|
|
@@ -168,21 +168,26 @@ module SpreeCmCommissioner
|
|
|
168
168
|
end
|
|
169
169
|
end
|
|
170
170
|
|
|
171
|
-
def
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
line_item.guests.none_bib.each do |guest|
|
|
176
|
-
guest.generate_bib
|
|
177
|
-
next if guest.save
|
|
171
|
+
def finalize_guests_and_bibs
|
|
172
|
+
ActiveRecord::Base.transaction do
|
|
173
|
+
line_items.each do |line_item|
|
|
174
|
+
line_item.generate_remaining_guests
|
|
178
175
|
|
|
179
|
-
|
|
180
|
-
|
|
176
|
+
line_item.guests.each do |guest|
|
|
177
|
+
guest.user = user if user.present?
|
|
178
|
+
guest.generate_bib_if_needed
|
|
179
|
+
guest.save!
|
|
181
180
|
end
|
|
182
181
|
end
|
|
183
182
|
end
|
|
184
183
|
|
|
185
|
-
|
|
184
|
+
true
|
|
185
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
186
|
+
e.record.errors.each do |msg|
|
|
187
|
+
errors.add(:guests, msg)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
false
|
|
186
191
|
end
|
|
187
192
|
|
|
188
193
|
def rejected_by(user)
|
|
@@ -7,13 +7,13 @@ module SpreeCmCommissioner
|
|
|
7
7
|
def increment_route_fulfilled_order_count
|
|
8
8
|
return unless has_trip_ids?
|
|
9
9
|
|
|
10
|
-
SpreeCmCommissioner::
|
|
10
|
+
SpreeCmCommissioner::Transit::RouteFulfilledOrderCountIncrementerJob.perform_later(order_id: id)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def increment_route_order_count
|
|
14
14
|
return unless has_trip_ids?
|
|
15
15
|
|
|
16
|
-
SpreeCmCommissioner::
|
|
16
|
+
SpreeCmCommissioner::Transit::RouteOrderCountIncrementerJob.perform_later(order_id: id)
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|