spree_cm_commissioner 2.3.2.pre.pre2 → 2.3.2.pre.pre5

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/app/controllers/spree/api/v2/storefront/intercity_taxi/draft_orders_controller.rb +36 -36
  4. data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +63 -0
  5. data/app/controllers/spree/api/v2/storefront/route_places_controller.rb +68 -0
  6. data/app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb +37 -37
  7. data/app/controllers/spree/api/v2/tenant/trip_places_controller.rb +5 -11
  8. data/app/controllers/spree/api/v2/tenant/trip_search_controller.rb +1 -1
  9. data/app/controllers/spree/api/v2/tenant/trips_controller.rb +8 -8
  10. data/app/factory/spree_cm_commissioner/order_telegram_message_factory.rb +12 -0
  11. data/app/finders/spree_cm_commissioner/places/find_with_route.rb +43 -0
  12. data/app/finders/spree_cm_commissioner/routes/find_popular.rb +25 -0
  13. data/app/mailers/spree/order_mailer_decorator.rb +8 -6
  14. data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +34 -89
  15. data/app/models/concerns/spree_cm_commissioner/service_recommendations.rb +2 -2
  16. data/app/models/spree_cm_commissioner/adjustment_decorator.rb +1 -1
  17. data/app/models/spree_cm_commissioner/calculators/extra_drop_off_distance.rb +15 -0
  18. data/app/models/spree_cm_commissioner/calculators/extra_pick_up_distance.rb +15 -0
  19. data/app/models/spree_cm_commissioner/order_decorator.rb +1 -1
  20. data/app/models/spree_cm_commissioner/place.rb +7 -0
  21. data/app/models/spree_cm_commissioner/pricing_action.rb +27 -0
  22. data/app/models/spree_cm_commissioner/pricing_model.rb +18 -0
  23. data/app/models/spree_cm_commissioner/pricing_model_variant.rb +6 -0
  24. data/app/models/spree_cm_commissioner/pricing_rule.rb +15 -0
  25. data/app/models/spree_cm_commissioner/pricing_rule_group.rb +20 -0
  26. data/app/models/spree_cm_commissioner/pricing_rules/extra_drop_off_distance.rb +10 -0
  27. data/app/models/spree_cm_commissioner/pricing_rules/extra_pick_up_distance.rb +12 -0
  28. data/app/models/spree_cm_commissioner/pricing_rules/nationality.rb +35 -0
  29. data/app/models/spree_cm_commissioner/tenant.rb +4 -0
  30. data/app/models/spree_cm_commissioner/variant_decorator.rb +3 -0
  31. data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -0
  32. data/app/request_schemas/spree_cm_commissioner/intercity_taxi_draft_order_update_schema.rb +22 -3
  33. data/app/request_schemas/spree_cm_commissioner/route_places_request_schema.rb +12 -0
  34. data/app/serializers/spree/v2/storefront/place_serializer.rb +3 -2
  35. data/app/serializers/spree/v2/tenant/cart_serializer.rb +1 -0
  36. data/app/serializers/spree/v2/tenant/intercity_taxi_cart_serializer.rb +12 -0
  37. data/app/serializers/spree/v2/tenant/line_item_serializer.rb +1 -0
  38. data/app/serializers/spree/v2/tenant/trip_place_serializer.rb +8 -0
  39. data/app/serializers/spree/v2/tenant/trip_query_result_serializer.rb +8 -0
  40. data/app/serializers/spree/v2/tenant/trip_serializer.rb +8 -0
  41. data/app/serializers/spree_cm_commissioner/v2/storefront/intercity_taxi_line_item_serializer.rb +17 -18
  42. data/app/serializers/spree_cm_commissioner/v2/storefront/route_serializer.rb +12 -0
  43. data/app/services/spree_cm_commissioner/intercity_taxi_order/create.rb +11 -22
  44. data/app/services/spree_cm_commissioner/intercity_taxi_order/update.rb +32 -11
  45. data/app/services/spree_cm_commissioner/pricing_models/apply.rb +51 -0
  46. data/app/services/spree_cm_commissioner/pricing_rules/build_params.rb +53 -0
  47. data/app/services/spree_cm_commissioner/pricing_rules/build_template.rb +27 -0
  48. data/app/services/spree_cm_commissioner/pricing_rules/create.rb +10 -0
  49. data/app/services/spree_cm_commissioner/pricing_rules/update.rb +11 -0
  50. data/app/services/spree_cm_commissioner/vendor_places/base.rb +24 -0
  51. data/app/services/spree_cm_commissioner/vendor_places/bulk_create.rb +70 -0
  52. data/app/services/spree_cm_commissioner/vendor_places/create_with_google_map_data.rb +85 -0
  53. data/app/services/spree_cm_commissioner/vendor_places/update.rb +56 -0
  54. data/app/views/spree/order_mailer/confirm_email.html.erb +1 -1
  55. data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +14 -13
  56. data/app/views/spree_cm_commissioner/order_mailer/tenant/_greeting.html.erb +6 -4
  57. data/config/routes.rb +4 -10
  58. data/db/migrate/20250915075830_create_spree_cm_commissioner_pricing_models.rb +17 -0
  59. data/db/migrate/20250915080733_create_spree_cm_commissioner_pricing_model_variants.rb +14 -0
  60. data/db/migrate/20251003082144_create_spree_cm_commissioner_pricing_rule_groups.rb +16 -0
  61. data/db/migrate/20251003093408_create_spree_cm_commissioner_pricing_rule.rb +19 -0
  62. data/db/migrate/20251003093643_create_spree_cm_commissioner_pricing_action.rb +14 -0
  63. data/db/migrate/20251119093000_add_tenant_id_to_cm_vendor_places.rb +2 -1
  64. data/lib/spree_cm_commissioner/intercity_taxi/distance.rb +38 -0
  65. data/lib/spree_cm_commissioner/intercity_taxi/map_place.rb +31 -0
  66. data/lib/spree_cm_commissioner/test_helper/factories/pricing_action_factory.rb +5 -0
  67. data/lib/spree_cm_commissioner/test_helper/factories/pricing_model_factory.rb +8 -0
  68. data/lib/spree_cm_commissioner/test_helper/factories/pricing_rule_factory.rb +17 -0
  69. data/lib/spree_cm_commissioner/test_helper/factories/pricing_rule_group_factory.rb +8 -0
  70. data/lib/spree_cm_commissioner/version.rb +1 -1
  71. data/lib/spree_cm_commissioner.rb +2 -0
  72. metadata +42 -2
