spree_cm_commissioner 2.3.0.pre.pre20 → 2.3.1.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/app/controllers/spree/admin/product_completion_steps_controller.rb +17 -1
  4. data/app/controllers/spree/admin/tenants_controller.rb +1 -1
  5. data/app/controllers/spree/api/v2/storefront/intercity_taxi/draft_orders_controller.rb +0 -1
  6. data/app/controllers/spree/api/v2/storefront/trip_search_controller.rb +3 -0
  7. data/app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb +41 -0
  8. data/app/controllers/spree/api/v2/tenant/trip_places_controller.rb +48 -0
  9. data/app/controllers/spree/api/v2/tenant/trip_search_controller.rb +103 -0
  10. data/app/controllers/spree/api/v2/tenant/trips_controller.rb +32 -0
  11. data/app/interactors/spree_cm_commissioner/create_ticket.rb +2 -0
  12. data/app/interactors/spree_cm_commissioner/google_routes_distance_calculator.rb +211 -0
  13. data/app/interactors/spree_cm_commissioner/host_matcher.rb +1 -1
  14. data/app/interactors/spree_cm_commissioner/intercity_taxi_order_creator.rb +52 -12
  15. data/app/interactors/spree_cm_commissioner/trip_distance_calculator.rb +165 -0
  16. data/app/interactors/spree_cm_commissioner/vendor_creation_telegram_alert_sender.rb +1 -1
  17. data/app/mailers/spree/order_mailer_decorator.rb +8 -9
  18. data/app/models/concerns/spree_cm_commissioner/order_scopes.rb +4 -5
  19. data/app/models/concerns/spree_cm_commissioner/service_recommendations.rb +2 -2
  20. data/app/models/concerns/spree_cm_commissioner/store_preference.rb +1 -0
  21. data/app/models/spree_cm_commissioner/product_completion_step.rb +4 -1
  22. data/app/models/spree_cm_commissioner/product_completion_step_banner.rb +12 -0
  23. data/app/models/spree_cm_commissioner/product_completion_steps/social_entry_url.rb +86 -19
  24. data/app/models/spree_cm_commissioner/tenant.rb +10 -1
  25. data/app/models/spree_cm_commissioner/vendor_place.rb +10 -1
  26. data/app/overrides/spree/admin/stores/_form/store_preferences.html.erb.deface +9 -0
  27. data/app/queries/spree_cm_commissioner/trip_query.rb +51 -33
  28. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_vehicle_serializer.rb +1 -1
  29. data/app/services/spree_cm_commissioner/intercity_taxi_order/create.rb +8 -0
  30. data/app/services/spree_cm_commissioner/intercity_taxi_order/update.rb +35 -45
  31. data/app/services/spree_cm_commissioner/orders/bulk_archive_inactive_orders.rb +10 -2
  32. data/app/services/spree_cm_commissioner/orders/daily_archive_inactive_orders.rb +8 -0
  33. data/app/services/spree_cm_commissioner/trips/search.rb +7 -11
  34. data/app/views/shared/_asset_field.html.erb +13 -0
  35. data/app/views/spree/admin/product_completion_steps/_form.html.erb +28 -2
  36. data/app/views/spree/admin/product_completion_steps/_supported_fields.html.erb +33 -0
  37. data/app/views/spree/admin/tenants/_form.html.erb +1 -1
  38. data/config/initializers/spree_permitted_attributes.rb +1 -0
  39. data/config/locales/en.yml +4 -0
  40. data/config/locales/km.yml +65 -61
  41. data/config/routes.rb +16 -0
  42. data/db/migrate/20251119093000_add_tenant_id_to_cm_vendor_places.rb +7 -0
  43. data/lib/spree_cm_commissioner/test_helper/factories/product_completion_step_banner_factory.rb +7 -0
  44. data/lib/spree_cm_commissioner/version.rb +1 -1
  45. metadata +12 -2
@@ -1,23 +1,20 @@
1
1
  module SpreeCmCommissioner
2
2
  module IntercityTaxiOrder
3
3
  class Update
4
- attr_reader :order_number, :params
4
+ attr_reader :params
5
5
 
6
- def self.call(order_number:, params:)
7
- new(order_number: order_number, params: params).call
6
+ def self.call(params:)
7
+ new(params: params).call
8
8
  end
