spree_cm_commissioner 2.5.1 → 2.5.2.pre.pre1
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/.github/workflows/test_and_build_gem.yml +2 -2
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/admin/inventory_items_controller.rb +36 -56
- data/app/controllers/spree/admin/stock_managements_controller.rb +14 -3
- data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/transit/draft_orders_controller.rb +4 -4
- data/app/controllers/spree/api/v2/tenant/popular_route_places_controller.rb +60 -0
- data/app/controllers/spree/api/v2/tenant/routes_controller.rb +50 -0
- data/app/controllers/spree/api/v2/tenant/transit/draft_orders_controller.rb +46 -0
- 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/route_metrics/find_popular.rb +44 -0
- data/app/finders/spree_cm_commissioner/routes/find.rb +94 -0
- data/app/finders/spree_cm_commissioner/routes/find_popular.rb +19 -35
- data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +11 -4
- data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +10 -1
- data/app/interactors/spree_cm_commissioner/trip_clone_creator.rb +4 -3
- data/app/interactors/spree_cm_commissioner/trip_stops_creator.rb +2 -2
- data/app/jobs/spree_cm_commissioner/route_metrics/decrease_trip_count_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_fulfilled_order_count_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_order_count_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_trip_count_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +2 -2
- data/app/models/concerns/spree_cm_commissioner/route_order_countable.rb +2 -2
- data/app/models/spree_cm_commissioner/place.rb +5 -8
- data/app/models/spree_cm_commissioner/product_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/route.rb +45 -5
- data/app/models/spree_cm_commissioner/route_metric.rb +21 -0
- data/app/models/spree_cm_commissioner/route_photo.rb +12 -0
- data/app/models/spree_cm_commissioner/trip.rb +8 -33
- data/app/models/spree_cm_commissioner/trip_stop.rb +16 -2
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +3 -1
- data/app/queries/spree_cm_commissioner/trip_query.rb +2 -2
- data/app/serializers/spree/v2/tenant/transit_cart_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_metric_serializer.rb +13 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_serializer.rb +2 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/transit_line_item_serializer.rb +17 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_stop_serializer.rb +1 -1
- data/app/services/spree_cm_commissioner/route_metrics/decrease_trip_count.rb +31 -0
- data/app/services/spree_cm_commissioner/{routes/increment_fulfilled_order_count.rb → route_metrics/increase_fulfilled_order_count.rb} +3 -3
- data/app/services/spree_cm_commissioner/{routes/increment_order_count.rb → route_metrics/increase_order_count.rb} +3 -3
- data/app/services/spree_cm_commissioner/route_metrics/increase_trip_count.rb +31 -0
- data/app/services/spree_cm_commissioner/{routes/base_update_order_metrics.rb → route_metrics/update_route_metrics.rb} +11 -16
- data/app/services/spree_cm_commissioner/routes/create.rb +51 -0
- data/app/services/spree_cm_commissioner/routes/update.rb +25 -0
- data/app/{interactors/spree_cm_commissioner/transit/draft_order_creator.rb → services/spree_cm_commissioner/transit_order/create.rb} +13 -16
- data/app/services/spree_cm_commissioner/trips/create_single_leg.rb +123 -0
- data/app/services/spree_cm_commissioner/trips/service_calendars/create_or_update.rb +54 -0
- data/app/services/spree_cm_commissioner/trips/update_single_leg.rb +88 -0
- data/app/services/spree_cm_commissioner/trips/variants/create.rb +103 -0
- data/app/views/spree/admin/inventory_items/prices.html.erb +45 -0
- data/app/views/spree/admin/inventory_items/stocks.html.erb +36 -0
- data/app/views/spree/admin/stock_managements/calendar.html.erb +105 -12
- data/app/views/spree/admin/stock_managements/index.html.erb +9 -8
- data/app/views/spree/transit/trip_stops/index.html.erb +4 -2
- data/app/views/spree_cm_commissioner/guest_mailer/send_ticket_to_guest.html.erb +0 -1
- data/config/initializers/spree_permitted_attributes.rb +11 -0
- data/config/routes.rb +12 -7
- data/db/migrate/20251224033103_migrate_cm_routes_to_cm_route_metrics.rb +17 -0
- data/db/migrate/20251224033910_migrate_cm_vendor_routes_to_cm_routes.rb +30 -0
- data/db/migrate/20260105072450_migrate_cm_trip_stops_to_support_trip_connection.rb +12 -0
- data/db/migrate/20260108101406_add_allow_booking_to_cm_trips.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/route_factory.rb +7 -6
- data/lib/spree_cm_commissioner/test_helper/factories/route_metric_factory.rb +12 -0
- data/lib/spree_cm_commissioner/test_helper/factories/route_photo_factory.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +4 -1
- data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +3 -1
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +2 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +22 -0
- data/lib/spree_cm_commissioner/transit/route_stop.rb +61 -0
- data/lib/spree_cm_commissioner/transit/route_stop_collection.rb +175 -0
- data/lib/spree_cm_commissioner/transit/trip_form.rb +81 -0
- data/lib/spree_cm_commissioner/transit/trip_stop_form.rb +65 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +4 -0
- metadata +42 -21
- data/app/jobs/spree_cm_commissioner/transit/route_fulfilled_order_count_incrementer_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/transit/route_order_count_incrementer_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/transit/route_previous_trip_count_decrementer_job.rb +0 -13
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_decrementer_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_incrementer_job.rb +0 -10
- data/app/models/concerns/spree_cm_commissioner/route_trip_count_callbacks.rb +0 -48
- data/app/models/spree_cm_commissioner/trip_connection.rb +0 -36
- data/app/models/spree_cm_commissioner/vendor_route.rb +0 -9
- data/app/services/spree_cm_commissioner/routes/decrement_previous_trip_count.rb +0 -30
- data/app/services/spree_cm_commissioner/routes/decrement_trip_count.rb +0 -33
- data/app/services/spree_cm_commissioner/routes/increment_trip_count.rb +0 -33
- data/app/views/spree/admin/inventory_items/show.html.erb +0 -72
- data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +0 -6
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module RouteTripCountCallbacks
|
|
3
|
-
extend ActiveSupport::Concern
|
|
4
|
-
|
|
5
|
-
included do
|
|
6
|
-
after_create :increase_trip_count
|
|
7
|
-
before_destroy :decrease_trip_count
|
|
8
|
-
|
|
9
|
-
# When route context may change, enqueue an async job after commit that
|
|
10
|
-
# reads the previous values from `previous_changes` to decrement counts
|
|
11
|
-
# on the old route/vendor. This avoids keeping in-memory state and keeps
|
|
12
|
-
# the Trip update fast.
|
|
13
|
-
after_commit :enqueue_decrement_previous_route_trip_counts, on: :update
|
|
14
|
-
|
|
15
|
-
after_commit :increment_new_route_trip_counts, on: :update, if: :changed_route_context?
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
def decrease_trip_count
|
|
21
|
-
SpreeCmCommissioner::Transit::RouteTripCountDecrementerJob.perform_now(trip_id: id)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def increase_trip_count
|
|
25
|
-
SpreeCmCommissioner::Transit::RouteTripCountIncrementerJob.perform_later(trip_id: id)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Read previous_changes to find prior route context and enqueue the job.
|
|
29
|
-
def enqueue_decrement_previous_route_trip_counts
|
|
30
|
-
prev_route_id = previous_changes['route_id']&.first
|
|
31
|
-
prev_origin_id = previous_changes['origin_place_id']&.first
|
|
32
|
-
prev_destination_id = previous_changes['destination_place_id']&.first
|
|
33
|
-
|
|
34
|
-
return unless prev_route_id.present? && prev_origin_id.present? && prev_destination_id.present?
|
|
35
|
-
|
|
36
|
-
SpreeCmCommissioner::Transit::RoutePreviousTripCountDecrementerJob.perform_later(
|
|
37
|
-
previous_route_id: prev_route_id
|
|
38
|
-
)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Safely increment the trip_count for the trip's (new) route after update.
|
|
42
|
-
def increment_new_route_trip_counts
|
|
43
|
-
return if origin_place_id.blank? || destination_place_id.blank? || route_id.blank?
|
|
44
|
-
|
|
45
|
-
SpreeCmCommissioner::Transit::RouteTripCountIncrementerJob.perform_later(trip_id: id)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class TripConnection < Base
|
|
3
|
-
belongs_to :from_trip, class_name: 'SpreeCmCommissioner::Trip'
|
|
4
|
-
belongs_to :to_trip, class_name: 'SpreeCmCommissioner::Trip'
|
|
5
|
-
|
|
6
|
-
validate :both_trip_cannot_be_the_same
|
|
7
|
-
before_validation :calculate_connection_time_minutes
|
|
8
|
-
validates :from_trip_id, uniqueness: { scope: :to_trip_id }
|
|
9
|
-
|
|
10
|
-
private
|
|
11
|
-
|
|
12
|
-
def calculate_connection_time_minutes
|
|
13
|
-
return if from_trip.nil? || to_trip.nil?
|
|
14
|
-
|
|
15
|
-
arrival_seconds = from_trip.arrival_time.seconds_since_midnight
|
|
16
|
-
departure_seconds = to_trip.departure_time.seconds_since_midnight
|
|
17
|
-
|
|
18
|
-
layover_seconds = departure_seconds - arrival_seconds
|
|
19
|
-
layover_seconds += 86_400 if layover_seconds.negative?
|
|
20
|
-
|
|
21
|
-
connection_time_in_minutes = layover_seconds / 60
|
|
22
|
-
|
|
23
|
-
if connection_time_in_minutes.between?(0, 180)
|
|
24
|
-
self.connection_time_minutes = connection_time_in_minutes.to_i
|
|
25
|
-
else
|
|
26
|
-
errors.add(:base, 'Connection time must be less than 3 hours')
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def both_trip_cannot_be_the_same
|
|
31
|
-
return unless from_trip.id == to_trip.id
|
|
32
|
-
|
|
33
|
-
errors.add(:base, 'Both trip cannot be the same')
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class VendorRoute < Base
|
|
3
|
-
belongs_to :vendor, class_name: 'Spree::Vendor', optional: false
|
|
4
|
-
belongs_to :route, class_name: 'SpreeCmCommissioner::Route', optional: false
|
|
5
|
-
|
|
6
|
-
has_many :trips, -> (vr) { where(vendor_id: vr.vendor_id, route_id: vr.route_id) }, class_name: 'SpreeCmCommissioner::Trip'
|
|
7
|
-
validates :vendor_id, uniqueness: { scope: :route_id }
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module Routes
|
|
3
|
-
class DecrementPreviousTripCount
|
|
4
|
-
prepend ::Spree::ServiceModule::Base
|
|
5
|
-
|
|
6
|
-
def call(previous_route_id:)
|
|
7
|
-
previous_route = SpreeCmCommissioner::Route.find_by(id: previous_route_id)
|
|
8
|
-
return failure(nil, 'Route not found') unless previous_route
|
|
9
|
-
|
|
10
|
-
if previous_route.vendors.exists?
|
|
11
|
-
|
|
12
|
-
# Build a trip-like object that responds to :route and :vendor so the delegated
|
|
13
|
-
# service can locate vendor routes correctly.
|
|
14
|
-
trip_like = Struct.new(:route, :vendor).new(previous_route, previous_route.vendors.first)
|
|
15
|
-
result = SpreeCmCommissioner::Routes::DecrementTripCount.call(trip: trip_like)
|
|
16
|
-
return result if result.failure?
|
|
17
|
-
else
|
|
18
|
-
previous_route.with_lock do
|
|
19
|
-
new_count = [previous_route.trip_count.to_i - 1, 0].max
|
|
20
|
-
previous_route.update!(trip_count: new_count)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
success(previous_route: previous_route)
|
|
25
|
-
rescue StandardError => e
|
|
26
|
-
failure(nil, e.message)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module Routes
|
|
3
|
-
class DecrementTripCount
|
|
4
|
-
prepend ::Spree::ServiceModule::Base
|
|
5
|
-
|
|
6
|
-
def call(trip:)
|
|
7
|
-
return failure(nil, 'Trip not found') unless trip
|
|
8
|
-
|
|
9
|
-
vendor = trip.vendor
|
|
10
|
-
return failure(nil, 'Vendor not found') unless vendor
|
|
11
|
-
|
|
12
|
-
ActiveRecord::Base.transaction do
|
|
13
|
-
route = trip.route
|
|
14
|
-
|
|
15
|
-
route.update!(trip_count: [route.trip_count - 1, 0].max)
|
|
16
|
-
|
|
17
|
-
vendor_route = locate_vendor_route(vendor: vendor, route: route)
|
|
18
|
-
vendor_route&.update!(trip_count: [vendor_route.trip_count - 1, 0].max)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
success(trip: trip)
|
|
22
|
-
rescue StandardError => e
|
|
23
|
-
failure(nil, e.message)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def locate_vendor_route(vendor:, route:)
|
|
29
|
-
vendor.vendor_routes.find_by(route_id: route.id)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module Routes
|
|
3
|
-
class IncrementTripCount
|
|
4
|
-
prepend ::Spree::ServiceModule::Base
|
|
5
|
-
|
|
6
|
-
def call(trip:)
|
|
7
|
-
return failure(nil, 'Trip not found') unless trip
|
|
8
|
-
|
|
9
|
-
vendor = trip.vendor
|
|
10
|
-
return failure(nil, 'Vendor not found') unless vendor
|
|
11
|
-
|
|
12
|
-
ActiveRecord::Base.transaction do
|
|
13
|
-
route = trip.route
|
|
14
|
-
|
|
15
|
-
route.update!(trip_count: route.trip_count + 1)
|
|
16
|
-
|
|
17
|
-
vendor_route = find_or_create_vendor_route(vendor: vendor, route: route)
|
|
18
|
-
vendor_route.update!(trip_count: vendor_route.trip_count + 1)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
success(trip: trip)
|
|
22
|
-
rescue StandardError => e
|
|
23
|
-
failure(nil, e.message)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def find_or_create_vendor_route(vendor:, route:)
|
|
29
|
-
vendor.vendor_routes.find_or_create_by!(route_id: route.id)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
<%= turbo_frame_tag "inventory_item" do %>
|
|
2
|
-
<div>
|
|
3
|
-
<h5 class="modal-title">Inventory</h5>
|
|
4
|
-
<p>
|
|
5
|
-
<% if @inventory_item.inventory_date.present? %>
|
|
6
|
-
<span><%= @inventory_item.inventory_date %></span><br>
|
|
7
|
-
<% end %>
|
|
8
|
-
<%= @inventory_item.variant.options_text %>
|
|
9
|
-
</p>
|
|
10
|
-
|
|
11
|
-
<ul class="list-group mb-1">
|
|
12
|
-
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
13
|
-
Max capacity
|
|
14
|
-
<span class="badge badge-primary badge-pill"><%= @inventory_item.max_capacity %></span>
|
|
15
|
-
</li>
|
|
16
|
-
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
17
|
-
Quantity available
|
|
18
|
-
<span class="badge badge-primary badge-pill"><%= @inventory_item.quantity_available %></span>
|
|
19
|
-
</li>
|
|
20
|
-
</ul>
|
|
21
|
-
|
|
22
|
-
<small class="text-muted">
|
|
23
|
-
<%= inventory_item_message(@inventory_item, @cached_inventory_item) %>
|
|
24
|
-
</small>
|
|
25
|
-
|
|
26
|
-
<%= link_to_with_icon('arrow-counterclockwise.svg', "Reset Inventory Item", reset_admin_product_variant_inventory_item_path(@product, @inventory_item.variant_id, @inventory_item.id),
|
|
27
|
-
method: :patch,
|
|
28
|
-
remote: false,
|
|
29
|
-
class: 'icon_link btn btn-sm outline text-dark',
|
|
30
|
-
data: { confirm: "Only reset if stock is incorrect. Are you sure?" }, no_text: true
|
|
31
|
-
) %>
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
<hr />
|
|
35
|
-
|
|
36
|
-
<div class="mt-2">
|
|
37
|
-
<h6 class="modal-title mb-1 d-flex flex-row justify-content-between">
|
|
38
|
-
Custom Prices
|
|
39
|
-
<%= link_to_with_icon('delete.svg', Spree.t(:remove),
|
|
40
|
-
delete_prices_admin_product_variant_inventory_item_path(@product, @inventory_item.variant_id, @inventory_item.id),
|
|
41
|
-
method: :delete, remote: false, class: 'icon_link btn btn-sm text-danger', data: { action: :remove, confirm: "Are you sure to remove these prices & use base price?" }, no_text: true
|
|
42
|
-
) if @prices.any?(&:persisted?) %>
|
|
43
|
-
</h6>
|
|
44
|
-
|
|
45
|
-
<%= form_with url: update_prices_admin_product_variant_inventory_item_path(@product, @inventory_item.variant_id, @inventory_item.id), method: :patch, local: true, html: { class: 'inventory-item-prices-form' } do |form| %>
|
|
46
|
-
<table class="table">
|
|
47
|
-
<tbody>
|
|
48
|
-
<% @prices.each do |price| %>
|
|
49
|
-
<% currency = price.currency %>
|
|
50
|
-
<% default_price = @default_prices[currency] || Spree::Price.new %>
|
|
51
|
-
<tr id="inventory-item_prices_row_<%= currency %>" data-hook="inventory-item_prices_row">
|
|
52
|
-
<td><%= form.label "price_#{currency}", currency, class: 'form-label' %></td>
|
|
53
|
-
<td>
|
|
54
|
-
<%= form.hidden_field "prices[#{currency}][currency]", value: currency %>
|
|
55
|
-
<%= form.text_field "prices[#{currency}][price]", value: price.amount, placeholder: "Default: #{default_price.amount || 'N/A'}", class: 'form-control' %>
|
|
56
|
-
</td>
|
|
57
|
-
<td>
|
|
58
|
-
<%= form.text_field "prices[#{currency}][compare_at_price]", value: price.compare_at_price, placeholder: "Default: #{default_price.compare_at_price || 'N/A'}", class: 'form-control' %>
|
|
59
|
-
</td>
|
|
60
|
-
</tr>
|
|
61
|
-
<% end %>
|
|
62
|
-
</tbody>
|
|
63
|
-
</table>
|
|
64
|
-
|
|
65
|
-
<div class="d-flex flex-row justify-content-end mt-2">
|
|
66
|
-
<div class="form-actions" data-hook="buttons">
|
|
67
|
-
<%= button Spree.t('actions.save'), 'save.svg', 'submit', { class: 'btn-outline-success', data: { disable_with: "#{ Spree.t(:saving) }...", turbo_frame: "_top" } } %>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
<% end %>
|
|
71
|
-
</div>
|
|
72
|
-
<% end %>
|