spree_cm_commissioner 2.0.3.pre.pre → 2.0.3.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 (236) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test_and_build_gem.yml +2 -16
  3. data/.gitignore +1 -2
  4. data/Gemfile.lock +1 -28
  5. data/Rakefile +4 -33
  6. data/app/assets/images/mailer/mail.png +0 -0
  7. data/app/assets/images/mailer/tenant_phone.png +0 -0
  8. data/app/assets/images/mailer/tenant_user.png +0 -0
  9. data/app/assets/stylesheets/spree_cm_commissioner/backend/calendar.scss +11 -8
  10. data/app/controllers/blazer/queries_controller_decorator.rb +11 -0
  11. data/app/controllers/concerns/spree_cm_commissioner/transit/taxon_bitwise.rb +44 -0
  12. data/app/controllers/spree/admin/stock_managements_controller.rb +1 -63
  13. data/app/controllers/spree/api/v2/operator/event_charts_controller.rb +59 -0
  14. data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +1 -1
  15. data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +31 -14
  16. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +13 -13
  17. data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
  18. data/app/factory/spree_cm_commissioner/invite_guest_claimed_telegram_message_factory.rb +24 -81
  19. data/app/finders/spree_cm_commissioner/line_items/find_by_variant_decorator.rb +20 -0
  20. data/app/interactors/spree_cm_commissioner/create_event.rb +5 -0
  21. data/app/interactors/spree_cm_commissioner/create_ticket.rb +6 -5
  22. data/app/interactors/spree_cm_commissioner/create_vendor.rb +44 -0
  23. data/app/interactors/spree_cm_commissioner/pin_code_sender.rb +0 -1
  24. data/app/interactors/spree_cm_commissioner/reports_assigner.rb +17 -0
  25. data/app/interactors/spree_cm_commissioner/sms.rb +1 -1
  26. data/app/interactors/spree_cm_commissioner/user_id_token_authenticator.rb +7 -3
  27. data/app/interactors/spree_cm_commissioner/user_id_token_checker.rb +11 -3
  28. data/app/interactors/spree_cm_commissioner/user_identity_checker.rb +12 -6
  29. data/app/interactors/spree_cm_commissioner/user_registration_with_id_token.rb +7 -1
  30. data/app/jobs/spree_cm_commissioner/application_job.rb +0 -20
  31. data/app/jobs/spree_cm_commissioner/application_unique_job.rb +0 -20
  32. data/app/jobs/spree_cm_commissioner/reports_assigner_job.rb +7 -0
  33. data/app/jobs/spree_cm_commissioner/sms_pin_code_job.rb +1 -1
  34. data/app/mailers/spree/order_mailer_decorator.rb +18 -3
  35. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +33 -9
  36. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +12 -1
  37. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +0 -39
  38. data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +3 -1
  39. data/app/models/concerns/spree_cm_commissioner/product_type.rb +0 -10
  40. data/app/models/concerns/spree_cm_commissioner/route_type.rb +1 -1
  41. data/app/models/concerns/spree_cm_commissioner/taxon_kind.rb +1 -1
  42. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +1 -0
  43. data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +4 -2
  44. data/app/models/spree_cm_commissioner/branch.rb +12 -0
  45. data/app/models/spree_cm_commissioner/dynamic_field.rb +20 -0
  46. data/app/models/spree_cm_commissioner/guest.rb +56 -18
  47. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +41 -1
  48. data/app/models/spree_cm_commissioner/line_item_decorator.rb +78 -46
  49. data/app/models/spree_cm_commissioner/line_item_seat.rb +10 -0
  50. data/app/models/spree_cm_commissioner/notification_taxon.rb +1 -1
  51. data/app/models/spree_cm_commissioner/option_type_decorator.rb +11 -1
  52. data/app/models/spree_cm_commissioner/option_value_vehicle_type.rb +8 -0
  53. data/app/models/spree_cm_commissioner/order_decorator.rb +1 -30
  54. data/app/models/spree_cm_commissioner/place.rb +4 -1
  55. data/app/models/spree_cm_commissioner/product_decorator.rb +28 -10
  56. data/app/models/spree_cm_commissioner/service_calendar.rb +2 -0
  57. data/app/models/spree_cm_commissioner/state_decorator.rb +1 -0
  58. data/app/models/spree_cm_commissioner/stock/availability_checker.rb +25 -26
  59. data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +1 -2
  60. data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
  61. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +0 -17
  62. data/app/models/spree_cm_commissioner/stop.rb +23 -0
  63. data/app/models/spree_cm_commissioner/taxon_decorator.rb +1 -0
  64. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +6 -0
  65. data/app/models/spree_cm_commissioner/trip.rb +10 -10
  66. data/app/models/spree_cm_commissioner/trip_connection.rb +5 -5
  67. data/app/models/spree_cm_commissioner/trip_stop.rb +25 -6
  68. data/app/models/spree_cm_commissioner/user_decorator.rb +6 -0
  69. data/app/models/spree_cm_commissioner/user_identity_provider.rb +26 -4
  70. data/app/models/spree_cm_commissioner/variant_decorator.rb +47 -37
  71. data/app/models/spree_cm_commissioner/variant_options.rb +23 -0
  72. data/app/models/spree_cm_commissioner/vehicle.rb +15 -10
  73. data/app/models/spree_cm_commissioner/vehicle_seat.rb +11 -0
  74. data/app/models/spree_cm_commissioner/vehicle_type.rb +76 -0
  75. data/app/models/spree_cm_commissioner/vendor_decorator.rb +17 -11
  76. data/app/models/spree_cm_commissioner/vendor_place.rb +3 -9
  77. data/app/models/spree_cm_commissioner/vendor_stop.rb +10 -0
  78. data/app/queries/spree_cm_commissioner/event_chart_queries.rb +179 -0
  79. data/app/queries/spree_cm_commissioner/trip_query.rb +44 -70
  80. data/app/queries/spree_cm_commissioner/trip_search_query.rb +76 -0
  81. data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +45 -0
  82. data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +55 -0
  83. data/app/queries/spree_cm_commissioner/vendor_stop_place_query.rb +54 -0
  84. data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +0 -3
  85. data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
  86. data/app/serializables/spree_cm_commissioner/event_chart.rb +11 -0
  87. data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +0 -2
  88. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +0 -1
  89. data/app/serializers/spree/v2/tenant/user_serializer.rb +1 -0
  90. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -1
  91. data/app/services/spree_cm_commissioner/user_authenticator.rb +1 -1
  92. data/app/services/spree_cm_commissioner/vehicle_option_value_creator.rb +11 -0
  93. data/app/views/blazer/queries/_content.html.erb +2 -0
  94. data/app/views/blazer/queries/_preset.html.erb +11 -0
  95. data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +2 -7
  96. data/app/views/spree/admin/stock_managements/index.html.erb +6 -55
  97. data/app/views/spree/admin/tenant_vendors/index.html.erb +9 -2
  98. data/app/views/spree/admin/tenants/_form.html.erb +9 -0
  99. data/app/views/spree/admin/tenants/edit.html.erb +2 -1
  100. data/app/views/spree/admin/tenants/index.html.erb +7 -1
  101. data/app/views/spree/admin/vendors/_form.html.erb +14 -0
  102. data/app/views/spree/order_mailer/confirm_email.html.erb +27 -16
  103. data/app/views/spree_cm_commissioner/layouts/order_mailer.html.erb +5 -1
  104. data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +41 -4
  105. data/app/views/spree_cm_commissioner/order_mailer/tenant/_customer_info.html.erb +42 -0
  106. data/app/views/spree_cm_commissioner/order_mailer/tenant/_footer.html.erb +25 -0
  107. data/app/views/spree_cm_commissioner/order_mailer/tenant/_greeting.html.erb +19 -0
  108. data/app/views/spree_cm_commissioner/order_mailer/tenant/_support_contact.html.erb +33 -0
  109. data/config/initializers/spree_permitted_attributes.rb +0 -5
  110. data/config/locales/en.yml +5 -1
  111. data/config/routes.rb +3 -21
  112. data/db/migrate/20240202080634_update_counter_cache_of_vehicle_type.rb +1 -3
  113. data/db/migrate/20250709073455_add_email_fields_to_spree_vendors.rb +6 -0
  114. data/db/migrate/20250710082132_add_preset_to_blazer_queries.rb +5 -0
  115. data/db/migrate/20250715103333_remove_indexes_from_cm_user_identity_providers.rb +13 -0
  116. data/db/migrate/20250718071620_add_data_fill_stage_to_dynamic_fields.rb +5 -0
  117. data/docker-compose.yml +1 -1
  118. data/lib/cm_app_logger.rb +4 -11
  119. data/lib/generators/spree_cm_commissioner/install/install_generator.rb +11 -14
  120. data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_dashboard/spree_cm_commissioner → spree_cm_commissioner}/utilities.js +0 -4
  121. data/lib/spree_cm_commissioner/calendar_event.rb +1 -11
  122. data/lib/spree_cm_commissioner/test_helper/factories/blazer_query_factory.rb +17 -0
  123. data/lib/spree_cm_commissioner/test_helper/factories/branch_factory.rb +12 -0
  124. data/lib/spree_cm_commissioner/test_helper/factories/departure_time_option_type_factory.rb +8 -0
  125. data/lib/spree_cm_commissioner/test_helper/factories/duration_option_type_factory.rb +8 -0
  126. data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +0 -10
  127. data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
  128. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
  129. data/lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb +7 -0
  130. data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +30 -6
  131. data/lib/spree_cm_commissioner/test_helper/factories/order_factory.rb +36 -0
  132. data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +34 -18
  133. data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
  134. data/lib/spree_cm_commissioner/test_helper/factories/stop_factory.rb +14 -0
  135. data/lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb +8 -0
  136. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +3 -11
  137. data/lib/spree_cm_commissioner/test_helper/factories/user_identity_provider_factory.rb +1 -1
  138. data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +19 -41
  139. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
  140. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_option_type_factory.rb +8 -0
  141. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +96 -0
  142. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -6
  143. data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +1 -13
  144. data/lib/spree_cm_commissioner/trip_query_result.rb +0 -8
  145. data/lib/spree_cm_commissioner/trip_result.rb +3 -5
  146. data/lib/spree_cm_commissioner/trip_seat_layout_result.rb +11 -0
  147. data/lib/spree_cm_commissioner/version.rb +1 -1
  148. data/lib/spree_cm_commissioner.rb +1 -35
  149. data/spree_cm_commissioner.gemspec +0 -7
  150. metadata +46 -145
  151. data/app/controllers/spree/admin/inventory_items_controller.rb +0 -83
  152. data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +0 -42
  153. data/app/finders/spree_cm_commissioner/accommodations/find.rb +0 -37
  154. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +0 -32
  155. data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +0 -40
  156. data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +0 -25
  157. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +0 -44
  158. data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +0 -13
  159. data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +0 -15
  160. data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +0 -75
  161. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +0 -32
  162. data/app/interactors/spree_cm_commissioner/variant_block_updater.rb +0 -62
  163. data/app/interactors/spree_cm_commissioner/vehicle_updater.rb +0 -41
  164. data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +0 -7
  165. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +0 -7
  166. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +0 -11
  167. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +0 -11
  168. data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +0 -9
  169. data/app/models/concerns/spree_cm_commissioner/order_seatable.rb +0 -44
  170. data/app/models/concerns/spree_cm_commissioner/vehicle_type.rb +0 -11
  171. data/app/models/spree_cm_commissioner/block.rb +0 -43
  172. data/app/models/spree_cm_commissioner/inventory.rb +0 -11
  173. data/app/models/spree_cm_commissioner/inventory_item.rb +0 -69
  174. data/app/models/spree_cm_commissioner/price_decorator.rb +0 -9
  175. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +0 -41
  176. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +0 -126
  177. data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +0 -36
  178. data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +0 -25
  179. data/app/models/spree_cm_commissioner/reserved_block.rb +0 -30
  180. data/app/models/spree_cm_commissioner/seat_layout.rb +0 -20
  181. data/app/models/spree_cm_commissioner/seat_section.rb +0 -16
  182. data/app/models/spree_cm_commissioner/seats/blocks_canceler.rb +0 -30
  183. data/app/models/spree_cm_commissioner/seats/blocks_holder.rb +0 -53
  184. data/app/models/spree_cm_commissioner/seats/blocks_reserver.rb +0 -49
  185. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_on_hold_by_other_guest.rb +0 -4
  186. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_other_guest.rb +0 -4
  187. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_same_guest.rb +0 -4
  188. data/app/models/spree_cm_commissioner/seats/errors/unable_to_save_reserved_block_record.rb +0 -4
  189. data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +0 -44
  190. data/app/models/spree_cm_commissioner/variant_block.rb +0 -9
  191. data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +0 -19
  192. data/app/views/spree/admin/inventory_items/show.html.erb +0 -72
  193. data/app/views/spree/admin/stock_managements/calendar.html.erb +0 -56
  194. data/config/initializers/paper_trail.rb +0 -1
  195. data/db/migrate/20250122000000_move_route_type_from_vehicles_to_trips.rb +0 -7
  196. data/db/migrate/20250304293518_create_cm_inventory_items.rb +0 -21
  197. data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +0 -5
  198. data/db/migrate/20250502025848_add_index_to_spree_products.rb +0 -5
  199. data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +0 -5
  200. data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +0 -5
  201. data/db/migrate/20250603035256_add_inventory_item_to_spree_prices.rb +0 -7
  202. data/db/migrate/20250619073724_drop_table_cm_line_item_seats.rb +0 -5
  203. data/db/migrate/20250619073812_drop_table_cm_vehicle_seats.rb +0 -5
  204. data/db/migrate/20250619073844_drop_table_cm_vehicle_types.rb +0 -9
  205. data/db/migrate/20250619073957_drop_table_cm_option_value_vehicle_types.rb +0 -5
  206. data/db/migrate/20250619082354_remove_unnecessary_fields_from_cm_places.rb +0 -9
  207. data/db/migrate/20250619082736_remove_route_type_from_spree_products.rb +0 -5
  208. data/db/migrate/20250619083055_remove_unnecessary_fields_from_spree_taxons.rb +0 -5
  209. data/db/migrate/20250620083055_remove_variant_id_from_cm_trips.rb +0 -5
  210. data/db/migrate/20250620090000_update_cm_trip_connections_to_use_cm_trips.rb +0 -6
  211. data/db/migrate/20250620090001_create_cm_seat_layouts.rb +0 -17
  212. data/db/migrate/20250620090002_create_cm_seat_sections.rb +0 -18
  213. data/db/migrate/20250620090003_create_cm_blocks.rb +0 -18
  214. data/db/migrate/20250624091005_create_cm_reserved_blocks.rb +0 -29
  215. data/db/migrate/20250626083642_create_cm_variant_blocks.rb +0 -24
  216. data/db/migrate/20250627023314_add_block_id_to_cm_guests.rb +0 -13
  217. data/db/migrate/20250716022821_add_location_reference_to_cm_vendor_places.rb +0 -5
  218. data/db/migrate/20250716031743_drop_table_cm_vendor_stops.rb +0 -5
  219. data/db/migrate/20250717023824_add_vendor_reference_to_cm_trips.rb +0 -5
  220. data/db/migrate/20250717041414_add_location_place_reference_to_cm_trip_stops.rb +0 -5
  221. data/db/migrate/20250717042539_rename_cm_trip_stops_stop_id_column_to_stop_place_id.rb +0 -7
  222. data/db/migrate/20250717042707_rename_cm_trips_origin_and_destination_to_origin_place_and_destination_place.rb +0 -11
  223. data/db/migrate/20250721080738_add_vehicle_type_to_cm_vehicles.rb +0 -7
  224. data/db/migrate/20250725092713_add_block_type_to_cm_blocks.rb +0 -5
  225. data/lib/spree_cm_commissioner/cached_inventory_item.rb +0 -23
  226. data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +0 -16
  227. data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +0 -9
  228. data/lib/spree_cm_commissioner/test_helper/factories/reserved_block_factory.rb +0 -27
  229. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +0 -11
  230. data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +0 -16
  231. data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +0 -6
  232. data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +0 -10
  233. data/lib/spree_cm_commissioner/test_helper/factories/variant_block_factory.rb +0 -7
  234. data/lib/tasks/create_default_non_permanent_inventory_items.rake +0 -16
  235. data/lib/tasks/ensure_correct_product_type.rake +0 -7
  236. data/lib/tasks/generate_inventory_items.rake +0 -7