@@ -1,30 +1,14 @@
1
1
  module SpreeCmCommissioner
2
2
  module IntercityTaxiOrder
3
3
  class Create
4
- attr_reader :trip_id, :from_date, :to_date, :user, :quantity
4
+ prepend ::Spree::ServiceModule::Base
5
5
 
6
- def self.call(trip_id:, from_date:, to_date:, user: nil, quantity: 1)
7
- new(
8
- trip_id: trip_id,
9
- from_date: from_date,
10
- to_date: to_date,
11
- user: user,
12
- quantity: quantity
13
- ).call
14
- end
15
-
16
- def initialize(trip_id:, from_date:, to_date:, user:, quantity:)
17
- @trip_id = trip_id
18
- @from_date = from_date
19
- @to_date = to_date
20
- @user = user
21
- @quantity = quantity.to_i <= 0 ? 1 : quantity.to_i
22
- end
6
+ def call(trip_id:, from_date:, to_date:, user: nil, quantity: 1)
7
+ validate!(trip_id: trip_id, from_date: from_date, to_date: to_date, quantity: quantity)
23
8
 
24
- def call
25
- validate!
9
+ quantity = quantity.to_i
26
10
 
27
- ActiveRecord::Base.transaction do
11
+ order = ActiveRecord::Base.transaction do
28
12
  trip = SpreeCmCommissioner::Trip.find(trip_id)
29
13
  variant = trip.product.variants.first
30
14
  raise ArgumentError, 'No variant found for trip' if variant.blank?
@@ -49,15 +33,20 @@ module SpreeCmCommissioner
49
33
 
50
34
  order
51
35
  end
36
+
37
+ success(order)
38
+ rescue StandardError => e
39
+ failure(nil, e.message)
52
40
  end
53
41
 
54
42
  private
55
43
 
56
- def validate!
44
+ def validate!(trip_id:, from_date:, to_date:, quantity:)
57
45
  raise ArgumentError, 'trip_id is required' if trip_id.blank?