9
9
 
10
- def initialize(order_number:, params:)
11
- @order_number = order_number
10
+ def initialize(params:)
12
11
  @params = ensure_parameters(params)
13
12
  end
14
13
 
15
14
  def call
16
- order = Spree::Order.find_by!(number: order_number)
15
+ order = find_order!
17
16
  order.update!(order_params)
18
17
 
19
- create_billing_address_if_missing(order)
20
-
21
18
  order
22
19
  end
23
20
 
@@ -29,48 +26,41 @@ module SpreeCmCommissioner
29
26
  ::ActionController::Parameters.new(params)
30
27
  end
31
28
 
32
- def create_billing_address_if_missing(order)
33
- return if order.bill_address.present?
29
+ def find_order!
30
+ raise(ArgumentError, 'Order token is required') if order_token.blank?
31
+
32
+ Spree::Order.find_by!(token: order_token)
33
+ end
34
34
 
35
- SpreeCmCommissioner::BillingAddressCreator.call(order: order)
35
+ def order_token
36
+ params[:order_token]
36
37
  end
37
38
 
38
39
  def order_params
39
40
  params.require(:order).permit(
40
- :intel_phone_number,
41
- :email,
42
- line_items_attributes: [
43
- :id,
44
- :pickup_place_name,
45
- :drop_off_place_name,
46
- :from_date,
47
- :pickup_lat,
48
- :pickup_lng,
49
- :pickup_oob_confirmed,
50
- :drop_off_lat,
51
- :drop_off_lng,
52
- :drop_off_oob_confirmed,
53
- :distance_km,
54
- :ordered_points,
55
- :base_km,
56
- :detour_pickup_km,
57
- :detour_dropoff_km,
58
- :extra_pickup_km,
59
- :extra_dropoff_km,
60
- :extra_pickup_charge_usd,
61
- :extra_dropoff_charge_usd,
62
- :estimated_time_minutes,
63
- :remark,
64
- :passenger_count,
65
- { guests_attributes: %i[
66
- id
67
- first_name
68
- last_name
69
- gender
70
- nationality_id
71
- age
72
- ]
73
- }
41
+ line_items_attributes: %i[
42
+ id
43
+ pickup_place_name
44
+ drop_off_place_name
45
+ from_date
46
+ pickup_lat
47
+ pickup_lng
48
+ pickup_oob_confirmed
49
+ drop_off_lat
50
+ drop_off_lng
51
+ drop_off_oob_confirmed
52
+ distance_km
53
+ ordered_points
54
+ base_km
55
+ detour_pickup_km
56
+ detour_dropoff_km
57
+ extra_pickup_km
58
+ extra_dropoff_km
59
+ extra_pickup_charge_usd
60
+ extra_dropoff_charge_usd
61
+ estimated_time_minutes
62
+ remark
63
+ passenger_count
74
64
  ]
75
65
  )
76
66
  end
@@ -12,8 +12,8 @@ module SpreeCmCommissioner
12
12
  # - completed_at IS NULL (incomplete/unfinished orders)
13
13
  # - updated_at < 14 days ago (inactive for 2+ weeks)
14
14
  #
15
- # Difference from ArchiveInactiveOrders:
16
- # - ArchiveInactiveOrders: Runs daily, archives only 1-week window (21-14 days)
15
+ # Difference from DailyArchiveInactiveOrders:
16
+ # - DailyArchiveInactiveOrders: Runs daily, archives only 1-week window (21-14 days)
17
17
  # - BulkArchiveInactiveOrders: Manual job, archives ALL orders older than 14 days
18
18
  #
19
19
  # Use case: Bulk cleanup when needed, triggered manually via Sidekiq
@@ -45,6 +45,14 @@ module SpreeCmCommissioner
45
45
 
46
46
  success(archived_count: count)
47
47
  rescue StandardError => e
48
+ CmAppLogger.error(
49
+ label: 'SpreeCmCommissioner::Orders::BulkArchiveInactiveOrders#call failed',
50
+ data: {
51
+ error_class: e.class.name,
52
+ error_message: e.message,
53
+ backtrace: e.backtrace&.first(5)&.join("\n")
54
+ }
55
+ )
48
56
  failure(nil, e.message)
49
57
  end
50
58
  end
@@ -51,6 +51,14 @@ module SpreeCmCommissioner
51
51
 
52
52
  success(archived_count: count)
53
53
  rescue StandardError => e
54
+ CmAppLogger.error(
55
+ label: 'SpreeCmCommissioner::Orders::DailyArchiveInactiveOrders#call failed',
56
+ data: {
57
+ error_class: e.class.name,
58
+ error_message: e.message,
59
+ backtrace: e.backtrace&.first(5)&.join("\n")
60
+ }
61
+ )
54
62
  failure(nil, e.message)
55
63
  end
56
64
  end
@@ -10,21 +10,23 @@ module SpreeCmCommissioner
10
10
  new.send(:cache_key, params, vendor)
11
11
  end
12
12
 
13
- def call(params:, vendor:, is_intercity_taxi: false)
13
+ def call(params:, vendor:)
14
14
  return success(results: []) unless valid_search?(params)
15
15
 
16
16
  cache_key = cache_key(params, vendor)
17
17
 
18
18
  results = Rails.cache.fetch(cache_key, expires_in: SEARCH_CACHE_TTL) do
19
+ route_type = intercity_taxi?(params) ? 'intercity_taxi' : nil
19
20
  trips = SpreeCmCommissioner::TripQuery.new(
20
21
  origin_id: origin_id(params),
21
22
  destination_id: destination_id(params),
23
+ date: search_date(params).to_date,
24
+ route_type: route_type,
22
25
  vendor_id: vendor.id,
23
- number_of_guests: params[:number_of_guests] || 1,
24
- date: search_date(params).to_date
26
+ number_of_guests: params[:number_of_guests] || 1
25
27
  ).call
26
28
 
27
- is_intercity_taxi || taxi?(params) ? filter_intercity(trips) : trips
29
+ trips
28
30
  end
29
31
 
30
32
  success(results: results)
@@ -38,17 +40,11 @@ module SpreeCmCommissioner
38
40
  params[:origin].present? && params[:destination].present? && params[:outbound_date].present?
39
41
  end
40
42
 
41
- def filter_intercity(results)
42
- Array(results).select do |res|
43
- res.respond_to?(:trips) && res.trips.any? { |t| t.route_type.to_s == 'intercity_taxi' }
44
- end
45
- end
46
-
47
43
  def origin_id(params) = outbound?(params) ? params[:origin] : params[:destination]
48
44
  def destination_id(params) = outbound?(params) ? params[:destination] : params[:origin]
49
45
  def search_date(params) = outbound?(params) ? params[:outbound_date] : params[:inbound_date]
50
46
  def outbound?(params) = params[:direction] == 'outbound' || params[:direction].blank?
51
- def taxi?(params) = params[:service_type] == 'intercity_taxi'
47
+ def intercity_taxi?(params) = params[:service_type] == 'intercity_taxi'
52
48
 
53
49
  def cache_key(params, vendor)
54
50
  [
@@ -3,6 +3,8 @@
3
3
  <%# :asset %>
4
4
  <%# :remove_url, optional %>
5
5
  <%# :classes, optional %>
6
+ <%# :aspect_ratio, optional %>
7
+ <%# :size_info, optional %>
6
8
  <%# :form %>
7
9
  <%# :required, optional, default: false %>
8
10
 
@@ -16,6 +18,17 @@
16
18
  class: 'rounded border mb-4 mw-100',
17
19
  style: 'max-height: 100px') if asset.present? && asset.attachment.present? %>
18
20
 
21
+ <% if defined?(aspect_ratio) || defined?(size_info) %>
22
+ <small class="mb-2 form-text text-muted d-block">
23
+ <% if defined?(aspect_ratio) && aspect_ratio.present? %>
24
+ <strong>Aspect Ratio:</strong> <%= aspect_ratio %><br>
25
+ <% end %>
26
+ <% if defined?(size_info) && size_info.present? %>
27
+ <strong>Recommended Size:</strong> <%= size_info %>
28
+ <% end %>
29
+ </small>
30
+ <% end %>
31
+
19
32
  <div data-hook="file" class="form-group">
20
33
  <%= form.label field, label || Spree.t(field) %>
21
34
  <%= form.file_field field, required: required %>
@@ -1,7 +1,7 @@
1
1
  <div data-hook="admin_product_completion_step_form_fields">
2
2
  <div data-hook="product_completion_step" class="row">
3
3
  <div class="col-12 col-md-6">
4
- <div class="card mb-3">
4
+ <div class="mb-3 card">
5
5
  <div class="card-header">
6
6
  <h5 class="mb-0"><%= Spree.t(:settings) %></h5>
7
7
  </div>
@@ -32,7 +32,7 @@
32
32
  </div>
33
33
 
34
34
  <div class="col-12 col-md-6">
35
- <div class="card mb-3">
35
+ <div class="mb-3 card">
36
36
  <div class="card-header">
37
37
  <h5 class="mb-0"><%= Spree.t(:completion_settings) %></h5>
38
38
  </div>
@@ -49,6 +49,32 @@
49
49
  </div>
50
50
  </div>
51
51
  </div>
52
+
53
+ <div class="mb-3 card">
54
+ <div class="card-header">
55
+ <h5 class="mb-0"><%= Spree.t(:banner) %></h5>
56
+ </div>
57
+ <div class="card-body">
58
+ <%= render 'shared/asset_field',
59
+ field: :banner,
60
+ label: Spree.t(:banner),
61
+ asset: @object.banner,
62
+ remove_url: (@object.banner.present? ? remove_banner_admin_product_product_completion_step_url(@object.product, @object) : nil),
63
+ form: f,
64
+ size_info: 'Min: 480x270, Max: 960x540',
65
+ aspect_ratio: '16x9',
66
+ classes: ['col-md-12']
67
+ %>
68
+ </div>
69
+ </div>
52
70
  </div>
53
71
  </div>
72
+
73
+ <% if @object.is_a?(SpreeCmCommissioner::ProductCompletionSteps::SocialEntryUrl) %>
74
+ <div class="row mt-3">
75
+ <div class="col-12">
76
+ <%= render 'supported_fields' %>
77
+ </div>
78
+ </div>
79
+ <% end %>
54
80
  </div>
@@ -0,0 +1,33 @@
1
+ <div class="mb-3 card">
2
+ <div class="card-header">
3
+ <h5 class="mb-0">Supported Placeholder Fields</h5>
4
+ </div>
5
+ <div class="card-body">
6
+ <p class="text-muted mb-3">Use these placeholders in your entry point link template:</p>
7
+
8
+ <% if @object.is_a?(SpreeCmCommissioner::ProductCompletionSteps::SocialEntryUrl) && @object.supported_fields.present? %>
9
+ <% @object.supported_fields.each do |category, fields| %>
10
+ <div class="mb-3">
11
+ <h6 class="fw-bold text-capitalize">
12
+ <%= category.to_s.humanize %>
13
+ <span class="badge bg-secondary"><%= fields.count %></span>
14
+ </h6>
15
+ <div class="field-list">
16
+ <% fields.each do |field| %>
17
+ <div class="field-item d-inline-block me-2 mb-2">
18
+ <code class="bg-light p-2 rounded">
19
+ {<%= category %><%= category == :guests ? '[index]' : '' %>.<%=field %>}
20
+ </code>
21
+ </div>
22
+ <% end %>
23
+ </div>
24
+ </div>
25
+ <% end %>
26
+
27
+ <div class="alert alert-info mt-3">
28
+ <strong>Example:</strong><br>
29
+ <code>https://example.com?order={order.number}&name={bill_address.first_name}&guest={guests[0].first_name}</code>
30
+ </div>
31
+ <% end %>
32
+ </div>
33
+ </div>
@@ -36,7 +36,7 @@
36
36
  <div class="col-12">
37
37
  <%= f.field_container :host do %>
38
38
  <%= f.label :host, raw(Spree.t(:host) + required_span_tag) %>
39
- <%= f.text_field :host, required: true, class: 'form-control', placeholder: 'host' %>
39
+ <%= f.text_field :host, required: true, class: 'form-control', placeholder: 'example.com' %>
40
40
  <% if f.object.errors[:host].any? %>
41
41
  <div class="error text-danger"><%= f.object.errors[:host].join(', ') %></div>
42
42
  <% end %>
@@ -48,6 +48,7 @@ module Spree
48
48
  :preferred_sms_sender_id,
49
49
  :preferred_telegram_order_alert_chat_id,
50
50
  :preferred_telegram_order_request_alert_chat_id,
51
+ :preferred_telegram_new_vendor_alert_chat_id,
51
52
  :preferred_assetlinks,
52
53
  :preferred_apple_app_site_association,
53
54
  { default_notification_image_attributes: {} },
@@ -509,6 +509,10 @@ en:
509
509
  attributes:
510
510
  place_id:
511
511
  taken: "has already existed with this place type"
512
+ spree_cm_commissioner/tenant:
513
+ attributes:
514
+ host:
515
+ format: "must not include protocol (http:// or https://)"
512
516
 
513
517
  mail:
514
518
  order_mailer:
@@ -370,6 +370,10 @@ km:
370
370
  attributes:
371
371
  exception_rules:
372
372
  invalid_json: "Format មិនត្រឹមត្រូវ"
373
+ spree_cm_commissioner/tenant:
374
+ attributes:
375
+ host:
376
+ format: "មិនអនុញ្ញាតឱ្យបញ្ចូលឈ្មោះដែលភ្ជាប់ជាមួយ (http:// ឬ https://)"
373
377
 
374
378
  mail:
375
379
  order_mailer:
@@ -469,64 +473,64 @@ km:
469
473
 
470
474
  blazer:
471
475
  columns:
472
- 'No.': "លេខរៀង"
473
- 'Reservation No.': "លេខកក់"
474
- 'Direction': "ទិសដៅ"
475
- 'Vehicle type': "ប្រភេទយានយន្ត"
476
- 'Seller': "អ្នកលក់"
477
- 'Paid to': "បង់ទៅ"
478
- 'Branch': "សាខា"
479
- 'Gateway': "ច្រកទ្វារ"
480
- 'Departure': "ចេញដំណើរ"
481
- 'Issued': "ចេញឲ្យ"
482
- 'Paid': "បានបង់"
483
- '# of seats': "ចំនួនកៅអី"
484
- 'Source': "ប្រភព"
485
- 'Status': "ស្ថានភាព"
486
- 'Fare': "តម្លៃឈ្នួល"
487
- 'Discount': "ការបញ្ចុះតម្លៃ"
488
- 'Commission': "កម្រៃជើងសារ"
489
- 'Amount': "ចំនួនទឹកប្រាក់"
490
- 'Metric': "រង្វាស់"
491
- 'Value': "តម្លៃ"
492
- 'Group': "ក្រុម"
493
- 'Orders': "ការបញ្ជាទិញ"
494
- 'Passengers': "អ្នកដំណើរ"
495
- 'Total fare': "តម្លៃឈ្នួលសរុប"
496
- 'Total discount': "ការបញ្ចុះតម្លៃសរុប"
497
- 'Total commission': "កម្រៃជើងសារសរុប"
498
- 'Total amount': "ចំនួនទឹកប្រាក់សរុប"
499
- 'Trip ID': "លេខសម្គាល់ជើងដំណើរ"
500
- 'Route': "ផ្លូវ"
501
- 'Origin': "ទីតាំងដើម"
502
- 'Destination': "ទីតាំងគោលដៅ"
503
- 'Departure Time': "ម៉ោងចេញដំណើរ"
504
- 'Vehicle': "យានយន្ត"
505
- 'Total Seats': "ចំនួនកៅអីសរុប"
506
- 'Bookings': "ការកក់"
507
- 'Seats Sold': "កៅអីលក់បាន"
508
- 'Occupancy %': "ភាគរយនៃការកាន់កាប់"
509
- 'Total Revenue': "ចំណូលសរុប"
510
- 'Avg Ticket Price': "តម្លៃសំបុត្រជាមធ្យម"
511
- 'Date': "កាលបរិច្ឆេទ"
512
- 'Time': "ម៉ោង"
513
- 'From': "ពី"
514
- 'To': "ទៅ"
515
- 'Capacity': "ចំណុះ"
516
- 'Available': "ទំនេរ"
517
- 'Filled %': "ភាគរយនៃការបំពេញ"
518
- 'Vehicle Code': "លេខកូដយានយន្ត"
519
- 'Plate': "ស្លាកលេខ"
520
- 'Type': "ប្រភេទ"
521
- 'Total Trips': "ចំនួនជើងដំណើរ​សរុប"
522
- 'Trips with Bookings': "ជើងដំណើរ​មានការកក់"
523
- 'Total Bookings': "ចំនួនការកក់​សរុប"
524
- 'Total Passengers': "ចំនួនអ្នកដំណើរ​សរុប"
525
- 'Avg Occupancy %': "ភាគរយនៃការកាន់កាប់​ជាមធ្យម"
526
- 'Lead Time': "រយៈពេលនៃការរង់ចាំ"
527
- 'Revenue': "ចំណូល"
528
- 'Avg Days in Advance': "ចំនួនថ្ងៃជាមធ្យមមុន"
529
- 'Current Period': "រយៈពេលបច្ចុប្បន្ន"
530
- 'Previous Period': "រយៈពេលមុន"
531
- 'Change': "បំលាស់ប្តូរ"
532
- 'Change %': "ភាគរយនៃបំលាស់ប្តូរ"
476
+ "No.": "លេខរៀង"
477
+ "Reservation No.": "លេខកក់"
478
+ "Direction": "ទិសដៅ"
479
+ "Vehicle type": "ប្រភេទយានយន្ត"
480
+ "Seller": "អ្នកលក់"
481
+ "Paid to": "បង់ទៅ"
482
+ "Branch": "សាខា"
483
+ "Gateway": "ច្រកទ្វារ"
484
+ "Departure": "ចេញដំណើរ"
485
+ "Issued": "ចេញឲ្យ"
486
+ "Paid": "បានបង់"
487
+ "# of seats": "ចំនួនកៅអី"
488
+ "Source": "ប្រភព"
489
+ "Status": "ស្ថានភាព"
490
+ "Fare": "តម្លៃឈ្នួល"
491
+ "Discount": "ការបញ្ចុះតម្លៃ"
492
+ "Commission": "កម្រៃជើងសារ"
493
+ "Amount": "ចំនួនទឹកប្រាក់"
494
+ "Metric": "រង្វាស់"
495
+ "Value": "តម្លៃ"
496
+ "Group": "ក្រុម"
497
+ "Orders": "ការបញ្ជាទិញ"
498
+ "Passengers": "អ្នកដំណើរ"
499
+ "Total fare": "តម្លៃឈ្នួលសរុប"
500
+ "Total discount": "ការបញ្ចុះតម្លៃសរុប"
501
+ "Total commission": "កម្រៃជើងសារសរុប"
502
+ "Total amount": "ចំនួនទឹកប្រាក់សរុប"
503
+ "Trip ID": "លេខសម្គាល់ជើងដំណើរ"
504
+ "Route": "ផ្លូវ"
505
+ "Origin": "ទីតាំងដើម"
506
+ "Destination": "ទីតាំងគោលដៅ"
507
+ "Departure Time": "ម៉ោងចេញដំណើរ"
508
+ "Vehicle": "យានយន្ត"
509
+ "Total Seats": "ចំនួនកៅអីសរុប"
510
+ "Bookings": "ការកក់"
511
+ "Seats Sold": "កៅអីលក់បាន"
512
+ "Occupancy %": "ភាគរយនៃការកាន់កាប់"
513
+ "Total Revenue": "ចំណូលសរុប"
514
+ "Avg Ticket Price": "តម្លៃសំបុត្រជាមធ្យម"
515
+ "Date": "កាលបរិច្ឆេទ"
516
+ "Time": "ម៉ោង"
517
+ "From": "ពី"
518
+ "To": "ទៅ"
519
+ "Capacity": "ចំណុះ"
520
+ "Available": "ទំនេរ"
521
+ "Filled %": "ភាគរយនៃការបំពេញ"
522
+ "Vehicle Code": "លេខកូដយានយន្ត"
523
+ "Plate": "ស្លាកលេខ"
524
+ "Type": "ប្រភេទ"
525
+ "Total Trips": "ចំនួនជើងដំណើរ​សរុប"
526
+ "Trips with Bookings": "ជើងដំណើរ​មានការកក់"
527
+ "Total Bookings": "ចំនួនការកក់​សរុប"
528
+ "Total Passengers": "ចំនួនអ្នកដំណើរ​សរុប"
529
+ "Avg Occupancy %": "ភាគរយនៃការកាន់កាប់​ជាមធ្យម"
530
+ "Lead Time": "រយៈពេលនៃការរង់ចាំ"
531
+ "Revenue": "ចំណូល"
532
+ "Avg Days in Advance": "ចំនួនថ្ងៃជាមធ្យមមុន"
533
+ "Current Period": "រយៈពេលបច្ចុប្បន្ន"
534
+ "Previous Period": "រយៈពេលមុន"
535
+ "Change": "បំលាស់ប្តូរ"
536
+ "Change %": "ភាគរយនៃបំលាស់ប្តូរ"
data/config/routes.rb CHANGED
@@ -163,6 +163,10 @@ Spree::Core::Engine.add_routes do
163
163
  collection do
164
164
  post :update_positions
165
165
  end
166
+
167
+ member do
168
+ delete :remove_banner
169
+ end
166
170
  end
167
171
 
168
172
  resources :product_places do
@@ -546,6 +550,18 @@ Spree::Core::Engine.add_routes do
546
550
  resources :guest_card_classes
547
551
  resources :tickets, only: :index
548
552
 
553
+ resources :trip_places, only: :index
554
+ resources :trip_search, only: [:index]
555
+ resources :trips, only: %i[show]
556
+
557
+ namespace :intercity_taxi do
558
+ resources :draft_orders, only: [:create] do
559
+ collection do
560
+ patch :update
561
+ end
562
+ end
563
+ end
564
+
549
565
  resource :reset_passwords, only: [:update]
550
566
  resource :change_passwords, only: [:update]
551
567
  resource :user_contacts, only: [:update]
@@ -0,0 +1,7 @@
1
+ class AddTenantIdToCmVendorPlaces < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :cm_vendor_places, :tenant_id, :integer, if_not_exists: true
4
+ add_index :cm_vendor_places, :tenant_id, if_not_exists: true
5
+ add_index :cm_vendor_places, %i[tenant_id vendor_id], if_not_exists: true, name: 'index_cm_vendor_places_on_tenant_and_vendor'
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :cm_product_completion_step_banner, class: SpreeCmCommissioner::ProductCompletionStepBanner do
3
+ viewable_type { 'SpreeCmCommissioner::ProductCompletionStep' }
4
+ viewable_id { nil }
5
+ attachment { Rack::Test::UploadedFile.new(Spree::Core::Engine.root.join('spec', 'fixtures', 'files', 'icon_256x256.png'), 'image/*') }
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '2.3.0-pre20'.freeze
2
+ VERSION = '2.3.1.pre.pre1'.freeze
3
3
 
4
4
  module_function
5
5
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_cm_commissioner
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0.pre.pre20
4
+ version: 2.3.1.pre.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-13 00:00:00.000000000 Z
11
+ date: 2025-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -1013,6 +1013,7 @@ files:
1013
1013
  - app/controllers/spree/api/v2/tenant/guests_controller.rb
1014
1014
  - app/controllers/spree/api/v2/tenant/homepage_sections_controller.rb
1015
1015
  - app/controllers/spree/api/v2/tenant/id_cards_controller.rb
1016
+ - app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb
1016
1017
  - app/controllers/spree/api/v2/tenant/line_items_controller.rb
1017
1018
  - app/controllers/spree/api/v2/tenant/notifications_controller.rb
1018
1019
  - app/controllers/spree/api/v2/tenant/order_histories_controller.rb
@@ -1025,6 +1026,9 @@ files:
1025
1026
  - app/controllers/spree/api/v2/tenant/s3_signed_urls_controller.rb
1026
1027
  - app/controllers/spree/api/v2/tenant/taxons_controller.rb
1027
1028
  - app/controllers/spree/api/v2/tenant/tickets_controller.rb
1029
+ - app/controllers/spree/api/v2/tenant/trip_places_controller.rb
1030
+ - app/controllers/spree/api/v2/tenant/trip_search_controller.rb
1031
+ - app/controllers/spree/api/v2/tenant/trips_controller.rb
1028
1032
  - app/controllers/spree/api/v2/tenant/user_account_linkages_controller.rb
1029
1033
  - app/controllers/spree/api/v2/tenant/user_contacts_controller.rb
1030
1034
  - app/controllers/spree/api/v2/tenant/user_device_tokens_controller.rb
@@ -1182,6 +1186,7 @@ files:
1182
1186
  - app/interactors/spree_cm_commissioner/firebase_email_fetcher_cron_executor.rb
1183
1187
  - app/interactors/spree_cm_commissioner/firebase_id_token_provider.rb
1184
1188
  - app/interactors/spree_cm_commissioner/google_places_fetcher.rb
1189
+ - app/interactors/spree_cm_commissioner/google_routes_distance_calculator.rb
1185
1190
  - app/interactors/spree_cm_commissioner/guest_dynamic_field_notification_sender.rb
1186
1191
  - app/interactors/spree_cm_commissioner/guest_dynamic_fields_manager.rb
1187
1192
  - app/interactors/spree_cm_commissioner/guest_id_card_manager.rb
@@ -1252,6 +1257,7 @@ files:
1252
1257
  - app/interactors/spree_cm_commissioner/transactional_email_sender.rb
1253
1258
  - app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb
1254
1259
  - app/interactors/spree_cm_commissioner/trip_clone_creator.rb
1260
+ - app/interactors/spree_cm_commissioner/trip_distance_calculator.rb
1255
1261
  - app/interactors/spree_cm_commissioner/trip_stops_creator.rb
1256
1262
  - app/interactors/spree_cm_commissioner/unique_device_token_cron_executor.rb
1257
1263
  - app/interactors/spree_cm_commissioner/update_payment_gateway_status.rb
@@ -1482,6 +1488,7 @@ files:
1482
1488
  - app/models/spree_cm_commissioner/place.rb
1483
1489
  - app/models/spree_cm_commissioner/price_decorator.rb
1484
1490
  - app/models/spree_cm_commissioner/product_completion_step.rb
1491
+ - app/models/spree_cm_commissioner/product_completion_step_banner.rb
1485
1492
  - app/models/spree_cm_commissioner/product_completion_steps/chatrace_telegram.rb
1486
1493
  - app/models/spree_cm_commissioner/product_completion_steps/social_entry_url.rb
1487
1494
  - app/models/spree_cm_commissioner/product_decorator.rb
@@ -2099,6 +2106,7 @@ files:
2099
2106
  - app/views/spree/admin/orders/notifications.html.erb
2100
2107
  - app/views/spree/admin/product_commissions/index.html.erb
2101
2108
  - app/views/spree/admin/product_completion_steps/_form.html.erb
2109
+ - app/views/spree/admin/product_completion_steps/_supported_fields.html.erb
2102
2110
  - app/views/spree/admin/product_completion_steps/edit.html.erb
2103
2111
  - app/views/spree/admin/product_completion_steps/index.html.erb
2104
2112
  - app/views/spree/admin/product_completion_steps/new.html.erb
@@ -2848,6 +2856,7 @@ files:
2848
2856
  - db/migrate/20251009073040_add_lock_version_to_cm_routes.rb
2849
2857
  - db/migrate/20251009073929_add_lock_version_to_cm_vendor_routes.rb
2850
2858
  - db/migrate/20251113081853_add_index_to_spree_orders_updated_at.rb
2859
+ - db/migrate/20251119093000_add_tenant_id_to_cm_vendor_places.rb
2851
2860
  - docker-compose.yml
2852
2861
  - docs/api/scoped-access-token-endpoints.md
2853
2862
  - docs/option_types/attr_types.md
@@ -2920,6 +2929,7 @@ files:
2920
2929
  - lib/spree_cm_commissioner/test_helper/factories/permission.rb
2921
2930
  - lib/spree_cm_commissioner/test_helper/factories/pin_code_factory.rb
2922
2931
  - lib/spree_cm_commissioner/test_helper/factories/place_factory.rb
2932
+ - lib/spree_cm_commissioner/test_helper/factories/product_completion_step_banner_factory.rb
2923
2933
  - lib/spree_cm_commissioner/test_helper/factories/product_completion_step_factory.rb
2924
2934
  - lib/spree_cm_commissioner/test_helper/factories/product_factory.rb
2925
2935
  - lib/spree_cm_commissioner/test_helper/factories/products_taxons_factory.rb