@@ -0,0 +1,45 @@
1
+ module SpreeCmCommissioner
2
+ module VariantAvailability
3
+ class NonPermanentStockQuery
4
+ attr_reader :variant, :except_line_item_id, :error_message
5
+
6
+ def initialize(variant:, except_line_item_id: nil)
7
+ @variant = variant
8
+ @except_line_item_id = except_line_item_id
9
+ @error_message = nil
10
+ end
11
+
12
+ def available?(quantity)
13
+ reserve_variants =
14
+ Spree::LineItem
15
+ .complete
16
+ .select('(SUM(DISTINCT spree_stock_items.count_on_hand) - SUM(spree_line_items.quantity)) AS available_quantity')
17
+ .joins(variant: :stock_items)
18
+ .where(variant_id: variant.id)
19
+ .where.not(id: except_line_item_id)
20
+ .group(:variant_id)
21
+
22
+ # there is a case when variant does not have any purchaces yet, it will return empty & always available true.
23
+ # in this case, we check with stock items directly.
24
+
25
+ available_quantity = if reserve_variants.any?
26
+ reserve_variants.sum(&:available_quantity)
27
+ else
28
+ variant.stock_items.sum(:count_on_hand)
29
+ end
30
+ if available_quantity >= quantity
31
+ true
32
+ elsif available_quantity == 1
33
+ @error_message = I18n.t('variant_availability.item_available_instock')
34
+ false
35
+ elsif available_quantity <= 0
36
+ @error_message = I18n.t('variant_availability.items_out_of_stock')
37
+ false
38
+ else
39
+ @error_message = I18n.t('variant_availability.items_available_instock', available_quantity: available_quantity)
40
+ false
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,55 @@
1
+ module SpreeCmCommissioner
2
+ module VariantAvailability
3
+ class PermanentStockQuery
4
+ attr_reader :variant, :from_date, :to_date, :except_line_item_id
5
+
6
+ def initialize(variant:, from_date:, to_date:, except_line_item_id: nil)
7
+ @variant = variant
8
+ @from_date = from_date
9
+ @to_date = to_date
10
+ @except_line_item_id = except_line_item_id
11
+ end
12
+
13
+ def available?(quantity)
14
+ (from_date..from_date).all? do |booking_date|
15
+ booked_date_quantity[booking_date].nil? ||
16
+ (booked_date_quantity[booking_date] - quantity) >= 0
17
+ end
18
+ end
19
+
20
+ def booked_date_quantity
21
+ dates_sql = ApplicationRecord.sanitize_sql_array(
22
+ [
23
+ 'SELECT date FROM generate_series(?::date, ?::date, ?) AS date',
24
+ from_date,
25
+ to_date,
26
+ date_interval
27
+ ]
28
+ )
29
+
30
+ @booked_variants ||=
31
+ Spree::LineItem
32
+ .complete
33
+ .select(
34
+ '(SUM(DISTINCT spree_stock_items.count_on_hand) - SUM(spree_line_items.quantity)) AS available_quantity',
35
+ 'dates.date AS reservation_date'
36
+ )
37
+ .joins(variant: :stock_items)
38
+ .where(variant_id: variant.id)
39
+ .where.not(id: except_line_item_id)
40
+ .joins("INNER JOIN (#{dates_sql}) dates ON dates.date >= spree_line_items.from_date AND dates.date < spree_line_items.to_date")
41
+ .group(:variant_id, :reservation_date)
42
+ .order(:reservation_date)
43
+ .each_with_object({}) do |record, hash|
44
+ hash[record.reservation_date.to_date] = record.available_quantity
45
+ end
46
+ end
47
+
48
+ # override this for product that have
49
+ # different date time interval than 1 day.
50
+ def date_interval
51
+ '1 day'
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,54 @@
1
+ module SpreeCmCommissioner
2
+ class VendorStopPlaceQuery
3
+ attr_reader :query, :vendor_id, :stop_type, :reference_stop_id
4
+
5
+ def initialize(query:, vendor_id:, stop_type: :boarding, reference_stop_id: nil)
6
+ @query = query.to_s.strip
7
+ @vendor_id = vendor_id
8
+ @stop_type = stop_type
9
+ @reference_stop_id = reference_stop_id
10
+ end
11
+
12
+ def call
13
+ results = vendor_stops
14
+ return [] if results.empty?
15
+
16
+ places = results.includes(:stop).map(&:stop).compact.uniq
17
+
18
+ format_places(places)
19
+ end
20
+
21
+ private
22
+
23
+ def vendor_stops
24
+ scope = base_scope
25
+ return scope if query.blank?
26
+
27
+ scope = scope.where.not(stop_id: reference_stop_id) if reference_stop_id.present?
28
+ scope.where('cm_places.name ILIKE ?', "%#{query}%")
29
+ end
30
+
31
+ def base_scope
32
+ SpreeCmCommissioner::VendorStop
33
+ .joins(:stop)
34
+ .where(vendor_id: vendor_id)
35
+ .where(stop_type: stop_type)
36
+ .order(trip_count: :desc)
37
+ .where.not(trip_count: 0)
38
+ end
39
+
40
+ def format_places(places)
41
+ places
42
+ .sort_by { |p| [-p.depth, -p.lft] }
43
+ .filter_map do |place|
44
+ next if place.depth.zero?
45
+
46
+ {
47
+ id: place.id,
48
+ parent_id: place.parent_id,
49
+ name: place.self_and_ancestors.map(&:name).reverse.join(', ')
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -3,9 +3,6 @@ module SpreeCmCommissioner
3
3
  params do
4
4
  required(:from_date).value(:date)
5
5
  required(:to_date).value(:date)
6
- required(:province_id).value(:integer)
7
- required(:adult).value(:integer)
8
- required(:children).value(:integer)
9
6
  end
10
7
 
11
8
  rule(:from_date, :to_date) do
@@ -11,7 +11,7 @@ module SpreeCmCommissioner
11
11
  end
12
12
 
13
13
  def error_message
14
- errors.map { |error| "#{error.path.join(', ')}: #{error.text}" }.to_sentence
14
+ errors.map(&:text).join(', ')
15
15
  end
16
16
 
17
17
  private
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ class EventChart
3
+ attr_reader :id, :chart_type, :product_charts
4
+
5
+ def initialize(id:, chart_type:, product_charts:)
6
+ @id = id
7
+ @chart_type = chart_type
8
+ @product_charts = product_charts
9
+ end
10
+ end
11
+ end
@@ -9,12 +9,10 @@ module Spree
9
9
 
10
10
  attributes :total_inventory, :service_availabilities
11
11
 
12
- # Deprecated
13
12
  attribute :total_booking do |vendor|
14
13
  vendor.respond_to?(:total_booking) ? vendor.total_booking : 0
15
14
  end
16
15
 
17
- # Deprecated
18
16
  attribute :remaining do |vendor|
19
17
  vendor.respond_to?(:remaining) ? vendor.remaining : vendor.total_inventory
20
18
  end
@@ -4,7 +4,6 @@ module Spree
4
4
  module LineItemSerializerDecorator
5
5
  def self.prepended(base)
6
6
  base.attributes :from_date, :to_date, :need_confirmation, :product_type, :event_status, :amount, :display_amount,
7
- :checkin_date, :checkout_date,
8
7
  :number, :qr_data,
9
8
  :kyc, :kyc_fields, :remaining_total_guests, :number_of_guests,
10
9
  :completion_steps, :available_social_contact_platforms, :allow_anonymous_booking, :discontinue_on,
@@ -11,6 +11,7 @@ module Spree
11
11
  has_one :profile, serializer: Spree::V2::Tenant::AssetSerializer
12
12
  has_many :device_tokens, serializer: Spree::V2::Tenant::UserDeviceTokenSerializer
13
13
  has_many :spree_roles, serializer: Spree::V2::Tenant::RoleSerializer
14
+ has_many :user_identity_providers, serializer: Spree::V2::Tenant::UserIdentityProviderSerializer
14
15
 
15
16
  attribute :store_credits, &:total_available_store_credit
16
17
 
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Storefront
4
4
  class DynamicFieldSerializer < BaseSerializer
5
- attributes :id, :label, :data_type, :vendor_id, :multiple_select, :created_at, :updated_at, :position
5
+ attributes :id, :label, :data_type, :vendor_id, :multiple_select, :created_at, :updated_at, :position, :data_fill_stage
6
6
 
7
7
  has_many :dynamic_field_options, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
8
8
  end
@@ -32,7 +32,7 @@ module SpreeCmCommissioner
32
32
  options = { login: params[:username], password: params[:password], tenant_id: tenant_id }
33
33
  SpreeCmCommissioner::UserPasswordAuthenticator.call(options)
34
34
  when 'social_auth'
35
- options = { id_token: params[:id_token] }
35
+ options = { id_token: params[:id_token], tenant_id: tenant_id }
36
36
  SpreeCmCommissioner::UserIdTokenAuthenticator.call(options)
37
37
  when 'telegram_web_app_auth'
38
38
  options = { telegram_init_data: params[:telegram_init_data], telegram_bot_username: params[:tg_bot] }
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ class VehicleOptionValueCreator
3
+ def self.call(vehicle)
4
+ vehicle_option_type = Spree::OptionType.vehicle
5
+
6
+ value = vehicle_option_type.option_values.where(name: vehicle.id).first_or_initialize
7
+ value.presentation = vehicle.code
8
+ value.save
9
+ end
10
+ end
11
+ end
@@ -58,6 +58,8 @@
58
58
  <% end %>
59
59
  </div>
60
60
 
61
+ <%= render partial: 'blazer/queries/preset' %>
62
+
61
63
  <% if flash[:success] %>
62
64
  <div class="alert alert-success">
63
65
  <%= flash[:success] %>
@@ -0,0 +1,11 @@
1
+ <%= form_for @query do |f| %>
2
+ <div>
3
+ <%= f.check_box :preset, onchange: "this.form.submit()" %>
4
+ <%= f.label :preset, Spree.t(:preset) %>
5
+ </div>
6
+ <small style="margin-bottom: 6px; display: inline-block;">
7
+ Mark as <strong>preset</strong> to auto-assign this report to new organizers or vendors.
8
+ </small>
9
+ <% end %>
10
+
11
+
@@ -17,11 +17,9 @@
17
17
  </td>
18
18
  <td class="text-center d-flex flex-column align-items-center justify-content-center">
19
19
  <div style="width: 90px;">
20
- <%= form_tag admin_product_stock_managements_path(product_id: params[:product_id], variant_id: variant.id, stock_location_id: stock_location.id), method: :post do %>
20
+ <%= form_tag admin_stock_items_path(variant_id: variant.id, stock_location_id: stock_location.id), method: :post do %>
21
21
  <div class="input-group input-group-sm">
22
22
  <%= number_field_tag 'stock_movement[quantity]', 0, class: 'form-control text-center p-0' %>
23
- <%= hidden_field_tag 'stock_movement[originator_id]', spree_current_user.id %>
24
- <%= hidden_field_tag 'stock_movement[originator_type]', spree_current_user.class.name %>
25
23
  <div class="input-group-append">
26
24
  <%= button_tag(class: 'btn btn-outline-success pl-2 pr-1') do %>
27
25
  <%= svg_icon(name: 'arrow-left-right.svg', classes: "icon", width: 14, height: 14) %>
@@ -34,10 +32,7 @@
34
32
  <td class="text-center">
35
33
  <% if item.persisted? && can?(:update, item) %>
36
34
  <%= form_tag admin_stock_item_path(item), method: :put, class: 'toggle_stock_item_backorderable' do %>
37
- <%= check_box_tag 'stock_item[backorderable]', true, item.backorderable?,
38
- class: 'stock_item_backorderable',
39
- id: "stock_item_backorderable_#{stock_location.id}",
40
- onclick: "if (!confirm('Are you sure to change backorderable status?')) { this.checked = !this.checked; }" %>
35
+ <%= check_box_tag 'stock_item[backorderable]', true, item.backorderable?, class: 'stock_item_backorderable', id: "stock_item_backorderable_#{stock_location.id}" %>
41
36
  <% end %>
42
37
  <% else %>
43
38
  <%= 'N/A' %>
@@ -19,73 +19,30 @@
19
19
  <% @variants.each do |variant| %>
20
20
  <tr id="<%= spree_dom_id variant %>" data-hook="admin_product_stock_management_index_rows">
21
21
  <td class="image text-center">
22
- <%= small_image(variant) %>
22
+ <%= small_image(variant) %>
23
+ <div class="mt-4">
24
+ Reserved Stock: <%= @reserved_stocks[variant.id] || 0 %></strong>
25
+ </div>
23
26
  </td>
24
27
  <td>
25
28
  <%= variant.sku_and_options_text %>
26
29
  <%= form_tag admin_product_variants_including_master_path(@product, variant, format: :js), method: :put, class: 'toggle_variant_track_inventory mt-2' do %>
27
30
  <div class="checkbox">
28
31
  <%= label_tag "track_inventory_#{ variant.id }", class: 'm-0' do %>
29
- <%= check_box_tag 'track_inventory', 1, variant.track_inventory?,
30
- class: 'track_inventory_checkbox',
31
- id: "track_inventory_#{ variant.id }",
32
- onclick: "if (!confirm('Are you sure to change track inventory status?')) { this.checked = !this.checked; }" %>
32
+ <%= check_box_tag 'track_inventory', 1, variant.track_inventory?, class: 'track_inventory_checkbox', id: "track_inventory_#{ variant.id }" %>
33
33
  <%= Spree.t(:track_inventory) %>
34
34
  <%= hidden_field_tag 'variant[track_inventory]', variant.track_inventory?, class: 'variant_track_inventory', id: "variant_track_inventory_#{variant.id}" %>
35
35
  <% end %>
36
36
  </div>
37
37
  <% end if can?(:update, @product) && can?(:update, variant) %>
38
-
39
- <% if defined?(@reserved_stocks) %>
40
- <div>
41
- <%= svg_icon name: "cart-check.svg", width: '14', height: '14' %>
42
- <%= label_tag "reserved_stock#{variant.id}", "Reserved Stock: #{@reserved_stocks[variant.id] || 0}", class: "m-0" %>
43
- <%= link_to_with_icon('capture.svg', "Create Inventory Item", admin_product_stock_management_variant_inventory_items(@product, variant.id),
44
- method: :post,
45
- remote: false,
46
- class: 'icon_link btn btn-sm btn-outline-primary ml-2',
47
- no_text: true
48
- ) unless @inventory_items[variant.id].present? %>
49
- </div>
50
- <% end %>
51
-
52
38
  <% if variant.permanent_stock? %>
53
39
  <div>
54
40
  <span type="button" data-toggle="popover" data-trigger="hover" data-placement="right" data-content="This product stock will renew every day">
55
41
  <%= svg_icon name: "info-circle-fill.svg", width: '14', height: '14' %>
56
42
  </span>
57
- <%= label_tag "permanent_stock_#{ variant.id }", Spree.t(:permanent_stock), class: "m-0" %>
43
+ <%= label_tag "permanent_stock_#{ variant.id }", Spree.t(:permanent_stock) %>
58
44
  </div>
59
45
  <% end %>
60
-
61
- <% if defined?(@inventory_items) %>
62
- <% @inventory_items[variant.id]&.each do |inventory_item| %>
63
- <div>
64
- <%= svg_icon name: "handbag.svg", width: '14', height: '14' %>
65
- <%= label_tag "max_capacity_#{ inventory_item.id }", "Max capacity: #{inventory_item.max_capacity}", class: "m-0" %>
66
- </div>
67
- <div>
68
- <%= svg_icon name: "approve.svg", width: '14', height: '14' %>
69
- <%= label_tag "quantity_available_#{ inventory_item.id }", "Quantity available: #{inventory_item.quantity_available}", class: "m-0" %>
70
-
71
- <% synced = inventory_item.quantity_available == @cached_inventory_items[inventory_item.id].quantity_available %>
72
- <span type="button" data-toggle="popover" data-trigger="hover" data-placement="right" data-content="<%= inventory_item_message(inventory_item, @cached_inventory_items[inventory_item.id]) %>">
73
- <% if synced %>
74
- <%= svg_icon name: "cloud-check.svg", width: '14', height: '14', classes: 'text-success' %>
75
- <% else %>
76
- <%= svg_icon name: "cloud-slash.svg", width: '14', height: '14', classes: 'text-danger' %>
77
- <% end %>
78
- </span>
79
-
80
- <%= link_to_with_icon('arrow-counterclockwise.svg', "Reset Inventory Item", reset_admin_product_variant_inventory_item_path(@product, inventory_item.variant_id, inventory_item.id),
81
- method: :patch,
82
- remote: false,
83
- class: 'icon_link btn btn-sm outline text-dark',
84
- data: { confirm: "Only reset if stock is incorrect. Are you sure?" }, no_text: true
85
- ) %>
86
- </div>
87
- <% end %>
88
- <% end %>
89
46
  </td>
90
47
 
91
48
  <td colspan="3" class="stock_location_info">
@@ -96,9 +53,3 @@
96
53
  </tbody>
97
54
  </table>
98
55
  </div>
99
-
100
- <%= turbo_frame_tag "calendar", src: calendar_admin_product_stock_managements_path(year: params[:year]) do %>
101
- <div class="spinner-border mt-2" role="status">
102
- <span class="sr-only">Loading...</span>
103
- </div>
104
- <% end if @product.permanent_stock? %>
@@ -1,6 +1,6 @@
1
1
  <% content_for :page_title do %>
2
2
  <%= page_header_back_button spree.admin_tenants_url %>
3
- <%= link_to @tenant.name, spree.admin_tenants_url %> / <%= Spree.t('vendors') %>
3
+ <%= link_to Spree.t('tenants'), spree.admin_tenants_url %> / <%= link_to @tenant.name, spree.admin_tenants_url%> / <%= Spree.t('vendors') %>
4
4
  <% end %>
5
5
 
6
6
  <% content_for :page_actions do %>
@@ -24,13 +24,20 @@
24
24
  <tbody>
25
25
  <% @vendors.each do |vendor| %>
26
26
  <tr id="<%= spree_dom_id vendor %>" data-hook="admin_vendors_index_rows">
27
- <td><%= vendor.name %></td>
27
+ <td>
28
+ <% if can?(:edit, vendor) %>
29
+ <%= link_to vendor.name, edit_admin_vendor_path(vendor.slug) %>
30
+ <% else %>
31
+ <td><%= vendor.name %></td>
32
+ <% end %>
33
+ </td>
28
34
  <td><%= vendor.slug %></td>
29
35
  <td><%= vendor.created_at %></td>
30
36
  <td><%= vendor.updated_at %></td>
31
37
  <td><%= vendor.tenant.name %></td>
32
38
  <td data-hook="admin_tenants_index_row_actions" class="actions">
33
39
  <span class="d-flex justify-content-end">
40
+ <%= link_to_edit vendor, url: edit_admin_vendor_path(vendor.slug), no_text: true if can?(:edit, vendor) %>
34
41
  <%= link_to_delete vendor, url: admin_tenant_vendor_path(@tenant, vendor.id), no_text: true if can?(:delete, vendor) %>
35
42
  </span>
36
43
  </td>
@@ -101,6 +101,15 @@
101
101
  <% end %>
102
102
  </div>
103
103
 
104
+ <!-- Brand Primary Color Field -->
105
+ <div class="col-md-6">
106
+ <%= f.label :preferred_brand_primary_color, Spree.t(:brand_primary_color), class: 'form-label' %>
107
+ <%= f.text_field :preferred_brand_primary_color, class: 'form-control color-picker', placeholder: '#FF5733', value: @object.preferred_brand_primary_color %>
108
+ <div class="color-preview" style="margin-top: 10px;">
109
+ <%= content_tag :div, nil, style: "background-color: #{@object.preferred_brand_primary_color}; width: 60px; height: 60px; border: 1px solid #ccc; box-sizing: border-box; display: block;" %>
110
+ </div>
111
+ </div>
112
+
104
113
  <!-- State Field -->
105
114
  <div class="col-6">
106
115
  <%= f.field_container :state do %>
@@ -1,6 +1,7 @@
1
1
  <% content_for :page_title do %>
2
2
  <%= page_header_back_button spree.admin_tenants_url %>
3
- <%= link_to @object.name, spree.admin_tenants_url %>
3
+ <%= link_to Spree.t('tenants'), spree.admin_tenants_url %> /
4
+ <%= @object.name %>
4
5
  <% end %>
5
6
 
6
7
  <%= render partial: 'tabs', locals: { current: :edit } %>
@@ -40,7 +40,13 @@
40
40
  <tbody>
41
41
  <% @collection.each do |tenant| %>
42
42
  <tr id="<%= spree_dom_id tenant %>" data-hook="admin_tenants_index_rows">
43
- <td><%= tenant.name %></td>
43
+ <td>
44
+ <% if can?(:edit, tenant) %>
45
+ <%= link_to tenant.name, edit_admin_tenant_path(tenant.slug) %>
46
+ <% else %>
47
+ <%= tenant.name %>
48
+ <% end %>
49
+ </td>
44
50
  <td><%= tenant.slug %></td>
45
51
  <td><%= tenant.description %></td>
46
52
  <td><%= tenant.created_at %></td>
@@ -60,4 +60,18 @@
60
60
  <%= f.label :notification_email %>
61
61
  <%= f.email_field :notification_email, class: 'form-control' %>
62
62
  <% end %>
63
+ <%= f.field_container :from_email do %>
64
+ <%= f.label :from_email, Spree.t(:from_email)%>
65
+ <%= f.email_field :from_email, class: 'form-control' %>
66
+ <small class="form-text text-muted">
67
+ This is the email which will be the sender of all your Store emails (Order Confirmation, Shipment notification etc)
68
+ </small>
69
+ <% end %>
70
+ <%= f.field_container :support_email do %>
71
+ <%= f.label :support_email, Spree.t(:support_email) %>
72
+ <%= f.email_field :support_email, class: 'form-control' %>
73
+ <small class="form-text text-muted">
74
+ This email is visible to your Store visitors in the Footer section
75
+ </small>
76
+ <% end %>
63
77
  </div>
@@ -1,22 +1,33 @@
1
1
  <tr>
2
- <td class="email-body" width="570" cellpadding="0" cellspacing="0">
3
- <table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
4
- <!-- Body content -->
2
+ <td class="email-body" width="570" cellpadding="0" cellspacing="0">
3
+ <table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
5
4
  <tbody>
6
- <tr>
7
- <td>
8
- <div class="f-fallback">
9
- <%= render 'spree_cm_commissioner/order_mailer/greeting', order: @order %>
10
- <div class="content">
5
+ <tr>
6
+ <td>
7
+ <% if @order.tenant.nil? %>
8
+ <div class="f-fallback">
9
+ <%= render 'spree_cm_commissioner/order_mailer/greeting', order: @order %>
10
+ <div class="content">
11
11
  <%= render 'spree_cm_commissioner/order_mailer/order_total', order: @order %>
12
12
  <%= render 'spree_cm_commissioner/order_mailer/your_booking', order: @order, show_booking_header: true %>
13
13
  <%= render 'spree_cm_commissioner/order_mailer/customer_info', order: @order %>
14
- <%= render 'spree_cm_commissioner/order_mailer/support_contact'%>
15
- </div>
16
- </div>
17
- </td>
18
- </tr>
14
+ <%= render 'spree_cm_commissioner/order_mailer/support_contact' %>
15
+ </div>
16
+ </div>
17
+ <% else %>
18
+ <div class="f-fallback">
19
+ <%= render 'spree_cm_commissioner/order_mailer/tenant/greeting', order: @order %>
20
+ <div class="content">
21
+ <%= render 'spree_cm_commissioner/order_mailer/order_total', order: @order %>
22
+ <%= render 'spree_cm_commissioner/order_mailer/your_booking', order: @order, show_booking_header: true %>
23
+ <%= render 'spree_cm_commissioner/order_mailer/tenant/customer_info', order: @order %>
24
+ <%= render 'spree_cm_commissioner/order_mailer/tenant/support_contact' %>
25
+ </div>
26
+ </div>
27
+ <% end %>
28
+ </td>
29
+ </tr>
19
30
  </tbody>
20
- </table>
21
- </td>
22
- </tr>
31
+ </table>
32
+ </td>
33
+ </tr>
@@ -23,7 +23,11 @@
23
23
  <table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
24
24
  <tr>
25
25
  <td>
26
- <%= render 'spree_cm_commissioner/order_mailer/footer', store: @order.store%>
26
+ <% if @order.tenant.nil? %>
27
+ <%= render 'spree_cm_commissioner/order_mailer/footer', store: @order.store %>
28
+ <% else %>
29
+ <%= render 'spree_cm_commissioner/order_mailer/tenant/footer', store: @order.store %>
30
+ <% end %>
27
31
  </td>
28
32
  </tr>
29
33
  </table>
@@ -55,10 +55,10 @@
55
55
  border-radius: 1.5625rem 1.5625rem 0 0;
56
56
  background: #653ed7;
57
57
  background: url(<%= image_path("mailer/event-mailer-bg.png") %>) center center / cover,
58
- linear-gradient(45deg, #653ed7, rgba(0, 0, 255, 0) 70.71%),
59
- linear-gradient(225deg, #653ed7, rgba(0, 0, 255, 0) 70.71%),
60
- linear-gradient(330deg, #35ace0, rgba(0, 0, 255, 0) 70.71%),
61
- linear-gradient(150deg, #35ace0, rgba(0, 0, 255, 0) 70.71%);
58
+ linear-gradient(45deg, #653ed7, rgba(0, 0, 255, 0) 70.71%),
59
+ linear-gradient(225deg, #653ed7, rgba(0, 0, 255, 0) 70.71%),
60
+ linear-gradient(330deg, #35ace0, rgba(0, 0, 255, 0) 70.71%),
61
+ linear-gradient(150deg, #35ace0, rgba(0, 0, 255, 0) 70.71%);
62
62
  }
63
63
  #confirm-email #greeting-card p,
64
64
  #confirm-email #greeting-card .booking-confirmm,
@@ -66,6 +66,24 @@
66
66
  #confirm-email #greeting-card .description {
67
67
  color: #fff;
68
68
  }
69
+
70
+ #confirm-email #greeting-card-1 {
71
+ color: #fff;
72
+ padding: 1.5rem;
73
+ background-size: cover;
74
+ background-position: center;
75
+ background-repeat: no-repeat;
76
+ border-radius: 1.5625rem 1.5625rem 0 0;
77
+ background: #<%= @brand_color %>;
78
+ }
79
+ #confirm-email #greeting-card-1 p,
80
+ #confirm-email #greeting-card-1 .header,
81
+ #confirm-email #greeting-card-1 .booking-confirm,
82
+ #confirm-email #greeting-card-1 .hello,
83
+ #confirm-email #greeting-card-1 .description {
84
+ color: #fff;
85
+ }
86
+
69
87
  #confirm-email .align-right {
70
88
  vertical-align: top;
71
89
  }
@@ -74,6 +92,15 @@
74
92
  margin-top: 1.25rem;
75
93
  margin-bottom: 0.625rem;
76
94
  }
95
+ #confirm-email .icon-hang-meas {
96
+ width: 6.25rem;
97
+ }
98
+ #confirm-email .header {
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: space-between;
102
+ width: 100%;
103
+ }
77
104
  #confirm-email #greeting-card .hello,
78
105
  .booking-confirm {
79
106
  font-size: 1.375rem;
@@ -83,6 +110,15 @@
83
110
  margin-bottom: 0.25rem;
84
111
  margin-top: 1.25rem;
85
112
  }
113
+ #confirm-email #greeting-card-1 .booking-confirm {
114
+ font-size: 1.375rem;
115
+ font-style: normal;
116
+ font-weight: 700;
117
+ line-height: 1.75rem;
118
+ margin-bottom: 0.25rem;
119
+ margin-top: 1.25rem;
120
+ color: #fff;
121
+ }
86
122
  #confirm-email #greeting-card .booking-confirm {
87
123
  font-size: 1.5rem;
88
124
  padding: 0.625rem 0;
@@ -233,6 +269,7 @@
233
269
  }
234
270
  #confirm-email .notice-info .description {
235
271
  padding-left: 0.75rem;
272
+ color: #939393;
236
273
  }
237
274
  #confirm-email .notice-info a {
238
275
  color: #6444D8;