58
46
  raise ArgumentError, 'from_date is required' if from_date.blank?
59
47
  raise ArgumentError, 'to_date is required' if to_date.blank?
60
48
  raise ArgumentError, 'to_date must be after from_date' if from_date.present? && to_date.present? && to_date < from_date
49
+ raise ArgumentError, 'quantity must be 1' if quantity.to_i != 1
61
50
  end
62
51
 
63
52
  def build_guests_for!(line_item, qty)
@@ -1,21 +1,42 @@
1
1
  module SpreeCmCommissioner
2
2
  module IntercityTaxiOrder
3
3
  class Update
4
- attr_reader :order, :order_params
4
+ prepend ::Spree::ServiceModule::Base
5
5
 
6
- def self.call(order:, order_params:)
7
- new(order: order, order_params: order_params).call
8
- end
6
+ def call(
7
+ order:,
8
+ remark: nil,
9
+ pickup_map_place_attributes: nil,
10
+ dropoff_map_place_attributes: nil,
11
+ distance_attributes: nil
12
+ )
13
+ line_item = order.line_items.first
9
14
 
10
- def initialize(order:, order_params:)
11
- @order = order
12
- @order_params = order_params
13
- end
15
+ raise ArgumentError, 'Order has no line items' if line_item.blank?
16
+
17
+ if pickup_map_place_attributes.present?
18
+ line_item.pickup_map_place = SpreeCmCommissioner::IntercityTaxi::MapPlace.new(
19
+ pickup_map_place_attributes
20
+ )
21
+ end
22
+
23
+ if dropoff_map_place_attributes.present?
24
+ line_item.dropoff_map_place = SpreeCmCommissioner::IntercityTaxi::MapPlace.new(
25
+ dropoff_map_place_attributes
26
+ )
27
+ end
28
+
29
+ if distance_attributes.present?
30
+ line_item.distance = SpreeCmCommissioner::IntercityTaxi::Distance.new(
31
+ distance_attributes
32
+ )
33
+ end
14
34
 
15
- def call
16
- order.update!(order_params)
35
+ line_item.update!(remark: remark)
17
36
 
18
- order
37
+ success(order.reload)
38
+ rescue StandardError => e
39
+ failure(nil, e.message)
19
40
  end
20
41
  end
21
42
  end
