spree_cm_commissioner 2.3.1 → 2.3.2.pre.pre4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/admin/product_completion_steps_controller.rb +17 -1
- data/app/controllers/spree/admin/tenants_controller.rb +1 -1
- data/app/controllers/spree/api/v2/storefront/intercity_taxi/draft_orders_controller.rb +52 -11
- data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +63 -0
- data/app/controllers/spree/api/v2/storefront/route_places_controller.rb +68 -0
- data/app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb +81 -0
- data/app/controllers/spree/api/v2/tenant/trip_places_controller.rb +42 -0
- data/app/controllers/spree/api/v2/tenant/trip_search_controller.rb +103 -0
- data/app/controllers/spree/api/v2/tenant/trips_controller.rb +32 -0
- data/app/factory/spree_cm_commissioner/order_telegram_message_factory.rb +12 -0
- data/app/finders/spree_cm_commissioner/places/find_with_route.rb +43 -0
- data/app/finders/spree_cm_commissioner/routes/find_popular.rb +25 -0
- data/app/interactors/spree_cm_commissioner/create_ticket.rb +2 -0
- data/app/interactors/spree_cm_commissioner/host_matcher.rb +1 -1
- data/app/interactors/spree_cm_commissioner/vendor_creation_telegram_alert_sender.rb +1 -1
- data/app/mailers/spree/order_mailer_decorator.rb +12 -11
- data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +34 -89
- data/app/models/concerns/spree_cm_commissioner/service_recommendations.rb +2 -2
- data/app/models/concerns/spree_cm_commissioner/store_preference.rb +1 -0
- data/app/models/spree_cm_commissioner/adjustment_decorator.rb +1 -1
- data/app/models/spree_cm_commissioner/calculators/extra_drop_off_distance.rb +15 -0
- data/app/models/spree_cm_commissioner/calculators/extra_pick_up_distance.rb +15 -0
- data/app/models/spree_cm_commissioner/place.rb +7 -0
- data/app/models/spree_cm_commissioner/pricing_action.rb +27 -0
- data/app/models/spree_cm_commissioner/pricing_model.rb +18 -0
- data/app/models/spree_cm_commissioner/pricing_model_variant.rb +6 -0
- data/app/models/spree_cm_commissioner/pricing_rule.rb +15 -0
- data/app/models/spree_cm_commissioner/pricing_rule_group.rb +20 -0
- data/app/models/spree_cm_commissioner/pricing_rules/extra_drop_off_distance.rb +10 -0
- data/app/models/spree_cm_commissioner/pricing_rules/extra_pick_up_distance.rb +12 -0
- data/app/models/spree_cm_commissioner/pricing_rules/nationality.rb +35 -0
- data/app/models/spree_cm_commissioner/product_completion_step.rb +4 -1
- data/app/models/spree_cm_commissioner/product_completion_step_banner.rb +12 -0
- data/app/models/spree_cm_commissioner/product_completion_steps/social_entry_url.rb +86 -19
- data/app/models/spree_cm_commissioner/tenant.rb +14 -1
- data/app/models/spree_cm_commissioner/variant_decorator.rb +3 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/vendor_place.rb +10 -1
- data/app/overrides/spree/admin/stores/_form/store_preferences.html.erb.deface +9 -0
- data/app/queries/spree_cm_commissioner/trip_query.rb +23 -17
- data/app/request_schemas/spree_cm_commissioner/intercity_taxi_draft_order_schema.rb +10 -0
- data/app/request_schemas/spree_cm_commissioner/intercity_taxi_draft_order_update_schema.rb +29 -0
- data/app/request_schemas/spree_cm_commissioner/route_places_request_schema.rb +12 -0
- data/app/serializers/spree/v2/storefront/place_serializer.rb +3 -2
- data/app/serializers/spree/v2/tenant/cart_serializer.rb +1 -0
- data/app/serializers/spree/v2/tenant/intercity_taxi_cart_serializer.rb +12 -0
- data/app/serializers/spree/v2/tenant/line_item_serializer.rb +1 -0
- data/app/serializers/spree/v2/tenant/trip_place_serializer.rb +8 -0
- data/app/serializers/spree/v2/tenant/trip_query_result_serializer.rb +8 -0
- data/app/serializers/spree/v2/tenant/trip_serializer.rb +8 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/intercity_taxi_line_item_serializer.rb +17 -18
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_serializer.rb +12 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_vehicle_serializer.rb +1 -1
- data/app/services/spree_cm_commissioner/intercity_taxi_order/create.rb +20 -23
- data/app/services/spree_cm_commissioner/intercity_taxi_order/update.rb +36 -72
- data/app/services/spree_cm_commissioner/pricing_models/apply.rb +51 -0
- data/app/services/spree_cm_commissioner/pricing_rules/build_params.rb +53 -0
- data/app/services/spree_cm_commissioner/pricing_rules/build_template.rb +27 -0
- data/app/services/spree_cm_commissioner/pricing_rules/create.rb +10 -0
- data/app/services/spree_cm_commissioner/pricing_rules/update.rb +11 -0
- data/app/services/spree_cm_commissioner/vendor_places/base.rb +24 -0
- data/app/services/spree_cm_commissioner/vendor_places/bulk_create.rb +70 -0
- data/app/services/spree_cm_commissioner/vendor_places/create_with_google_map_data.rb +85 -0
- data/app/services/spree_cm_commissioner/vendor_places/update.rb +56 -0
- data/app/views/shared/_asset_field.html.erb +13 -0
- data/app/views/spree/admin/product_completion_steps/_form.html.erb +28 -2
- data/app/views/spree/admin/product_completion_steps/_supported_fields.html.erb +33 -0
- data/app/views/spree/admin/tenants/_form.html.erb +1 -1
- data/app/views/spree/order_mailer/confirm_email.html.erb +1 -1
- data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +14 -13
- data/app/views/spree_cm_commissioner/order_mailer/tenant/_greeting.html.erb +6 -4
- data/config/initializers/spree_permitted_attributes.rb +1 -0
- data/config/locales/en.yml +4 -0
- data/config/locales/km.yml +65 -61
- data/config/routes.rb +15 -1
- data/db/migrate/20250915075830_create_spree_cm_commissioner_pricing_models.rb +17 -0
- data/db/migrate/20250915080733_create_spree_cm_commissioner_pricing_model_variants.rb +14 -0
- data/db/migrate/20251003082144_create_spree_cm_commissioner_pricing_rule_groups.rb +16 -0
- data/db/migrate/20251003093408_create_spree_cm_commissioner_pricing_rule.rb +19 -0
- data/db/migrate/20251003093643_create_spree_cm_commissioner_pricing_action.rb +14 -0
- data/db/migrate/20251119093000_add_tenant_id_to_cm_vendor_places.rb +8 -0
- data/lib/spree_cm_commissioner/intercity_taxi/distance.rb +38 -0
- data/lib/spree_cm_commissioner/intercity_taxi/map_place.rb +31 -0
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_action_factory.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_model_factory.rb +8 -0
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_rule_factory.rb +17 -0
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_rule_group_factory.rb +8 -0
- data/lib/spree_cm_commissioner/test_helper/factories/product_completion_step_banner_factory.rb +7 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +2 -0
- metadata +54 -4
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module PricingRules
|
|
3
|
+
class BuildTemplate
|
|
4
|
+
def self.call(pricing_model:, template_key:)
|
|
5
|
+
template = PRICING_RULE_GROUP_TEMPLATES[template_key.to_sym]
|
|
6
|
+
return unless template
|
|
7
|
+
|
|
8
|
+
group = pricing_model.pricing_rule_groups.build
|
|
9
|
+
|
|
10
|
+
template[:rules]&.each do |rule_data|
|
|
11
|
+
group.pricing_rules.where(type: rule_data[:type]).build(
|
|
12
|
+
type: rule_data[:type],
|
|
13
|
+
private_metadata: rule_data[:private_metadata] || {}
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if template[:action]
|
|
18
|
+
calculator = template[:action][:calculator_type].constantize.new
|
|
19
|
+
BuildParams.set_preferences(calculator, template[:action][:preferences])
|
|
20
|
+
group.build_pricing_action(calculator: calculator)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
group
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module VendorPlaces
|
|
3
|
+
class Base
|
|
4
|
+
prepend ::Spree::ServiceModule::Base
|
|
5
|
+
|
|
6
|
+
ALLOWED_PLACE_TYPES = %w[venue stop branch location].freeze
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def validate_place_type!(place_type)
|
|
11
|
+
return I18n.t('controller.vendor_places.place_type_required', default: 'Place type is required') if place_type.nil?
|
|
12
|
+
|
|
13
|
+
unless ALLOWED_PLACE_TYPES.include?(place_type.to_s)
|
|
14
|
+
return I18n.t(
|
|
15
|
+
'controller.vendor_places.invalid_place_type',
|
|
16
|
+
default: "Place type must be one of: #{ALLOWED_PLACE_TYPES.join(', ')}"
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Bulk creates vendor places of any valid type (e.g., :stop, :branch, :location) with validation and transaction support.
|
|
2
|
+
#
|
|
3
|
+
# Validates place_ids count and creates vendor places atomically.
|
|
4
|
+
# Rolls back all changes if any creation fails.
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# result = SpreeCmCommissioner::VendorPlaces::BulkCreate.call(
|
|
8
|
+
# vendor: current_vendor,
|
|
9
|
+
# place_ids: [1, 2, 3],
|
|
10
|
+
# place_type: :location, # or :stop, :branch, etc.
|
|
11
|
+
# description: "Sample description",
|
|
12
|
+
# max_count: 10,
|
|
13
|
+
# location: parent_location # required for :stop and :branch
|
|
14
|
+
# )
|
|
15
|
+
#
|
|
16
|
+
# if result.success?
|
|
17
|
+
# created_vendor_places = result.value
|
|
18
|
+
# else
|
|
19
|
+
# error_message = result.error
|
|
20
|
+
|
|
21
|
+
module SpreeCmCommissioner
|
|
22
|
+
module VendorPlaces
|
|
23
|
+
class BulkCreate < Base
|
|
24
|
+
def call(vendor:, place_ids:, place_type:, description: nil, max_count: 10, location: nil) # rubocop:disable Metrics/ParameterLists
|
|
25
|
+
error_message = validate_inputs!(place_ids: place_ids, place_type: place_type, max_count: max_count, location: location)
|
|
26
|
+
return failure(nil, error_message) if error_message
|
|
27
|
+
|
|
28
|
+
created_vendor_places = []
|
|
29
|
+
|
|
30
|
+
ActiveRecord::Base.transaction do
|
|
31
|
+
place_ids.each do |place_id|
|
|
32
|
+
vendor_place = build_vendor_place(
|
|
33
|
+
vendor: vendor,
|
|
34
|
+
place_id: place_id,
|
|
35
|
+
place_type: place_type,
|
|
36
|
+
description: description,
|
|
37
|
+
location: location
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
vendor_place.save!
|
|
41
|
+
created_vendor_places << vendor_place
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
success(created_vendor_places)
|
|
46
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
47
|
+
failure(nil, e.record.errors.full_messages.to_sentence)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def validate_inputs!(place_ids:, place_type:, max_count:, location: nil)
|
|
53
|
+
validate_place_type!(place_type) ||
|
|
54
|
+
(place_ids.blank? && I18n.t('controller.vendor_places.place_ids_blank')) ||
|
|
55
|
+
(place_ids.size > max_count && I18n.t('controller.vendor_places.selection_limit', count: max_count)) ||
|
|
56
|
+
(requires_location?(place_type: place_type) && location.blank? && I18n.t('controller.vendor_places.location_required'))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def build_vendor_place(vendor:, place_id:, place_type:, description:, location: nil)
|
|
60
|
+
attrs = { vendor_id: vendor.id, place_type: place_type.to_sym, place_id: place_id, description: description }
|
|
61
|
+
attrs[:location_id] = location&.id if requires_location?(place_type: place_type)
|
|
62
|
+
SpreeCmCommissioner::VendorPlace.new(attrs)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def requires_location?(place_type:)
|
|
66
|
+
%i[stop branch].include?(place_type.to_sym)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Creates a vendor place from Google Map base64-encoded place data.
|
|
2
|
+
# Processes place data and creates both Place and VendorPlace records atomically.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# result = SpreeCmCommissioner::VendorPlaces::CreateWithGoogleMapData.call(
|
|
6
|
+
# vendor: current_vendor,
|
|
7
|
+
# place_type: 'stop',
|
|
8
|
+
# google_place_base_64_content: google_place_base_64_content,
|
|
9
|
+
# description: 'Main Warehouse',
|
|
10
|
+
# location: parent_vendor_location
|
|
11
|
+
# )
|
|
12
|
+
#
|
|
13
|
+
# if result.success?
|
|
14
|
+
# vendor_place = result.value
|
|
15
|
+
# else
|
|
16
|
+
# error_message = result.error
|
|
17
|
+
# end
|
|
18
|
+
|
|
19
|
+
module SpreeCmCommissioner
|
|
20
|
+
module VendorPlaces
|
|
21
|
+
class CreateWithGoogleMapData < Base
|
|
22
|
+
def call(vendor:, place_type:, google_place_base_64_content:, description: nil, location: nil)
|
|
23
|
+
error_message = validate_place_type!(place_type)
|
|
24
|
+
return failure(nil, error_message) if error_message.present?
|
|
25
|
+
|
|
26
|
+
# Only require location for stop and branch types
|
|
27
|
+
return failure(nil, I18n.t('controller.vendor_places.location_required')) if %w[stop branch].include?(place_type) && location.nil?
|
|
28
|
+
|
|
29
|
+
place = process_place(google_place_base_64_content: google_place_base_64_content)
|
|
30
|
+
return failure(nil, place) unless place.is_a?(SpreeCmCommissioner::Place)
|
|
31
|
+
|
|
32
|
+
vendor_place = create_vendor_place(vendor: vendor, place: place, place_type: place_type, description: description, location: location)
|
|
33
|
+
return failure(nil, vendor_place) if vendor_place.nil? || vendor_place.is_a?(String)
|
|
34
|
+
|
|
35
|
+
success(vendor_place)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def process_place(google_place_base_64_content:)
|
|
41
|
+
place = SpreeCmCommissioner::PlaceDecoder.process_place(google_place_base_64_content)
|
|
42
|
+
return I18n.t('controller.vendor_places.process_place_failed', default: 'Failed to process place') if place.nil? || !place.save
|
|
43
|
+
|
|
44
|
+
place
|
|
45
|
+
rescue StandardError => e
|
|
46
|
+
e.message
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def create_vendor_place(vendor:, place:, place_type:, description:, location:)
|
|
50
|
+
error_message = nil
|
|
51
|
+
result = ActiveRecord::Base.transaction do
|
|
52
|
+
vendor_place = build_vendor_place(vendor: vendor, place: place, type: place_type, description: description, location: location)
|
|
53
|
+
unless vendor_place.save
|
|
54
|
+
error_message = vendor_place.errors.full_messages.to_sentence
|
|
55
|
+
raise ActiveRecord::Rollback
|
|
56
|
+
end
|
|
57
|
+
vendor_place
|
|
58
|
+
end
|
|
59
|
+
error_message || result
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def build_vendor_place(vendor:, place:, type:, description: nil, location: nil)
|
|
63
|
+
case type
|
|
64
|
+
when 'stop'
|
|
65
|
+
vendor.stops.new(
|
|
66
|
+
place_id: place.id,
|
|
67
|
+
description: description,
|
|
68
|
+
location_id: location&.id
|
|
69
|
+
)
|
|
70
|
+
when 'branch'
|
|
71
|
+
vendor.branches.new(
|
|
72
|
+
place_id: place.id,
|
|
73
|
+
description: description,
|
|
74
|
+
location_id: location&.id
|
|
75
|
+
)
|
|
76
|
+
when 'location'
|
|
77
|
+
vendor.locations.new(
|
|
78
|
+
place_id: place.id,
|
|
79
|
+
description: description
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Updates all vendor places matching the same vendor, place_id, and location_id.
|
|
2
|
+
# Only updates description and location_id. Rolls back if any update fails.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# result = SpreeCmCommissioner::VendorPlaces::Update.call(
|
|
6
|
+
# vendor: current_vendor,
|
|
7
|
+
# vendor_place: existing_vendor_place,
|
|
8
|
+
# location_id: new_location_id,
|
|
9
|
+
# description: 'Updated description'
|
|
10
|
+
# )
|
|
11
|
+
#
|
|
12
|
+
# if result.success?
|
|
13
|
+
# updated_place = result.value
|
|
14
|
+
# else
|
|
15
|
+
# error_message = result.error
|
|
16
|
+
# end
|
|
17
|
+
module SpreeCmCommissioner
|
|
18
|
+
module VendorPlaces
|
|
19
|
+
class Update < Base
|
|
20
|
+
def call(vendor:, vendor_place:, description: nil, location_id: nil)
|
|
21
|
+
if vendor_place.blank?
|
|
22
|
+
return failure(
|
|
23
|
+
nil,
|
|
24
|
+
I18n.t('controller.vendor_places.vendor_place_not_found', default: 'Vendor place not found')
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
ActiveRecord::Base.transaction do
|
|
29
|
+
related_places = SpreeCmCommissioner::VendorPlace.where(
|
|
30
|
+
vendor_id: vendor.id,
|
|
31
|
+
place_id: vendor_place.place_id,
|
|
32
|
+
location_id: vendor_place.location_id
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
update_attrs = {}
|
|
36
|
+
update_attrs[:description] = description unless description.nil?
|
|
37
|
+
update_attrs[:location_id] = location_id unless location_id.nil?
|
|
38
|
+
|
|
39
|
+
related_places.each do |vp|
|
|
40
|
+
unless vp.update(update_attrs)
|
|
41
|
+
error_message = vp.errors.full_messages.to_sentence
|
|
42
|
+
raise ActiveRecord::Rollback, error_message
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
vendor_place.reload
|
|
48
|
+
success(vendor_place)
|
|
49
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
50
|
+
failure(nil, e.record.errors.full_messages.to_sentence)
|
|
51
|
+
rescue ActiveRecord::Rollback => e
|
|
52
|
+
failure(nil, e.message)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -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="
|
|
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="
|
|
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: '
|
|
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 %>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
<% else %>
|
|
18
18
|
<div class="f-fallback">
|
|
19
|
-
<%= render 'spree_cm_commissioner/order_mailer/tenant/greeting', order: @order %>
|
|
19
|
+
<%= render 'spree_cm_commissioner/order_mailer/tenant/greeting', order: @order, logo: @logo, name: @name%>
|
|
20
20
|
<div class="content">
|
|
21
21
|
<%= render 'spree_cm_commissioner/order_mailer/order_total', order: @order %>
|
|
22
22
|
<%= render 'spree_cm_commissioner/order_mailer/your_booking', order: @order, show_booking_header: true %>
|
|
@@ -74,7 +74,9 @@
|
|
|
74
74
|
background-position: center;
|
|
75
75
|
background-repeat: no-repeat;
|
|
76
76
|
border-radius: 1.5625rem 1.5625rem 0 0;
|
|
77
|
-
|
|
77
|
+
<% if @brand_color.present? %>
|
|
78
|
+
background: <%= @brand_color %>;
|
|
79
|
+
<% end %>
|
|
78
80
|
}
|
|
79
81
|
#confirm-email #greeting-card-1 p,
|
|
80
82
|
#confirm-email #greeting-card-1 .header,
|
|
@@ -93,21 +95,20 @@
|
|
|
93
95
|
margin-bottom: 0.625rem;
|
|
94
96
|
}
|
|
95
97
|
#confirm-email .icon-hang-meas {
|
|
96
|
-
width:
|
|
97
|
-
|
|
98
|
-
border-radius: 50%;
|
|
99
|
-
background-color: #fff;
|
|
100
|
-
display: flex;
|
|
101
|
-
align-items: center;
|
|
102
|
-
justify-content: center;
|
|
103
|
-
overflow: hidden;
|
|
98
|
+
width: 50%;
|
|
99
|
+
text-align: right;
|
|
104
100
|
}
|
|
105
|
-
|
|
106
101
|
#confirm-email .icon-hang-meas img {
|
|
107
|
-
width:
|
|
108
|
-
height:
|
|
109
|
-
object-fit: cover;
|
|
102
|
+
width: 6.25rem;
|
|
103
|
+
height: 6.25rem;
|
|
110
104
|
border-radius: 50%;
|
|
105
|
+
background-color: #fff;
|
|
106
|
+
display: inline-block;
|
|
107
|
+
}
|
|
108
|
+
#confirm-email .header h1 {
|
|
109
|
+
margin: 0;
|
|
110
|
+
color: #fff;
|
|
111
|
+
width: 50%;
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
#confirm-email .header {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<div id="greeting-card-1">
|
|
2
2
|
<div>
|
|
3
3
|
<div class="header">
|
|
4
|
-
<h1
|
|
5
|
-
<% if
|
|
6
|
-
<
|
|
4
|
+
<h1><%= name %></h1>
|
|
5
|
+
<% if logo.present? %>
|
|
6
|
+
<div class="icon-hang-meas">
|
|
7
|
+
<img src="<%= logo %>" alt="<%= name %> Logo">
|
|
8
|
+
</div>
|
|
7
9
|
<% end %>
|
|
8
10
|
</div>
|
|
9
11
|
<div class="booking-confirm">
|
|
@@ -13,7 +15,7 @@
|
|
|
13
15
|
<%= I18n.t('mail.order_mailer.hello', full_name: user_full_name(order)) %>
|
|
14
16
|
</div>
|
|
15
17
|
<div class="description">
|
|
16
|
-
<%= I18n.t('mail.order_mailer.booking_event', order_number:
|
|
18
|
+
<%= I18n.t('mail.order_mailer.booking_event', order_number: order.number || 'NA') %>
|
|
17
19
|
</div>
|
|
18
20
|
</div>
|
|
19
21
|
</div>
|
|
@@ -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: {} },
|
data/config/locales/en.yml
CHANGED
data/config/locales/km.yml
CHANGED
|
@@ -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
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
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 %": "ភាគរយនៃបំលាស់ប្តូរ"
|