spree_cm_commissioner 2.5.0.pre.pre13 → 2.5.0.pre.pre14
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/.env.example +4 -0
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/admin/base_controller_decorator.rb +7 -33
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +7 -51
- data/app/controllers/spree/api/v2/storefront/intercity_taxi/distance_calculator_controller.rb +47 -0
- data/app/controllers/spree/api/v2/storefront/intercity_taxi/draft_orders_controller.rb +7 -5
- data/app/controllers/spree/api/v2/storefront/trip_search_controller.rb +2 -2
- data/app/controllers/spree/api/v2/tenant/intercity_taxi/distance_calculator_controller.rb +47 -0
- data/app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb +7 -5
- data/app/controllers/spree/api/v2/tenant/trip_search_controller.rb +2 -2
- data/app/interactors/spree_cm_commissioner/google_routes_distance_calculator.rb +0 -13
- data/app/interactors/spree_cm_commissioner/invalidate_cache_request.rb +3 -3
- data/app/interactors/spree_cm_commissioner/vehicle_type_updater.rb +41 -0
- data/app/jobs/spree_cm_commissioner/invalidate_cache_request_job.rb +1 -1
- data/app/mailers/spree/order_mailer_decorator.rb +22 -1
- data/app/models/concerns/spree_cm_commissioner/line_item_seat_selection.rb +40 -0
- data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +1 -1
- data/app/models/concerns/spree_cm_commissioner/vehicle_kind.rb +21 -0
- data/app/models/spree_cm_commissioner/adjustable/adjuster/pricing_action.rb +25 -0
- data/app/models/spree_cm_commissioner/guest.rb +1 -1
- data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +3 -0
- data/app/models/spree_cm_commissioner/homepage_background_app_image.rb +1 -1
- data/app/models/spree_cm_commissioner/invite_guest.rb +2 -5
- data/app/models/spree_cm_commissioner/line_item_decorator.rb +2 -2
- data/app/models/spree_cm_commissioner/option_type_decorator.rb +4 -1
- data/app/models/spree_cm_commissioner/option_value_decorator.rb +4 -1
- data/app/models/spree_cm_commissioner/{option_value_vehicle.rb → option_value_vehicle_type.rb} +2 -2
- data/app/models/spree_cm_commissioner/trip.rb +7 -6
- data/app/models/spree_cm_commissioner/vehicle.rb +8 -20
- data/app/models/spree_cm_commissioner/vehicle_type.rb +28 -0
- data/app/models/spree_cm_commissioner/vehicle_type_option_type.rb +6 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -0
- data/app/overrides/spree/admin/products/edit/clear_cache_button.html.erb.deface +1 -1
- data/app/overrides/spree/admin/taxons/edit/clear_cache_button.html.erb.deface +3 -2
- data/app/queries/spree_cm_commissioner/trip_query.rb +5 -5
- data/app/request_schemas/spree_cm_commissioner/intercity_taxi_draft_order_update_schema.rb +2 -0
- data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +12 -0
- data/app/serializers/spree/v2/tenant/line_item_serializer.rb +14 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/distance_serializer.rb +26 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/intercity_taxi_line_item_serializer.rb +3 -3
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_result_serializer.rb +2 -2
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_serializer.rb +1 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/{trip_vehicle_serializer.rb → trip_vehicle_type_serializer.rb} +2 -4
- data/app/services/spree_cm_commissioner/api_caches/invalidate.rb +98 -0
- data/app/services/spree_cm_commissioner/calculate_distance.rb +279 -0
- data/app/services/spree_cm_commissioner/cart/recalculate_decorator.rb +28 -1
- data/app/services/spree_cm_commissioner/guests/claim_invite_guest_service.rb +65 -0
- data/app/services/spree_cm_commissioner/intercity_taxi_order/calculate_distance.rb +224 -0
- data/app/services/spree_cm_commissioner/intercity_taxi_order/update.rb +30 -3
- data/app/services/spree_cm_commissioner/line_items/apply_pricing_models.rb +27 -0
- data/app/services/spree_cm_commissioner/pricing_models/apply.rb +4 -12
- data/app/services/spree_cm_commissioner/signing/sign_data.rb +42 -0
- data/app/services/spree_cm_commissioner/signing/verify_signature.rb +52 -0
- data/app/services/spree_cm_commissioner/transit/export_order.rb +146 -0
- data/app/services/spree_cm_commissioner/update_guest_service.rb +129 -0
- data/app/views/spree/admin/homepage_section/edit.html.erb +7 -2
- data/app/views/spree/order_mailer/cancel_email.html.erb +19 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/_cancel_email.html.erb +12 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/_footer.html.erb +8 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/_header.html.erb +3 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/_mailer_stylesheets.html.erb +139 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/_your_booking.html.erb +8 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/purchased_items/_items.html.erb +53 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/purchased_items/_summary.html.erb +108 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_cancel_email.html.erb +12 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_footer.html.erb +8 -0
- data/app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_header.html.erb +15 -0
- data/app/views/spree_cm_commissioner/layouts/cancel_order_mailer.html.erb +16 -0
- data/config/locales/en.yml +15 -0
- data/config/locales/km.yml +27 -2
- data/config/routes.rb +2 -0
- data/db/migrate/20251127074809_change_guest_dynamic_fields_value_from_jsonb_to_text.rb +40 -0
- data/db/migrate/20251219035243_add_migrations_to_support_vehicle_types.rb +36 -0
- data/lib/spree_cm_commissioner/distance.rb +88 -0
- data/lib/spree_cm_commissioner/engine.rb +3 -0
- data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +2 -2
- data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +3 -3
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_model_variant_factory.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +1 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +4 -1
- data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +7 -0
- data/lib/spree_cm_commissioner/trip_query_result.rb +1 -1
- data/lib/spree_cm_commissioner/trip_result.rb +7 -1
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +1 -1
- metadata +39 -10
- data/app/interactors/spree_cm_commissioner/trip_distance_calculator.rb +0 -165
- data/app/interactors/spree_cm_commissioner/vehicle_updater.rb +0 -41
- data/app/models/concerns/spree_cm_commissioner/vehicle_type.rb +0 -11
- data/app/models/spree_cm_commissioner/vehicle_option_type.rb +0 -6
- data/lib/spree_cm_commissioner/intercity_taxi/distance.rb +0 -38
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_route_factory.rb +0 -7
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<table class="purchase purchase-summary">
|
|
2
|
+
<tr>
|
|
3
|
+
<td valign="middle" colspan="2">
|
|
4
|
+
<p class="f-fallback purchase_total purchase_total--label">
|
|
5
|
+
<%= Spree.t('order_mailer.subtotal') %>
|
|
6
|
+
</p>
|
|
7
|
+
</td>
|
|
8
|
+
<td valign="middle">
|
|
9
|
+
<p class="f-fallback purchase_total align-right">
|
|
10
|
+
<%= order.display_item_total %>
|
|
11
|
+
</p>
|
|
12
|
+
</td>
|
|
13
|
+
</tr>
|
|
14
|
+
<% if order.line_item_adjustments.exists? %>
|
|
15
|
+
<% if order.all_adjustments.promotion.eligible.exists? %>
|
|
16
|
+
<% order.all_adjustments.promotion.eligible.group_by(&:label).each do |label, adjustments| %>
|
|
17
|
+
<tr class="purchase-summary-item">
|
|
18
|
+
<td class="purchase_footer" valign="middle">
|
|
19
|
+
<p class="f-fallback purchase_total purchase_total--label">
|
|
20
|
+
<%= Spree.t(:promotion) %>
|
|
21
|
+
</p>
|
|
22
|
+
</td>
|
|
23
|
+
<td class="purchase_footer" valign="middle">
|
|
24
|
+
<p class="f-fallback purchase_total--name purchase_total--label">
|
|
25
|
+
<%= label %>
|
|
26
|
+
</p>
|
|
27
|
+
</td>
|
|
28
|
+
<td class="purchase_footer" valign="middle">
|
|
29
|
+
<p class="f-fallback purchase_total align-right">
|
|
30
|
+
<%= Spree::Money.new(adjustments.sum(&:amount), currency: order.currency) %>
|
|
31
|
+
</p>
|
|
32
|
+
</td>
|
|
33
|
+
</tr>
|
|
34
|
+
<% end %>
|
|
35
|
+
<% end %>
|
|
36
|
+
<% end %>
|
|
37
|
+
<% order.shipments.group_by { |s| s.selected_shipping_rate&.name }.each do |name, shipments| %>
|
|
38
|
+
<tr class="purchase-summary-item">
|
|
39
|
+
<td class="purchase_footer" valign="middle">
|
|
40
|
+
<p class="f-fallback purchase_total purchase_total--label">
|
|
41
|
+
<%= Spree.t(:shipping) %>
|
|
42
|
+
</p>
|
|
43
|
+
</td>
|
|
44
|
+
<td class="purchase_footer" valign="middle">
|
|
45
|
+
<p class="f-fallback purchase_total--name purchase_total--label">
|
|
46
|
+
<%= name %>
|
|
47
|
+
</p>
|
|
48
|
+
</td>
|
|
49
|
+
<td class="purchase_footer" valign="middle">
|
|
50
|
+
<p class="f-fallback purchase_total align-right">
|
|
51
|
+
<%= Spree::Money.new(shipments.sum(&:discounted_cost), currency: order.currency) %>
|
|
52
|
+
</p>
|
|
53
|
+
</td>
|
|
54
|
+
</tr>
|
|
55
|
+
<%end%>
|
|
56
|
+
<% if order.additional_tax_total != 0 %>
|
|
57
|
+
<tr class="purchase-summary-item">
|
|
58
|
+
<td class="purchase_footer" valign="middle" colspan="2">
|
|
59
|
+
<p class="f-fallback purchase_total purchase_total--label">
|
|
60
|
+
<%= Spree.t(:tax) %>
|
|
61
|
+
</p>
|
|
62
|
+
</td>
|
|
63
|
+
<td class="purchase_footer" valign="middle">
|
|
64
|
+
<p class="f-fallback purchase_total align-right">
|
|
65
|
+
<%= order.display_additional_tax_total.to_html %>
|
|
66
|
+
</p>
|
|
67
|
+
</td>
|
|
68
|
+
</tr>
|
|
69
|
+
<% end %>
|
|
70
|
+
|
|
71
|
+
<% order.adjustments.eligible.each do |adjustment| %>
|
|
72
|
+
<% next if (adjustment.source_type == 'Spree::TaxRate') || (adjustment.amount == 0) %>
|
|
73
|
+
<tr>
|
|
74
|
+
<td class="purchase_footer" valign="middle">
|
|
75
|
+
<p class="f-fallback purchase_total purchase_total--label">
|
|
76
|
+
<%= Spree.t(:adjustments) %>
|
|
77
|
+
</p>
|
|
78
|
+
</td>
|
|
79
|
+
<td class="purchase_footer" valign="middle">
|
|
80
|
+
<p class="f-fallback purchase_total--name purchase_total--label">
|
|
81
|
+
<%= raw(adjustment.label) %>:
|
|
82
|
+
</p>
|
|
83
|
+
</td>
|
|
84
|
+
<td class="purchase_total-col align-right">
|
|
85
|
+
<p class="f-fallback purchase_total">
|
|
86
|
+
<%= Spree::Money.new(adjustment.amount, currency: order.currency) %>
|
|
87
|
+
</p>
|
|
88
|
+
</td>
|
|
89
|
+
</tr>
|
|
90
|
+
<% end %>
|
|
91
|
+
<tr>
|
|
92
|
+
<td class="purchase_footer" colspan="2">
|
|
93
|
+
<p class="f-fallback purchase_total purchase_total--label">
|
|
94
|
+
<strong><%= I18n.t('mail.order_mailer.etotal') %></strong> (<%= I18n.t('mail.order_mailer.including_vat') %>)
|
|
95
|
+
</p>
|
|
96
|
+
</td>
|
|
97
|
+
<td class="purchase_total-col align-right">
|
|
98
|
+
<p class="f-fallback purchase_total">
|
|
99
|
+
<strong><%= order.display_total %></strong>
|
|
100
|
+
</p>
|
|
101
|
+
</td>
|
|
102
|
+
</tr>
|
|
103
|
+
<tr>
|
|
104
|
+
<td colspan="4">
|
|
105
|
+
<hr style="border-top-width: 1px; border-top-color: #E5E7EB; height: 0; margin: 1.5rem 0 0; border-style: solid none none;" />
|
|
106
|
+
</td>
|
|
107
|
+
</tr>
|
|
108
|
+
</table>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<div class="cancel-greeting">
|
|
2
|
+
<h1>
|
|
3
|
+
<%= I18n.t('mail.order_mailer.hello', full_name: user_full_name(order))%>
|
|
4
|
+
</h1>
|
|
5
|
+
<p class="description">
|
|
6
|
+
<%= I18n.t('mail.order_mailer.cancel_description') %>
|
|
7
|
+
</p>
|
|
8
|
+
<b>
|
|
9
|
+
<%= I18n.t('mail.order_mailer.order_cancelled', order_number: order.number || 'NA') %>
|
|
10
|
+
</b>
|
|
11
|
+
<div style="border-bottom: 1px solid #E5E7EB; margin-top: 1.5rem;">
|
|
12
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<div class="header-tenant">
|
|
2
|
+
<table width="100%" cellpadding="0" cellspacing="0">
|
|
3
|
+
<tr>
|
|
4
|
+
<td class="tenant-name">
|
|
5
|
+
<%= name %>
|
|
6
|
+
</td>
|
|
7
|
+
|
|
8
|
+
<% if logo.present? %>
|
|
9
|
+
<td class="logo-tenant" align="right">
|
|
10
|
+
<img src="<%= logo %>">
|
|
11
|
+
</td>
|
|
12
|
+
<% end %>
|
|
13
|
+
</tr>
|
|
14
|
+
</table>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
5
|
+
<meta name="x-apple-disable-message-reformatting"/>
|
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
|
7
|
+
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
|
|
8
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
9
|
+
<%= render partial: 'spree_cm_commissioner/cancel_order_mailer/mailer_stylesheets' %>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="100%">
|
|
13
|
+
<%= yield %>
|
|
14
|
+
</table>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
data/config/locales/en.yml
CHANGED
|
@@ -119,6 +119,17 @@ en:
|
|
|
119
119
|
product_kind_option_types:
|
|
120
120
|
empty_info: "<b>Note:</b> Set service option types to service first. To edit, go to <b>Details</b> tab > <b>Option Types</b>"
|
|
121
121
|
|
|
122
|
+
vehicle_type:
|
|
123
|
+
suv: "SUV"
|
|
124
|
+
sedan: "Sedan"
|
|
125
|
+
van: "Van"
|
|
126
|
+
minivan: "Minivan"
|
|
127
|
+
sleeping_bus: "Sleeping Bus"
|
|
128
|
+
luxury_van: "Luxury Van"
|
|
129
|
+
air_bus: "Air Bus"
|
|
130
|
+
bus: "Bus"
|
|
131
|
+
ferry: "Ferry"
|
|
132
|
+
|
|
122
133
|
line_item:
|
|
123
134
|
validation:
|
|
124
135
|
exceeded_max_quantity_per_order: "Exceeded maximum quantity per order"
|
|
@@ -528,6 +539,10 @@ en:
|
|
|
528
539
|
hello: "Hello %{full_name},"
|
|
529
540
|
thanks: "Thanks %{full_name},"
|
|
530
541
|
booking_event: "Your booking for %{order_number} is successfully complete!"
|
|
542
|
+
cancel_description: "Your order has been CANCELED. Please retain this cancellation information for your records."
|
|
543
|
+
order_cancelled: "Order %{order_number} Summary [CANCELED]"
|
|
544
|
+
cancel_thank: "Thank you for your business."
|
|
545
|
+
from_team: "The %{store} Team"
|
|
531
546
|
booking_reference: "For reference, your booking ID is %{order_number}."
|
|
532
547
|
booking_id: "Booking ID <b>%{order_number}</b>"
|
|
533
548
|
booking_summary: "Booking Summary"
|
data/config/locales/km.yml
CHANGED
|
@@ -113,6 +113,17 @@ km:
|
|
|
113
113
|
product_kind_option_types:
|
|
114
114
|
empty_info: "<b>ចំណាំ:</b> កំណត់ប្រភេទសម្រាប់ផលិតផល. ដើម្បីកែប្រែ, សូមចូលទៅ <b>លម្អិត</b> tab > <b>ប្រភេទ</b>"
|
|
115
115
|
|
|
116
|
+
vehicle_type:
|
|
117
|
+
suv: "SUV"
|
|
118
|
+
sedan: "Sedan"
|
|
119
|
+
van: "Van"
|
|
120
|
+
minivan: "Minivan"
|
|
121
|
+
sleeping_bus: "Sleeping Bus"
|
|
122
|
+
luxury_van: "Luxury Van"
|
|
123
|
+
air_bus: "Air Bus"
|
|
124
|
+
bus: "Bus"
|
|
125
|
+
ferry: "Ferry"
|
|
126
|
+
|
|
116
127
|
line_item:
|
|
117
128
|
validation:
|
|
118
129
|
exceeded_max_quantity_per_order: "លើសពីបរិមាណអតិបរមាក្នុងមួយការបញ្ជាទិញ"
|
|
@@ -190,6 +201,16 @@ km:
|
|
|
190
201
|
system_registered: "ចុះឈ្មោះដោយប្រព័ន្ធ"
|
|
191
202
|
self_registered: "ចុះឈ្មោះដោយខ្លួនឯង"
|
|
192
203
|
registration_source: "ប្រភេទការចុះឈ្មោះ"
|
|
204
|
+
vehicle_kind:
|
|
205
|
+
suv: "SUV"
|
|
206
|
+
sedan: "Sedan"
|
|
207
|
+
van: "Van"
|
|
208
|
+
minivan: "Minivan"
|
|
209
|
+
sleeping_bus: "Sleeping Bus"
|
|
210
|
+
luxury_van: "Luxury Van"
|
|
211
|
+
air_bus: "Air Bus"
|
|
212
|
+
bus: "Bus"
|
|
213
|
+
ferry: "Ferry"
|
|
193
214
|
service_types:
|
|
194
215
|
organizer: "Organizer"
|
|
195
216
|
transit: "Transit"
|
|
@@ -388,9 +409,13 @@ km:
|
|
|
388
409
|
booking_confirm: "Confirmed!"
|
|
389
410
|
hello: "Hello %{full_name},"
|
|
390
411
|
thanks: "Thanks %{full_name},"
|
|
391
|
-
booking_event: "Your booking for %{
|
|
412
|
+
booking_event: "Your booking for %{order_number} is successfully complete!"
|
|
413
|
+
cancel_description: "Your order has been CANCELED. Please retain this cancellation information for your records."
|
|
414
|
+
order_cancelled: "Order %{order_number} Summary [CANCELED]"
|
|
415
|
+
cancel_thank: "Thank you for your business."
|
|
416
|
+
from_team: "The %{store} Team"
|
|
392
417
|
booking_reference: "For reference, your booking ID is %{order_number}."
|
|
393
|
-
booking_id: "Booking ID <b>%{order_number}
|
|
418
|
+
booking_id: "Booking ID <b>%{order_number}</b>"
|
|
394
419
|
booking_summary: "Booking Summary"
|
|
395
420
|
check_in: "Check in:"
|
|
396
421
|
check_out: "Check out:"
|
data/config/routes.rb
CHANGED
|
@@ -563,6 +563,7 @@ Spree::Core::Engine.add_routes do
|
|
|
563
563
|
|
|
564
564
|
namespace :intercity_taxi do
|
|
565
565
|
resource :draft_orders, only: %i[create update]
|
|
566
|
+
resource :distance_calculator, controller: :distance_calculator, only: [:create]
|
|
566
567
|
end
|
|
567
568
|
|
|
568
569
|
resource :reset_passwords, only: [:update]
|
|
@@ -708,6 +709,7 @@ Spree::Core::Engine.add_routes do
|
|
|
708
709
|
end
|
|
709
710
|
namespace :intercity_taxi do
|
|
710
711
|
resource :draft_orders, only: %i[create update]
|
|
712
|
+
resource :distance_calculator, controller: :distance_calculator, only: [:create]
|
|
711
713
|
end
|
|
712
714
|
end
|
|
713
715
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class ChangeGuestDynamicFieldsValueFromJsonbToText < ActiveRecord::Migration[7.0]
|
|
2
|
+
def up
|
|
3
|
+
# Check if the migration has already been run
|
|
4
|
+
return if column_exists?(:cm_guest_dynamic_fields, :value, :text)
|
|
5
|
+
|
|
6
|
+
add_column :cm_guest_dynamic_fields, :value_text, :text
|
|
7
|
+
|
|
8
|
+
# Convert JSONB value to TEXT value
|
|
9
|
+
execute <<-SQL
|
|
10
|
+
UPDATE cm_guest_dynamic_fields
|
|
11
|
+
SET value_text = value ->> 0
|
|
12
|
+
SQL
|
|
13
|
+
|
|
14
|
+
remove_column :cm_guest_dynamic_fields, :value
|
|
15
|
+
rename_column :cm_guest_dynamic_fields, :value_text, :value
|
|
16
|
+
|
|
17
|
+
# Restore NOT NULL and default value constraints
|
|
18
|
+
#To make it the same as the original: t.jsonb :value, default: [], null: false
|
|
19
|
+
change_column_default :cm_guest_dynamic_fields, :value, ''
|
|
20
|
+
change_column_null :cm_guest_dynamic_fields, :value, false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def down
|
|
24
|
+
add_column :cm_guest_dynamic_fields, :value_jsonb, :jsonb
|
|
25
|
+
|
|
26
|
+
# Convert TEXT value to JSONB value
|
|
27
|
+
execute <<-SQL
|
|
28
|
+
UPDATE cm_guest_dynamic_fields
|
|
29
|
+
SET value_jsonb = to_jsonb(value)
|
|
30
|
+
SQL
|
|
31
|
+
|
|
32
|
+
remove_column :cm_guest_dynamic_fields, :value
|
|
33
|
+
rename_column :cm_guest_dynamic_fields, :value_jsonb, :value
|
|
34
|
+
|
|
35
|
+
# Restore NOT NULL and default value constraints
|
|
36
|
+
#To make it the same as the original: t.jsonb :value, default: [], null: false
|
|
37
|
+
change_column_default :cm_guest_dynamic_fields, :value, []
|
|
38
|
+
change_column_null :cm_guest_dynamic_fields, :value, false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
class AddMigrationsToSupportVehicleTypes < ActiveRecord::Migration[7.0]
|
|
2
|
+
def change
|
|
3
|
+
# 1. rename amentity table from vehicle to vehicle type
|
|
4
|
+
rename_table :cm_vehicle_option_types, :cm_vehicle_type_option_types if table_exists?(:cm_vehicle_option_types)
|
|
5
|
+
rename_table :cm_option_value_vehicles, :cm_option_value_vehicle_types if table_exists?(:cm_option_value_vehicles)
|
|
6
|
+
rename_table :cm_vehicles, :cm_vehicle_types if table_exists?(:cm_vehicles) && !table_exists?(:cm_vehicle_types)
|
|
7
|
+
|
|
8
|
+
rename_column :cm_vehicle_type_option_types, :vehicle_id, :vehicle_type_id if column_exists?(:cm_vehicle_type_option_types, :vehicle_id)
|
|
9
|
+
rename_column :cm_option_value_vehicle_types, :vehicle_id, :vehicle_type_id if column_exists?(:cm_option_value_vehicle_types, :vehicle_id)
|
|
10
|
+
|
|
11
|
+
# 2. remove uncessary column for vehicle type.
|
|
12
|
+
# also rename code to name to make it more friendly. Meyhong also use name.
|
|
13
|
+
# rename vehicle_type to kind to avoid confusion with vehicle_type association
|
|
14
|
+
change_table :cm_vehicle_types do |t|
|
|
15
|
+
t.remove :license_plate if column_exists?(:cm_vehicle_types, :license_plate)
|
|
16
|
+
t.remove :allow_seat_selection if column_exists?(:cm_vehicle_types, :allow_seat_selection)
|
|
17
|
+
t.rename :code, :name if column_exists?(:cm_vehicle_types, :code)
|
|
18
|
+
t.rename :vehicle_type, :kind if column_exists?(:cm_vehicle_types, :vehicle_type)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# 3. new vehicle table
|
|
22
|
+
create_table :cm_vehicles, if_not_exists: true do |t|
|
|
23
|
+
t.string :license_plate
|
|
24
|
+
t.string :name
|
|
25
|
+
t.integer :kind
|
|
26
|
+
t.references :vendor, null: false, foreign_key: { to_table: :spree_vendors }
|
|
27
|
+
t.references :vehicle_type, null: false, foreign_key: { to_table: :cm_vehicle_types }
|
|
28
|
+
t.timestamps
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# 4. drop existing vehicle assocation, and add vehicle/vehicle type assocation type to trip again.
|
|
32
|
+
remove_column :cm_trips, :vehicle_id if column_exists?(:cm_trips, :vehicle_id)
|
|
33
|
+
add_reference :cm_trips, :vehicle, null: true, foreign_key: { to_table: :cm_vehicles } unless column_exists?(:cm_trips, :vehicle_id)
|
|
34
|
+
add_reference :cm_trips, :vehicle_type, null: true, foreign_key: { to_table: :cm_vehicle_types } unless column_exists?(:cm_trips, :vehicle_type_id)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
# Generic value object representing a computed trip distance and detours.
|
|
3
|
+
# This is the canonical class used by distance calculation services
|
|
4
|
+
# and line item metadata (see LineItemTransitable concern).
|
|
5
|
+
class Distance
|
|
6
|
+
attr_accessor :id,
|
|
7
|
+
:distance_km,
|
|
8
|
+
:ordered_points,
|
|
9
|
+
:estimated_time_minutes,
|
|
10
|
+
:base_km,
|
|
11
|
+
:detour_pickup_km,
|
|
12
|
+
:detour_dropoff_km,
|
|
13
|
+
:extra_pickup_km,
|
|
14
|
+
:extra_dropoff_km
|
|
15
|
+
|
|
16
|
+
def initialize(options = {})
|
|
17
|
+
options = options.stringify_keys if options.is_a?(Hash)
|
|
18
|
+
|
|
19
|
+
@id = SecureRandom.hex
|
|
20
|
+
@distance_km = options['distance_km']&.to_f
|
|
21
|
+
@ordered_points = options['ordered_points']
|
|
22
|
+
@estimated_time_minutes = options['estimated_time_minutes']&.to_i
|
|
23
|
+
@base_km = options['base_km']&.to_f
|
|
24
|
+
@detour_pickup_km = options['detour_pickup_km']&.to_f
|
|
25
|
+
@detour_dropoff_km = options['detour_dropoff_km']&.to_f
|
|
26
|
+
@extra_pickup_km = options['extra_pickup_km']&.to_f
|
|
27
|
+
@extra_dropoff_km = options['extra_dropoff_km']&.to_f
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.from_hash(hash)
|
|
31
|
+
new(hash || {})
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Build a Distance from a signed hash (used for request-time verification).
|
|
35
|
+
def self.from_signed_hash(hash)
|
|
36
|
+
return nil unless valid_signature?(hash)
|
|
37
|
+
|
|
38
|
+
new(hash || {})
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.valid_signature?(signed_hash)
|
|
42
|
+
return false if signed_hash.nil?
|
|
43
|
+
|
|
44
|
+
verify_result = SpreeCmCommissioner::Signing::VerifySignature.call(
|
|
45
|
+
signed_hash: signed_hash,
|
|
46
|
+
signing_key: ENV.fetch('DISTANCE_SIGNING_KEY')
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
verify_result.success? && verify_result.value == true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def to_h
|
|
53
|
+
{
|
|
54
|
+
'distance_km' => @distance_km,
|
|
55
|
+
'ordered_points' => @ordered_points,
|
|
56
|
+
'estimated_time_minutes' => @estimated_time_minutes,
|
|
57
|
+
'base_km' => @base_km,
|
|
58
|
+
'detour_pickup_km' => @detour_pickup_km,
|
|
59
|
+
'detour_dropoff_km' => @detour_dropoff_km,
|
|
60
|
+
'extra_pickup_km' => @extra_pickup_km,
|
|
61
|
+
'extra_dropoff_km' => @extra_dropoff_km
|
|
62
|
+
}.compact
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def to_signed_h
|
|
66
|
+
hash = {
|
|
67
|
+
'distance_km' => @distance_km,
|
|
68
|
+
'ordered_points' => @ordered_points,
|
|
69
|
+
'estimated_time_minutes' => @estimated_time_minutes,
|
|
70
|
+
'base_km' => @base_km,
|
|
71
|
+
'detour_pickup_km' => @detour_pickup_km,
|
|
72
|
+
'detour_dropoff_km' => @detour_dropoff_km,
|
|
73
|
+
'extra_pickup_km' => @extra_pickup_km,
|
|
74
|
+
'extra_dropoff_km' => @extra_dropoff_km,
|
|
75
|
+
'signed_at' => Time.current.utc.iso8601
|
|
76
|
+
}.compact
|
|
77
|
+
|
|
78
|
+
sign_result = SpreeCmCommissioner::Signing::SignData.call(
|
|
79
|
+
hash: hash,
|
|
80
|
+
signing_key: ENV.fetch('DISTANCE_SIGNING_KEY')
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
return hash unless sign_result.success?
|
|
84
|
+
|
|
85
|
+
hash.merge('signature' => sign_result.value)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -38,6 +38,9 @@ module SpreeCmCommissioner
|
|
|
38
38
|
SpreeCmCommissioner::Promotion::Actions::CreateDateSpecificItemAdjustments,
|
|
39
39
|
SpreeCmCommissioner::Promotion::Actions::CreateGuestItemAdjustments,
|
|
40
40
|
]
|
|
41
|
+
|
|
42
|
+
# Register PricingAction adjuster to include pricing_action adjustments in totals
|
|
43
|
+
Rails.application.config.spree.adjusters << SpreeCmCommissioner::Adjustable::Adjuster::PricingAction
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
config.to_prepare(&method(:activate).to_proc)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
FactoryBot.define do
|
|
2
2
|
# use cm_guest instead for consistency
|
|
3
3
|
factory :guest, class: SpreeCmCommissioner::Guest do
|
|
4
|
-
line_item { |a| a.association(:
|
|
4
|
+
line_item { |a| a.association(:cm_line_item) }
|
|
5
5
|
first_name { FFaker::Name.name }
|
|
6
6
|
last_name { FFaker::Name.name }
|
|
7
7
|
gender { 1 }
|
|
@@ -10,7 +10,7 @@ FactoryBot.define do
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
factory :cm_guest, class: SpreeCmCommissioner::Guest do
|
|
13
|
-
line_item { |a| a.association(:
|
|
13
|
+
line_item { |a| a.association(:cm_line_item) }
|
|
14
14
|
first_name { FFaker::Name.name }
|
|
15
15
|
last_name { FFaker::Name.name }
|
|
16
16
|
gender { 1 }
|
|
@@ -7,13 +7,13 @@ FactoryBot.define do
|
|
|
7
7
|
|
|
8
8
|
product do
|
|
9
9
|
if order&.store&.present?
|
|
10
|
-
create(:
|
|
10
|
+
create(:cm_product, stores: [order.store])
|
|
11
11
|
else
|
|
12
|
-
create(:
|
|
12
|
+
create(:cm_product)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
variant { product
|
|
16
|
+
variant { create(:cm_variant, product: product, track_inventory: false) }
|
|
17
17
|
|
|
18
18
|
factory :cm_need_confirmation_line_item do
|
|
19
19
|
product { create(:cm_product, need_confirmation: true) }
|
|
@@ -7,6 +7,7 @@ FactoryBot.define do
|
|
|
7
7
|
product { create(:cm_product, product_type: :transit) }
|
|
8
8
|
|
|
9
9
|
association :vendor, factory: :cm_transit_vendor
|
|
10
|
+
association :vehicle_type, factory: :cm_vehicle_type
|
|
10
11
|
association :vehicle, factory: :cm_vehicle
|
|
11
12
|
association :origin_place, factory: :cm_place
|
|
12
13
|
association :destination_place, factory: :cm_place
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
FactoryBot.define do
|
|
2
2
|
factory :cm_vehicle, class: SpreeCmCommissioner::Vehicle do
|
|
3
|
-
sequence(:
|
|
3
|
+
sequence(:name) { |n| "vehicle_#{n}" }
|
|
4
4
|
sequence(:license_plate) { |n| "2KH-#{'%04d' % (n % 10000)}" }
|
|
5
|
+
kind { :air_bus }
|
|
6
|
+
association :vendor, factory: :vendor
|
|
7
|
+
association :vehicle_type, factory: :cm_vehicle_type
|
|
5
8
|
end
|
|
6
9
|
end
|
|
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
|
|
|
2
2
|
class TripResult
|
|
3
3
|
attr_accessor :id, :origin_place, :destination_place, :allow_seat_selection,
|
|
4
4
|
:departure_time, :duration, :route_type,
|
|
5
|
-
:
|
|
5
|
+
:vehicle_type_id, :vehicle_type, :vendor_id, :vendor,
|
|
6
6
|
:quantity_available, :max_capacity, :boarding, :drop_off,
|
|
7
7
|
:product_id, :amenities, :price, :compare_at_amount, :currency, :distance
|
|
8
8
|
|
|
@@ -37,6 +37,12 @@ module SpreeCmCommissioner
|
|
|
37
37
|
departure_time + duration.seconds
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
def display_price
|
|
41
|
+
return nil if price.nil? || currency.nil?
|
|
42
|
+
|
|
43
|
+
Spree::Money.new(price, currency: currency).to_s
|
|
44
|
+
end
|
|
45
|
+
|
|
40
46
|
# Enable serializer-level caching (like ActiveRecord's cache_key_with_version)
|
|
41
47
|
# Create a version hash based on attributes that matter for caching
|
|
42
48
|
def cache_key_with_version
|
|
@@ -24,7 +24,7 @@ require 'spree_cm_commissioner/cached_inventory_item'
|
|
|
24
24
|
require 'spree_cm_commissioner/transit/leg'
|
|
25
25
|
require 'spree_cm_commissioner/transit/seat_selection'
|
|
26
26
|
require 'spree_cm_commissioner/intercity_taxi/map_place'
|
|
27
|
-
require 'spree_cm_commissioner/
|
|
27
|
+
require 'spree_cm_commissioner/distance'
|
|
28
28
|
|
|
29
29
|
require 'activerecord_multi_tenant'
|
|
30
30
|
require 'google/cloud/recaptcha_enterprise'
|