@@ -0,0 +1,51 @@
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
@@ -0,0 +1,53 @@
1
+ module SpreeCmCommissioner
2
+ module PricingRules
3
+ module BuildParams
4
+ module_function
5
+
6
+ def permitted_group_params(params)
7
+ group_params = params[:spree_cm_commissioner_pricing_rule_group] || params
8
+
9
+ {
10
+ name: group_params[:name],
11
+ status: group_params[:status],
12
+ template_key: group_params[:template_key],
13
+ match_type: group_params[:match_type],
14
+ pricing_rules_attributes: build_rules_attributes(params[:pricing_rules]),
15
+ pricing_action_attributes: build_action_attributes(params[:pricing_action])
16
+ }
17
+ end
18
+
19
+ def build_rules_attributes(rules_array)
20
+ return [] unless rules_array
21
+
22
+ rules_array.map do |r|
23
+ {
24
+ id: r[:id],
25
+ type: r[:type],
26
+ private_metadata: r[:private_metadata],
27
+ _destroy: r[:_destroy]
28
+ }
29
+ end
30
+ end
31
+
32
+ def build_action_attributes(action_data)
33
+ return nil unless action_data&.dig(:calculator)
34
+
35
+ calc_data = action_data[:calculator]
36
+ calculator = calc_data[:type].safe_constantize&.new
37
+ set_preferences(calculator, calc_data[:preferences]) if calculator
38
+
39
+ { id: action_data[:id], calculator: calculator }
40
+ end
41
+
42
+ def set_preferences(calculator, preferences)
43
+ return unless preferences && calculator
44
+
45
+ prefs = preferences.respond_to?(:to_unsafe_h) ? preferences.to_unsafe_h : preferences
46
+ prefs.each do |key, value|
47
+ setter = "preferred_#{key}="
48
+ calculator.public_send(setter, value) if calculator.respond_to?(setter)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ module SpreeCmCommissioner
2
+ module PricingRules
3
+ class BuildTemplate
4
+ def self.call(pricing_model:, template_key:)
5
+ template = PRICING_RULE_GROUP_TEMPLATES[template_key.to_sym]
6
+ return unless template
7
+
8
+ group = pricing_model.pricing_rule_groups.build
9
+
10
+ template[:rules]&.each do |rule_data|
11
+ group.pricing_rules.where(type: rule_data[:type]).build(
12
+ type: rule_data[:type],
13
+ private_metadata: rule_data[:private_metadata] || {}
14
+ )
15
+ end
16
+
17
+ if template[:action]
18
+ calculator = template[:action][:calculator_type].constantize.new
19
+ BuildParams.set_preferences(calculator, template[:action][:preferences])
20
+ group.build_pricing_action(calculator: calculator)
21
+ end
22
+
23
+ group
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ module SpreeCmCommissioner
2
+ module PricingRules
3
+ class Create
4
+ def self.call(pricing_model:, params:)
5
+ attrs = BuildParams.permitted_group_params(params)
6
+ pricing_model.pricing_rule_groups.create(attrs)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ module PricingRules
3
+ class Update
4
+ def self.call(pricing_rule_group:, params:)
5
+ attrs = BuildParams.permitted_group_params(params)
6
+ pricing_rule_group.update(attrs)
7
+ pricing_rule_group
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ module SpreeCmCommissioner
2
+ module VendorPlaces
3
+ class Base
4
+ prepend ::Spree::ServiceModule::Base
5
+
6
+ ALLOWED_PLACE_TYPES = %w[venue stop branch location].freeze
7
+
8
+ private
9
+
10
+ def validate_place_type!(place_type)
11
+ return I18n.t('controller.vendor_places.place_type_required', default: 'Place type is required') if place_type.nil?
12
+
13
+ unless ALLOWED_PLACE_TYPES.include?(place_type.to_s)
14
+ return I18n.t(
15
+ 'controller.vendor_places.invalid_place_type',
16
+ default: "Place type must be one of: #{ALLOWED_PLACE_TYPES.join(', ')}"
17
+ )
18
+ end
19
+
20
+ nil
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,70 @@
1
+ # Bulk creates vendor places of any valid type (e.g., :stop, :branch, :location) with validation and transaction support.
2
+ #
3
+ # Validates place_ids count and creates vendor places atomically.
4
+ # Rolls back all changes if any creation fails.
5
+ #
6
+ # Usage:
7
+ # result = SpreeCmCommissioner::VendorPlaces::BulkCreate.call(
8
+ # vendor: current_vendor,
9
+ # place_ids: [1, 2, 3],
10
+ # place_type: :location, # or :stop, :branch, etc.
11
+ # description: "Sample description",
12
+ # max_count: 10,
13
+ # location: parent_location # required for :stop and :branch
14
+ # )
15
+ #
16
+ # if result.success?
17
+ # created_vendor_places = result.value
18
+ # else
19
+ # error_message = result.error
20
+
21
+ module SpreeCmCommissioner
22
+ module VendorPlaces
23
+ class BulkCreate < Base
24
+ def call(vendor:, place_ids:, place_type:, description: nil, max_count: 10, location: nil) # rubocop:disable Metrics/ParameterLists
25
+ error_message = validate_inputs!(place_ids: place_ids, place_type: place_type, max_count: max_count, location: location)
26
+ return failure(nil, error_message) if error_message
27
+
28
+ created_vendor_places = []
29
+
30
+ ActiveRecord::Base.transaction do
31
+ place_ids.each do |place_id|
32
+ vendor_place = build_vendor_place(
33
+ vendor: vendor,
34
+ place_id: place_id,
35
+ place_type: place_type,
36
+ description: description,
37
+ location: location
38
+ )
39
+
40
+ vendor_place.save!
41
+ created_vendor_places << vendor_place
42
+ end
43
+ end
44
+
45
+ success(created_vendor_places)
46
+ rescue ActiveRecord::RecordInvalid => e
47
+ failure(nil, e.record.errors.full_messages.to_sentence)
48
+ end
49
+
50
+ private
51
+
52
+ def validate_inputs!(place_ids:, place_type:, max_count:, location: nil)
53
+ validate_place_type!(place_type) ||
54
+ (place_ids.blank? && I18n.t('controller.vendor_places.place_ids_blank')) ||
55
+ (place_ids.size > max_count && I18n.t('controller.vendor_places.selection_limit', count: max_count)) ||
56
+ (requires_location?(place_type: place_type) && location.blank? && I18n.t('controller.vendor_places.location_required'))
57
+ end
58
+
59
+ def build_vendor_place(vendor:, place_id:, place_type:, description:, location: nil)
60
+ attrs = { vendor_id: vendor.id, place_type: place_type.to_sym, place_id: place_id, description: description }
61
+ attrs[:location_id] = location&.id if requires_location?(place_type: place_type)
62
+ SpreeCmCommissioner::VendorPlace.new(attrs)
63
+ end
64
+
65
+ def requires_location?(place_type:)
66
+ %i[stop branch].include?(place_type.to_sym)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,85 @@
1
+ # Creates a vendor place from Google Map base64-encoded place data.
2
+ # Processes place data and creates both Place and VendorPlace records atomically.
3
+ #
4
+ # Usage:
5
+ # result = SpreeCmCommissioner::VendorPlaces::CreateWithGoogleMapData.call(
6
+ # vendor: current_vendor,
7
+ # place_type: 'stop',
8
+ # google_place_base_64_content: google_place_base_64_content,
9
+ # description: 'Main Warehouse',
10
+ # location: parent_vendor_location
11
+ # )
12
+ #
13
+ # if result.success?
14
+ # vendor_place = result.value
15
+ # else
16
+ # error_message = result.error
17
+ # end
18
+
19
+ module SpreeCmCommissioner
20
+ module VendorPlaces
21
+ class CreateWithGoogleMapData < Base
22
+ def call(vendor:, place_type:, google_place_base_64_content:, description: nil, location: nil)
23
+ error_message = validate_place_type!(place_type)
24
+ return failure(nil, error_message) if error_message.present?
25
+
26
+ # Only require location for stop and branch types
27
+ return failure(nil, I18n.t('controller.vendor_places.location_required')) if %w[stop branch].include?(place_type) && location.nil?
28
+
29
+ place = process_place(google_place_base_64_content: google_place_base_64_content)
30
+ return failure(nil, place) unless place.is_a?(SpreeCmCommissioner::Place)
31
+
32
+ vendor_place = create_vendor_place(vendor: vendor, place: place, place_type: place_type, description: description, location: location)
33
+ return failure(nil, vendor_place) if vendor_place.nil? || vendor_place.is_a?(String)
34
+
35
+ success(vendor_place)
36
+ end
37
+
38
+ private
39
+
40
+ def process_place(google_place_base_64_content:)
41
+ place = SpreeCmCommissioner::PlaceDecoder.process_place(google_place_base_64_content)
42
+ return I18n.t('controller.vendor_places.process_place_failed', default: 'Failed to process place') if place.nil? || !place.save
43
+
44
+ place
45
+ rescue StandardError => e
46
+ e.message
47
+ end
48
+
49
+ def create_vendor_place(vendor:, place:, place_type:, description:, location:)
50
+ error_message = nil
51
+ result = ActiveRecord::Base.transaction do
52
+ vendor_place = build_vendor_place(vendor: vendor, place: place, type: place_type, description: description, location: location)
53
+ unless vendor_place.save
54
+ error_message = vendor_place.errors.full_messages.to_sentence
55
+ raise ActiveRecord::Rollback
56
+ end
57
+ vendor_place
58
+ end
59
+ error_message || result
60
+ end
61
+
62
+ def build_vendor_place(vendor:, place:, type:, description: nil, location: nil)
63
+ case type
64
+ when 'stop'
65
+ vendor.stops.new(
66
+ place_id: place.id,
67
+ description: description,
68
+ location_id: location&.id
69
+ )
70
+ when 'branch'
71
+ vendor.branches.new(
72
+ place_id: place.id,
73
+ description: description,
74
+ location_id: location&.id
75
+ )
76
+ when 'location'
77
+ vendor.locations.new(
78
+ place_id: place.id,
79
+ description: description
80
+ )
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,56 @@
1
+ # Updates all vendor places matching the same vendor, place_id, and location_id.
2
+ # Only updates description and location_id. Rolls back if any update fails.
3
+ #
4
+ # Usage:
5
+ # result = SpreeCmCommissioner::VendorPlaces::Update.call(
6
+ # vendor: current_vendor,
7
+ # vendor_place: existing_vendor_place,
8
+ # location_id: new_location_id,
9
+ # description: 'Updated description'
10
+ # )
11
+ #
12
+ # if result.success?
13
+ # updated_place = result.value
14
+ # else
15
+ # error_message = result.error
16
+ # end
17
+ module SpreeCmCommissioner
18
+ module VendorPlaces
19
+ class Update < Base
20
+ def call(vendor:, vendor_place:, description: nil, location_id: nil)
21
+ if vendor_place.blank?
22
+ return failure(
23
+ nil,
24
+ I18n.t('controller.vendor_places.vendor_place_not_found', default: 'Vendor place not found')
25
+ )
26
+ end
27
+
28
+ ActiveRecord::Base.transaction do
29
+ related_places = SpreeCmCommissioner::VendorPlace.where(
30
+ vendor_id: vendor.id,
31
+ place_id: vendor_place.place_id,
32
+ location_id: vendor_place.location_id
33
+ )
34
+
35
+ update_attrs = {}
36
+ update_attrs[:description] = description unless description.nil?
37
+ update_attrs[:location_id] = location_id unless location_id.nil?
38
+
39
+ related_places.each do |vp|
40
+ unless vp.update(update_attrs)
41
+ error_message = vp.errors.full_messages.to_sentence
42
+ raise ActiveRecord::Rollback, error_message
43
+ end
44
+ end
45
+ end
46
+
47
+ vendor_place.reload
48
+ success(vendor_place)
49
+ rescue ActiveRecord::RecordInvalid => e
50
+ failure(nil, e.record.errors.full_messages.to_sentence)
51
+ rescue ActiveRecord::Rollback => e
52
+ failure(nil, e.message)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -16,7 +16,7 @@
16
16
  </div>
