spree_cm_commissioner 2.3.2.pre.pre6 → 2.3.2
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/v2/storefront/intercity_taxi/draft_orders_controller.rb +11 -52
- data/app/factory/spree_cm_commissioner/order_telegram_message_factory.rb +0 -12
- data/app/mailers/spree/order_mailer_decorator.rb +6 -8
- data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +89 -34
- data/app/models/concerns/spree_cm_commissioner/service_recommendations.rb +2 -2
- data/app/models/spree_cm_commissioner/adjustment_decorator.rb +1 -1
- data/app/models/spree_cm_commissioner/order_decorator.rb +1 -1
- data/app/models/spree_cm_commissioner/place.rb +0 -7
- data/app/models/spree_cm_commissioner/tenant.rb +0 -4
- data/app/models/spree_cm_commissioner/variant_decorator.rb +0 -3
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +0 -1
- data/app/models/spree_cm_commissioner/vendor_place.rb +0 -9
- data/app/queries/spree_cm_commissioner/trip_query.rb +17 -23
- data/app/serializers/spree/v2/storefront/place_serializer.rb +2 -3
- data/app/serializers/spree/v2/tenant/cart_serializer.rb +0 -1
- data/app/serializers/spree/v2/tenant/line_item_serializer.rb +0 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/intercity_taxi_line_item_serializer.rb +18 -17
- data/app/services/spree_cm_commissioner/intercity_taxi_order/create.rb +23 -20
- data/app/services/spree_cm_commissioner/intercity_taxi_order/update.rb +72 -36
- data/app/views/spree/order_mailer/confirm_email.html.erb +1 -1
- data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +13 -14
- data/app/views/spree_cm_commissioner/order_mailer/tenant/_greeting.html.erb +4 -6
- data/config/routes.rb +1 -11
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +0 -2
- metadata +4 -51
- data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +0 -63
- data/app/controllers/spree/api/v2/storefront/route_places_controller.rb +0 -68
- data/app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb +0 -81
- data/app/controllers/spree/api/v2/tenant/trip_places_controller.rb +0 -42
- data/app/controllers/spree/api/v2/tenant/trip_search_controller.rb +0 -103
- data/app/controllers/spree/api/v2/tenant/trips_controller.rb +0 -32
- data/app/finders/spree_cm_commissioner/places/find_with_route.rb +0 -43
- data/app/finders/spree_cm_commissioner/routes/find_popular.rb +0 -25
- data/app/models/spree_cm_commissioner/calculators/extra_drop_off_distance.rb +0 -15
- data/app/models/spree_cm_commissioner/calculators/extra_pick_up_distance.rb +0 -15
- data/app/models/spree_cm_commissioner/pricing_action.rb +0 -27
- data/app/models/spree_cm_commissioner/pricing_model.rb +0 -18
- data/app/models/spree_cm_commissioner/pricing_model_variant.rb +0 -6
- data/app/models/spree_cm_commissioner/pricing_rule.rb +0 -15
- data/app/models/spree_cm_commissioner/pricing_rule_group.rb +0 -20
- data/app/models/spree_cm_commissioner/pricing_rules/extra_drop_off_distance.rb +0 -10
- data/app/models/spree_cm_commissioner/pricing_rules/extra_pick_up_distance.rb +0 -12
- data/app/models/spree_cm_commissioner/pricing_rules/nationality.rb +0 -35
- data/app/request_schemas/spree_cm_commissioner/intercity_taxi_draft_order_schema.rb +0 -10
- data/app/request_schemas/spree_cm_commissioner/intercity_taxi_draft_order_update_schema.rb +0 -29
- data/app/request_schemas/spree_cm_commissioner/route_places_request_schema.rb +0 -12
- data/app/serializers/spree/v2/tenant/intercity_taxi_cart_serializer.rb +0 -12
- data/app/serializers/spree/v2/tenant/trip_place_serializer.rb +0 -8
- data/app/serializers/spree/v2/tenant/trip_query_result_serializer.rb +0 -8
- data/app/serializers/spree/v2/tenant/trip_serializer.rb +0 -8
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_serializer.rb +0 -12
- data/app/services/spree_cm_commissioner/pricing_models/apply.rb +0 -51
- data/app/services/spree_cm_commissioner/pricing_rules/build_params.rb +0 -53
- data/app/services/spree_cm_commissioner/pricing_rules/build_template.rb +0 -27
- data/app/services/spree_cm_commissioner/pricing_rules/create.rb +0 -10
- data/app/services/spree_cm_commissioner/pricing_rules/update.rb +0 -11
- data/app/services/spree_cm_commissioner/vendor_places/base.rb +0 -24
- data/app/services/spree_cm_commissioner/vendor_places/bulk_create.rb +0 -70
- data/app/services/spree_cm_commissioner/vendor_places/create_with_google_map_data.rb +0 -85
- data/app/services/spree_cm_commissioner/vendor_places/update.rb +0 -56
- data/db/migrate/20250915075830_create_spree_cm_commissioner_pricing_models.rb +0 -17
- data/db/migrate/20250915080733_create_spree_cm_commissioner_pricing_model_variants.rb +0 -14
- data/db/migrate/20251003082144_create_spree_cm_commissioner_pricing_rule_groups.rb +0 -16
- data/db/migrate/20251003093408_create_spree_cm_commissioner_pricing_rule.rb +0 -19
- data/db/migrate/20251003093643_create_spree_cm_commissioner_pricing_action.rb +0 -14
- data/db/migrate/20251119093000_add_tenant_id_to_cm_vendor_places.rb +0 -8
- data/lib/spree_cm_commissioner/intercity_taxi/distance.rb +0 -38
- data/lib/spree_cm_commissioner/intercity_taxi/map_place.rb +0 -31
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_action_factory.rb +0 -5
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_model_factory.rb +0 -8
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_rule_factory.rb +0 -17
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_rule_group_factory.rb +0 -8
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Api
|
|
3
|
-
module V2
|
|
4
|
-
module Tenant
|
|
5
|
-
module IntercityTaxi
|
|
6
|
-
class DraftOrdersController < BaseController
|
|
7
|
-
include Spree::Api::V2::Storefront::OrderConcern
|
|
8
|
-
include SpreeCmCommissioner::OrderConcern
|
|
9
|
-
|
|
10
|
-
before_action :ensure_order, only: :update
|
|
11
|
-
|
|
12
|
-
def create
|
|
13
|
-
result = SpreeCmCommissioner::IntercityTaxiOrder::Create.call(
|
|
14
|
-
trip_id: params[:trip_id],
|
|
15
|
-
from_date: params[:from_date],
|
|
16
|
-
to_date: params[:to_date],
|
|
17
|
-
quantity: params[:quantity],
|
|
18
|
-
user: spree_current_user
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
if result.success?
|
|
22
|
-
render_serialized_payload { serialize_resource(result.value) }
|
|
23
|
-
else
|
|
24
|
-
render_error_payload(result.error)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def update
|
|
29
|
-
result = SpreeCmCommissioner::IntercityTaxiOrder::Update.call(
|
|
30
|
-
order: spree_current_order,
|
|
31
|
-
remark: params[:remark],
|
|
32
|
-
pickup_map_place_attributes: params.require(:pickup_map_place_attributes).permit(
|
|
33
|
-
:place_name,
|
|
34
|
-
:lat,
|
|
35
|
-
:lng,
|
|
36
|
-
:oob_confirmed
|
|
37
|
-
),
|
|
38
|
-
dropoff_map_place_attributes: params.require(:dropoff_map_place_attributes).permit(
|
|
39
|
-
:place_name,
|
|
40
|
-
:lat,
|
|
41
|
-
:lng,
|
|
42
|
-
:oob_confirmed
|
|
43
|
-
),
|
|
44
|
-
distance_attributes: params.require(:distance_attributes).permit(
|
|
45
|
-
:distance_km,
|
|
46
|
-
:ordered_points,
|
|
47
|
-
:estimated_time_minutes,
|
|
48
|
-
:base_km,
|
|
49
|
-
:detour_pickup_km,
|
|
50
|
-
:detour_dropoff_km,
|
|
51
|
-
:extra_pickup_km,
|
|
52
|
-
:extra_dropoff_km
|
|
53
|
-
)
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
if result.success?
|
|
57
|
-
render_serialized_payload { serialize_resource(result.value) }
|
|
58
|
-
else
|
|
59
|
-
render_error_payload(result.error)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
private
|
|
64
|
-
|
|
65
|
-
def required_schema
|
|
66
|
-
if action_name == 'create'
|
|
67
|
-
SpreeCmCommissioner::IntercityTaxiDraftOrderSchema
|
|
68
|
-
else
|
|
69
|
-
SpreeCmCommissioner::IntercityTaxiDraftOrderUpdateSchema
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def resource_serializer
|
|
74
|
-
Spree::V2::Tenant::IntercityTaxiCartSerializer
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Api
|
|
3
|
-
module V2
|
|
4
|
-
module Tenant
|
|
5
|
-
class TripPlacesController < BaseController
|
|
6
|
-
private
|
|
7
|
-
|
|
8
|
-
# override
|
|
9
|
-
def collection
|
|
10
|
-
@collection ||= begin
|
|
11
|
-
base_scope = scope
|
|
12
|
-
|
|
13
|
-
if params[:q].present?
|
|
14
|
-
@search = base_scope.ransack(params[:q])
|
|
15
|
-
@search.result
|
|
16
|
-
else
|
|
17
|
-
base_scope
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# override
|
|
23
|
-
def scope
|
|
24
|
-
model_class.joins(:location_vendor_places)
|
|
25
|
-
.where(location_vendor_places: { tenant_id: @tenant.id })
|
|
26
|
-
.distinct
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# override
|
|
30
|
-
def model_class
|
|
31
|
-
SpreeCmCommissioner::Place
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# override
|
|
35
|
-
def collection_serializer
|
|
36
|
-
Spree::V2::Tenant::TripPlaceSerializer
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Api
|
|
3
|
-
module V2
|
|
4
|
-
module Tenant
|
|
5
|
-
class TripSearchController < BaseController
|
|
6
|
-
CACHE_EXPIRES_IN = 5.minutes
|
|
7
|
-
|
|
8
|
-
def index
|
|
9
|
-
render_serialized_payload do
|
|
10
|
-
Rails.cache.fetch(collection_cache_key, collection_cache_opts) do
|
|
11
|
-
trips = SpreeCmCommissioner::TripQuery.new(
|
|
12
|
-
origin_id: params[:origin_id],
|
|
13
|
-
destination_id: params[:destination_id],
|
|
14
|
-
date: params[:date],
|
|
15
|
-
route_type: params[:route_type],
|
|
16
|
-
number_of_guests: params[:number_of_guests],
|
|
17
|
-
tenant_id: @tenant.id,
|
|
18
|
-
params: params
|
|
19
|
-
).call
|
|
20
|
-
|
|
21
|
-
serialize_collection(trips)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
# override from ContentCacheable
|
|
29
|
-
def max_age
|
|
30
|
-
CACHE_EXPIRES_IN.to_i
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# override
|
|
34
|
-
def collection_cache_key
|
|
35
|
-
cache_key_parts = [
|
|
36
|
-
'trip_search',
|
|
37
|
-
@tenant.id,
|
|
38
|
-
params[:origin_id],
|
|
39
|
-
params[:destination_id],
|
|
40
|
-
params[:date],
|
|
41
|
-
params[:route_type],
|
|
42
|
-
params[:number_of_guests],
|
|
43
|
-
resource_includes&.sort&.join(','),
|
|
44
|
-
sparse_fields&.sort&.join(','),
|
|
45
|
-
serializer_params.to_json,
|
|
46
|
-
params[:page]&.to_s&.strip,
|
|
47
|
-
params[:per_page]&.to_s&.strip
|
|
48
|
-
].compact.join('-')
|
|
49
|
-
|
|
50
|
-
Digest::MD5.hexdigest(cache_key_parts)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# override
|
|
54
|
-
def collection_cache_opts
|
|
55
|
-
{
|
|
56
|
-
namespace: Spree::Api::Config[:api_v2_collection_cache_namespace],
|
|
57
|
-
expires_in: CACHE_EXPIRES_IN
|
|
58
|
-
}
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# override
|
|
62
|
-
def default_resource_includes
|
|
63
|
-
[
|
|
64
|
-
'trips.vendor',
|
|
65
|
-
'trips.vendor.logo',
|
|
66
|
-
'trips.vehicle',
|
|
67
|
-
'trips.vehicle.vehicle_photos',
|
|
68
|
-
'trips.amenities'
|
|
69
|
-
]
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def serialize_collection(collection)
|
|
73
|
-
serialized_data = Spree::V2::Tenant::TripQueryResultSerializer.new(
|
|
74
|
-
collection,
|
|
75
|
-
include: default_resource_includes,
|
|
76
|
-
params: serializer_params
|
|
77
|
-
).serializable_hash
|
|
78
|
-
serialized_data[:meta] = {
|
|
79
|
-
count: collection.size,
|
|
80
|
-
total_count: collection.respond_to?(:total_count) ? collection.total_count : collection.size,
|
|
81
|
-
current_page: collection.respond_to?(:current_page) ? collection.current_page : 1,
|
|
82
|
-
per_page: collection.respond_to?(:limit_value) ? collection.limit_value : collection.size,
|
|
83
|
-
pages: collection.respond_to?(:total_pages) ? collection.total_pages : 1,
|
|
84
|
-
next_page: collection.respond_to?(:next_page) ? collection.next_page : nil,
|
|
85
|
-
prev_page: collection.respond_to?(:prev_page) ? collection.prev_page : nil
|
|
86
|
-
}
|
|
87
|
-
serialized_data
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# override
|
|
91
|
-
def serializer_params
|
|
92
|
-
params.permit(:include).to_hash
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# override
|
|
96
|
-
def required_schema
|
|
97
|
-
SpreeCmCommissioner::TripSearchRequestSchema
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Api
|
|
3
|
-
module V2
|
|
4
|
-
module Tenant
|
|
5
|
-
class TripsController < BaseController
|
|
6
|
-
private
|
|
7
|
-
|
|
8
|
-
# override
|
|
9
|
-
def resource
|
|
10
|
-
scope.find(params[:id])
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# override
|
|
14
|
-
def scope
|
|
15
|
-
model_class.joins(:vendor)
|
|
16
|
-
.where(spree_vendors: { tenant_id: @tenant.id })
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# override
|
|
20
|
-
def model_class
|
|
21
|
-
SpreeCmCommissioner::Trip
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# override
|
|
25
|
-
def resource_serializer
|
|
26
|
-
Spree::V2::Tenant::TripSerializer
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# Finds places that are used in routes (as origin or destination) by keyword search.
|
|
2
|
-
#
|
|
3
|
-
# @param keyword [String] Search term to match against place names (case-insensitive)
|
|
4
|
-
# @param place_type [String] Type of route place: 'origin' or 'destination'
|
|
5
|
-
#
|
|
6
|
-
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Place>] Places matching the keyword
|
|
7
|
-
# that are used as origins or destinations in existing routes. Returns empty relation if
|
|
8
|
-
# keyword is blank or place_type is invalid.
|
|
9
|
-
#
|
|
10
|
-
# @note For default/empty state display, use SpreeCmCommissioner::Routes::FindPopular instead
|
|
11
|
-
# to show popular routes to users before they enter a search term.
|
|
12
|
-
#
|
|
13
|
-
# @example
|
|
14
|
-
# finder = SpreeCmCommissioner::Places::FindWithRoute.new(keyword: 'Phnom', place_type: 'origin')
|
|
15
|
-
# finder.execute # => Returns places with "Phnom" in name that are used as route origins
|
|
16
|
-
module SpreeCmCommissioner
|
|
17
|
-
module Places
|
|
18
|
-
class FindWithRoute
|
|
19
|
-
attr_reader :keyword, :place_type
|
|
20
|
-
|
|
21
|
-
def initialize(keyword:, place_type:)
|
|
22
|
-
@keyword = keyword
|
|
23
|
-
@place_type = place_type
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def execute
|
|
27
|
-
return SpreeCmCommissioner::Place.none if keyword.blank? || place_type.blank?
|
|
28
|
-
|
|
29
|
-
scope.where('cm_places.name ILIKE ?', "%#{keyword}%")
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
private
|
|
33
|
-
|
|
34
|
-
def scope
|
|
35
|
-
if place_type == 'origin'
|
|
36
|
-
SpreeCmCommissioner::Place.with_routes_as_origin
|
|
37
|
-
else
|
|
38
|
-
SpreeCmCommissioner::Place.with_routes_as_destination
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Route>] Routes with origin and destination places loaded,
|
|
8
|
-
# ordered from most to least popular
|
|
9
|
-
#
|
|
10
|
-
# @example
|
|
11
|
-
# finder = SpreeCmCommissioner::Routes::FindPopular.new
|
|
12
|
-
# finder.execute # => Returns routes sorted by fulfillment and order counts
|
|
13
|
-
|
|
14
|
-
module SpreeCmCommissioner
|
|
15
|
-
module Routes
|
|
16
|
-
class FindPopular
|
|
17
|
-
def execute
|
|
18
|
-
SpreeCmCommissioner::Route
|
|
19
|
-
.includes(:origin_place, :destination_place)
|
|
20
|
-
.order(Arel.sql('COALESCE(fulfilled_order_count, 0) DESC'))
|
|
21
|
-
.order(Arel.sql('COALESCE(order_count, 0) DESC'))
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module Calculators
|
|
3
|
-
class ExtraDropOffDistance < ExtraPickUpDistance
|
|
4
|
-
preference :base_price, :decimal, default: 0
|
|
5
|
-
preference :amount, :decimal, default: 0
|
|
6
|
-
|
|
7
|
-
def compute(line_item)
|
|
8
|
-
distance_km = line_item.distance.extra_dropoff_km
|
|
9
|
-
return nil if distance_km.nil?
|
|
10
|
-
|
|
11
|
-
preferred_base_price + (distance_km * preferred_amount)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module Calculators
|
|
3
|
-
class ExtraPickUpDistance < Spree::Calculator
|
|
4
|
-
preference :base_price, :decimal, default: 0
|
|
5
|
-
preference :amount, :decimal, default: 0
|
|
6
|
-
|
|
7
|
-
def compute(line_item)
|
|
8
|
-
distance_km = line_item.distance.extra_pickup_km
|
|
9
|
-
return nil if distance_km.nil?
|
|
10
|
-
|
|
11
|
-
preferred_base_price + (distance_km * preferred_amount)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class PricingAction < Base
|
|
3
|
-
belongs_to :pricing_rule_group, class_name: 'SpreeCmCommissioner::PricingRuleGroup'
|
|
4
|
-
|
|
5
|
-
has_one :calculator, as: :calculable, class_name: 'Spree::Calculator', dependent: :destroy
|
|
6
|
-
accepts_nested_attributes_for :calculator
|
|
7
|
-
|
|
8
|
-
def perform(line_item)
|
|
9
|
-
return if pricing_rule_group.pricing_rules.blank?
|
|
10
|
-
|
|
11
|
-
amount = calculator&.compute(line_item)
|
|
12
|
-
|
|
13
|
-
line_item.adjustments.create!(
|
|
14
|
-
amount: amount,
|
|
15
|
-
source: self,
|
|
16
|
-
adjustable: line_item,
|
|
17
|
-
order: line_item.order,
|
|
18
|
-
label: pricing_rule_group.pricing_model.name,
|
|
19
|
-
mandatory: true
|
|
20
|
-
)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def self.available_calculator_types
|
|
24
|
-
SpreeCmCommissioner::Calculators.constants.map(&:to_s)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class PricingModel < Base
|
|
3
|
-
acts_as_list column: :position, scope: :vendor_id
|
|
4
|
-
|
|
5
|
-
belongs_to :vendor, class_name: 'Spree::Vendor'
|
|
6
|
-
|
|
7
|
-
has_many :pricing_model_variants, class_name: 'SpreeCmCommissioner::PricingModelVariant', dependent: :destroy
|
|
8
|
-
has_many :variants, through: :pricing_model_variants, class_name: 'Spree::Variant'
|
|
9
|
-
has_many :pricing_rule_groups, class_name: 'SpreeCmCommissioner::PricingRuleGroup', dependent: :destroy
|
|
10
|
-
has_many :pricing_rules, through: :pricing_rule_groups, class_name: 'SpreeCmCommissioner::PricingRule'
|
|
11
|
-
|
|
12
|
-
accepts_nested_attributes_for :pricing_rule_groups, allow_destroy: true
|
|
13
|
-
|
|
14
|
-
validates :name, presence: true, uniqueness: { scope: :vendor_id }
|
|
15
|
-
|
|
16
|
-
enum status: { draft: 0, active: 1, archived: 2 }
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class PricingRule < Base
|
|
3
|
-
acts_as_list column: :position, scope: :pricing_rule_group_id
|
|
4
|
-
|
|
5
|
-
belongs_to :pricing_rule_group, class_name: 'SpreeCmCommissioner::PricingRuleGroup'
|
|
6
|
-
|
|
7
|
-
def eligible?(_line_item)
|
|
8
|
-
raise 'eligible? should be implemented in a sub-class of SpreeCmCommissioner::PricingRule'
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def self.available_rule_types
|
|
12
|
-
SpreeCmCommissioner::PricingRules.constants.map(&:to_s)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class PricingRuleGroup < Base
|
|
3
|
-
MATCH_TYPES = %w[all any none].freeze
|
|
4
|
-
|
|
5
|
-
acts_as_list column: :position, scope: :pricing_model_id
|
|
6
|
-
store_accessor :private_metadata, :template_key
|
|
7
|
-
store_accessor :private_metadata, :match_type
|
|
8
|
-
|
|
9
|
-
belongs_to :pricing_model, class_name: 'SpreeCmCommissioner::PricingModel'
|
|
10
|
-
has_many :pricing_rules, class_name: 'SpreeCmCommissioner::PricingRule', dependent: :destroy
|
|
11
|
-
has_one :pricing_action, class_name: 'SpreeCmCommissioner::PricingAction', dependent: :destroy
|
|
12
|
-
|
|
13
|
-
accepts_nested_attributes_for :pricing_rules, allow_destroy: true
|
|
14
|
-
accepts_nested_attributes_for :pricing_action, allow_destroy: true
|
|
15
|
-
|
|
16
|
-
validates :name, presence: true
|
|
17
|
-
|
|
18
|
-
enum status: { draft: 0, active: 1, archived: 2 }
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module PricingRules
|
|
3
|
-
class ExtraPickUpDistance < SpreeCmCommissioner::PricingRule
|
|
4
|
-
store_accessor :private_metadata, :min_distance
|
|
5
|
-
|
|
6
|
-
def eligible?(line_item)
|
|
7
|
-
distance_km = line_item.distance&.extra_pickup_km || 0
|
|
8
|
-
distance_km > min_distance.to_f
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module PricingRules
|
|
3
|
-
class Nationality < SpreeCmCommissioner::PricingRule
|
|
4
|
-
RULE_TYPES = %w[all any none].freeze
|
|
5
|
-
|
|
6
|
-
store_accessor :private_metadata, :rule_type, :nationalities
|
|
7
|
-
|
|
8
|
-
def eligible?(line_item) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
9
|
-
return false if nationalities.blank? || line_item.guests.blank?
|
|
10
|
-
|
|
11
|
-
targets = Array.wrap(nationalities).map(&:downcase)
|
|
12
|
-
guest_nationalities = line_item.guests.map { |g| guest_nationality(g) }.compact
|
|
13
|
-
|
|
14
|
-
return false if guest_nationalities.empty?
|
|
15
|
-
|
|
16
|
-
case rule_type
|
|
17
|
-
when 'all'
|
|
18
|
-
guest_nationalities.all? { |n| targets.include?(n) }
|
|
19
|
-
when 'any'
|
|
20
|
-
guest_nationalities.any? { |n| targets.include?(n) }
|
|
21
|
-
when 'none'
|
|
22
|
-
guest_nationalities.none? { |n| targets.include?(n) }
|
|
23
|
-
else
|
|
24
|
-
false
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
|
|
30
|
-
def guest_nationality(guest)
|
|
31
|
-
guest.nationality&.name.to_s.downcase
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class IntercityTaxiDraftOrderSchema < ApplicationRequestSchema
|
|
3
|
-
params do
|
|
4
|
-
required(:trip_id).value(:integer)
|
|
5
|
-
required(:from_date).value(:date)
|
|
6
|
-
required(:to_date).value(:date)
|
|
7
|
-
required(:quantity).value(:integer)
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class IntercityTaxiDraftOrderUpdateSchema < ApplicationRequestSchema
|
|
3
|
-
params do
|
|
4
|
-
optional(:remark).filled(:string)
|
|
5
|
-
optional(:pickup_map_place_attributes).hash do
|
|
6
|
-
optional(:place_name).filled(:string)
|
|
7
|
-
optional(:lat).filled(:string)
|
|
8
|
-
optional(:lng).filled(:string)
|
|
9
|
-
optional(:oob_confirmed).filled(:bool)
|
|
10
|
-
end
|
|
11
|
-
optional(:dropoff_map_place_attributes).hash do
|
|
12
|
-
optional(:place_name).filled(:string)
|
|
13
|
-
optional(:lat).filled(:string)
|
|
14
|
-
optional(:lng).filled(:string)
|
|
15
|
-
optional(:oob_confirmed).filled(:bool)
|
|
16
|
-
end
|
|
17
|
-
optional(:distance_attributes).hash do
|
|
18
|
-
optional(:distance_km).filled(:float)
|
|
19
|
-
optional(:ordered_points).filled(:array)
|
|
20
|
-
optional(:estimated_time_minutes).filled(:integer)
|
|
21
|
-
optional(:base_km).filled(:float)
|
|
22
|
-
optional(:detour_pickup_km).filled(:float)
|
|
23
|
-
optional(:detour_dropoff_km).filled(:float)
|
|
24
|
-
optional(:extra_pickup_km).filled(:float)
|
|
25
|
-
optional(:extra_dropoff_km).filled(:float)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
class RoutePlacesRequestSchema < ApplicationRequestSchema
|
|
3
|
-
params do
|
|
4
|
-
required(:place_type).filled(:string)
|
|
5
|
-
required(:query).filled(:string)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
rule(:place_type) do
|
|
9
|
-
key.failure('Invalid place_type. Use origin or destination') unless %w[origin destination].include?(value)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module V2
|
|
3
|
-
module Storefront
|
|
4
|
-
class RouteSerializer < BaseSerializer
|
|
5
|
-
attributes :route_name
|
|
6
|
-
|
|
7
|
-
has_one :origin_place, serializer: ::Spree::V2::Storefront::PlaceSerializer
|
|
8
|
-
has_one :destination_place, serializer: ::Spree::V2::Storefront::PlaceSerializer
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module PricingModels
|
|
3
|
-
class Apply
|
|
4
|
-
def initialize(line_item_id:, pricing_model_id:)
|
|
5
|
-
@line_item_id = line_item_id
|
|
6
|
-
@pricing_model_id = pricing_model_id
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def call
|
|
10
|
-
pricing_model.pricing_rule_groups.each do |group|
|
|
11
|
-
apply_group(group, line_item)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
attr_reader :line_item_id, :pricing_model_id
|
|
18
|
-
|
|
19
|
-
def line_item
|
|
20
|
-
@line_item ||= Spree::LineItem.find(line_item_id)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def pricing_model
|
|
24
|
-
@pricing_model ||= SpreeCmCommissioner::PricingModel.find(pricing_model_id)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def apply_group(group, line_item)
|
|
28
|
-
eligible_rules = group.pricing_rules.select { |r| r.eligible?(line_item) }
|
|
29
|
-
|
|
30
|
-
return if eligible_rules.empty?
|
|
31
|
-
|
|
32
|
-
if group_eligible?(group, eligible_rules)
|
|
33
|
-
group.pricing_action&.perform(line_item)
|
|
34
|
-
else
|
|
35
|
-
Rails.logger.info("Group #{group.id} not eligible for line_item #{line_item.id}")
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def group_eligible?(group, eligible_rules)
|
|
40
|
-
case group.match_type
|
|
41
|
-
when 'all'
|
|
42
|
-
eligible_rules.size == group.pricing_rules.size
|
|
43
|
-
when 'any'
|
|
44
|
-
eligible_rules.any?
|
|
45
|
-
else
|
|
46
|
-
false
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|