17
17
  <% else %>
18
18
  <div class="f-fallback">
19
- <%= render 'spree_cm_commissioner/order_mailer/tenant/greeting', order: @order %>
19
+ <%= render 'spree_cm_commissioner/order_mailer/tenant/greeting', order: @order, logo: @logo, name: @name%>
20
20
  <div class="content">
21
21
  <%= render 'spree_cm_commissioner/order_mailer/order_total', order: @order %>
22
22
  <%= render 'spree_cm_commissioner/order_mailer/your_booking', order: @order, show_booking_header: true %>
@@ -74,7 +74,9 @@
74
74
  background-position: center;
75
75
  background-repeat: no-repeat;
76
76
  border-radius: 1.5625rem 1.5625rem 0 0;
77
- background: <%= @brand_color %>;
77
+ <% if @brand_color.present? %>
78
+ background: <%= @brand_color %>;
79
+ <% end %>
78
80
  }
79
81
  #confirm-email #greeting-card-1 p,
80
82
  #confirm-email #greeting-card-1 .header,
@@ -93,21 +95,20 @@
93
95
  margin-bottom: 0.625rem;
94
96
  }
95
97
  #confirm-email .icon-hang-meas {
96
- width: 6.25rem;
97
- height: 6.25rem;
98
- border-radius: 50%;
99
- background-color: #fff;
100
- display: flex;
101
- align-items: center;
102
- justify-content: center;
103
- overflow: hidden;
98
+ width: 50%;
99
+ text-align: right;
104
100
  }
105
-
106
101
  #confirm-email .icon-hang-meas img {
107
- width: 100%;
108
- height: 100%;
109
- object-fit: cover;
102
+ width: 6.25rem;
103
+ height: 6.25rem;
110
104
  border-radius: 50%;
105
+ background-color: #fff;
106
+ display: inline-block;
107
+ }
108
+ #confirm-email .header h1 {
109
+ margin: 0;
110
+ color: #fff;
111
+ width: 50%;
111
112
  }
112
113
 
113
114
  #confirm-email .header {
@@ -1,9 +1,11 @@
1
1
  <div id="greeting-card-1">
2
2
  <div>
3
3
  <div class="header">
4
- <h1><%=@order.tenant.name %></h1>
5
- <% if @vendor_logo_url.present? %>
6
- <img src="<%= @vendor_logo_url %>" alt="Vendor Logo" class="icon-hang-meas">
4
+ <h1><%= name %></h1>
5
+ <% if logo.present? %>
6
+ <div class="icon-hang-meas">
7
+ <img src="<%= logo %>" alt="<%= name %> Logo">
8
+ </div>
7
9
  <% end %>
8
10
  </div>
9
11
  <div class="booking-confirm">
@@ -13,7 +15,7 @@
13
15
  <%= I18n.t('mail.order_mailer.hello', full_name: user_full_name(order)) %>
14
16
  </div>
15
17
  <div class="description">
16
- <%= I18n.t('mail.order_mailer.booking_event', order_number: @order.number || 'NA') %>
18
+ <%= I18n.t('mail.order_mailer.booking_event', order_number: order.number || 'NA') %>
17
19
  </div>
18
20
  </div>
19
21
  </div>
data/config/routes.rb CHANGED
@@ -555,11 +555,7 @@ Spree::Core::Engine.add_routes do
555
555
  resources :trips, only: %i[show]
556
556
 
557
557
  namespace :intercity_taxi do
558
- resources :draft_orders, only: [:create] do
559
- collection do
560
- patch :update
561
- end
562
- end
558
+ resource :draft_orders, only: %i[create update]
563
559
  end
564
560
 
565
561
  resource :reset_passwords, only: [:update]
@@ -587,6 +583,8 @@ Spree::Core::Engine.add_routes do
587
583
  resources :trip_places
588
584
  resources :trip_search, only: [:index]
589
585
  resources :trips, only: %i[show]
586
+ resources :route_places, only: [:index]
587
+ resources :popular_route_places, only: [:index]
590
588
 
591
589
  namespace :queue_cart do
592
590
  resources :line_items, only: [:create]
@@ -701,11 +699,7 @@ Spree::Core::Engine.add_routes do
701
699
  resources :draft_orders, only: %i[create]
702
700
  end
703
701
  namespace :intercity_taxi do
704
- resources :draft_orders, only: [:create] do
705
- collection do
706
- patch :update
707
- end
708
- end
702
+ resource :draft_orders, only: %i[create update]
709
703
  end
710
704
  end
711
705
 
@@ -0,0 +1,17 @@
1
+ class CreateSpreeCmCommissionerPricingModels < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cm_pricing_models, if_not_exists: true do |t|
4
+ t.string :name, null: false
5
+ t.text :description
6
+ t.integer :status, default: 0, null: false
7
+ t.integer :position, null: false, default: 0
8
+
9
+ t.references :vendor, null: false, foreign_key: { to_table: :spree_vendors }
10
+
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :cm_pricing_models, :position unless index_exists?(:cm_pricing_models, :position)
15
+ add_index :cm_pricing_models, :vendor_id unless index_exists?(:cm_pricing_models, :vendor_id)
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ class CreateSpreeCmCommissionerPricingModelVariants < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cm_pricing_model_variants, if_not_exists: true do |t|
4
+ t.references :pricing_model, null: false, foreign_key: { to_table: :cm_pricing_models }
5
+ t.references :variant, null: false, foreign_key: { to_table: :spree_variants }
6
+ t.references :product, null: true, foreign_key: { to_table: :spree_products }
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :cm_pricing_model_variants, [:pricing_model_id, :variant_id], name: 'idx_pm_variants_on_model_variant'
12
+ add_index :cm_pricing_model_variants, [:pricing_model_id, :product_id], name: 'idx_pm_variants_on_model_product'
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ class CreateSpreeCmCommissionerPricingRuleGroups < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cm_pricing_rule_groups, if_not_exists: true do |t|
4
+ t.references :pricing_model, null: false, foreign_key: { to_table: :cm_pricing_models }
5
+ t.string :name
6
+ t.integer :position, default: 0
7
+ t.integer :status, default: 0, null: false
8
+ t.jsonb :public_metadata
9
+ t.jsonb :private_metadata
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :cm_pricing_rule_groups, :pricing_model_id, name: 'idx_rule_groups_on_model'
14
+ add_index :cm_pricing_rule_groups, [:pricing_model_id, :position], name: 'idx_rule_groups_on_model_position'
15
+ end
16
+ end