spree_cm_commissioner 2.5.0.pre.pre7 → 2.5.0.pre.pre8

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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test_and_build_gem.yml +1 -1
  3. data/.tool-versions +1 -1
  4. data/Gemfile.lock +1 -1
  5. data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +7 -1
  6. data/app/controllers/spree/api/v2/storefront/route_places_controller.rb +9 -9
  7. data/app/finders/spree_cm_commissioner/places/find_with_route.rb +10 -10
  8. data/app/finders/spree_cm_commissioner/routes/find_popular.rb +10 -14
  9. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +1 -1
  10. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +3 -3
  11. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +3 -15
  12. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +0 -2
  13. data/app/models/concerns/spree_cm_commissioner/store_metadata.rb +2 -14
  14. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +3 -0
  15. data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +7 -1
  16. data/app/models/spree_cm_commissioner/guest.rb +0 -13
  17. data/app/models/spree_cm_commissioner/inventory_item.rb +1 -5
  18. data/app/models/spree_cm_commissioner/line_item_decorator.rb +1 -13
  19. data/app/models/spree_cm_commissioner/option_type_decorator.rb +0 -8
  20. data/app/models/spree_cm_commissioner/option_value_decorator.rb +0 -34
  21. data/app/models/spree_cm_commissioner/order_decorator.rb +0 -1
  22. data/app/models/spree_cm_commissioner/product_decorator.rb +2 -3
  23. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +2 -2
  24. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +2 -2
  25. data/app/models/spree_cm_commissioner/taxon_decorator.rb +0 -1
  26. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +1 -13
  27. data/app/models/spree_cm_commissioner/variant_decorator.rb +4 -7
  28. data/app/models/spree_cm_commissioner/vendor_decorator.rb +0 -4
  29. data/app/presenters/spree/variants/{visible_options_presenter.rb → visable_options_presenter.rb} +4 -2
  30. data/app/request_schemas/spree_cm_commissioner/popular_route_places_request_schema.rb +12 -0
  31. data/app/request_schemas/spree_cm_commissioner/route_places_request_schema.rb +5 -0
  32. data/app/views/spree/admin/tenants/_form.html.erb +18 -0
  33. data/app/views/spree/admin/tenants/form/_footer.html.erb +31 -0
  34. data/app/views/spree/admin/tenants/form/_social.html.erb +31 -0
  35. data/app/views/spree/order_mailer/confirm_email.html.erb +1 -1
  36. data/app/views/spree_cm_commissioner/layouts/order_mailer.html.erb +1 -1
  37. data/app/views/spree_cm_commissioner/order_mailer/tenant/_footer.html.erb +13 -6
  38. data/app/views/spree_cm_commissioner/order_mailer/tenant/_support_contact.html.erb +23 -24
  39. data/config/locales/en.yml +0 -8
  40. data/config/locales/km.yml +0 -8
  41. data/config/routes.rb +0 -8
  42. data/db/migrate/20251209022924_add_contact_fields_to_cm_tenants.rb +9 -0
  43. data/lib/cm_app_logger.rb +3 -21
  44. data/lib/spree_cm_commissioner/version.rb +1 -1
  45. data/lib/spree_cm_commissioner.rb +7 -8
  46. metadata +7 -57
  47. data/app/controllers/spree/admin/integration_mappings_controller.rb +0 -21
  48. data/app/controllers/spree/admin/integration_sessions_controller.rb +0 -21
  49. data/app/controllers/spree/admin/integrations_controller.rb +0 -83
  50. data/app/controllers/spree/api/v2/storefront/event_matches_controller.rb +0 -15
  51. data/app/errors/spree_cm_commissioner/integrations/external_client_error.rb +0 -10
  52. data/app/errors/spree_cm_commissioner/integrations/sync_error.rb +0 -4
  53. data/app/finders/spree_cm_commissioner/events/find_matches.rb +0 -15
  54. data/app/helpers/spree_cm_commissioner/external_integrations_helper.rb +0 -58
  55. data/app/jobs/spree_cm_commissioner/integrations/base_job.rb +0 -39
  56. data/app/jobs/spree_cm_commissioner/integrations/polling_job.rb +0 -53
  57. data/app/jobs/spree_cm_commissioner/integrations/polling_scheduler_job.rb +0 -30
  58. data/app/jobs/spree_cm_commissioner/telegram_alerts/integration_sync_failure_job.rb +0 -17
  59. data/app/models/concerns/spree_cm_commissioner/integrations/integration_mappable.rb +0 -61
  60. data/app/models/concerns/spree_cm_commissioner/line_item_integration.rb +0 -36
  61. data/app/models/concerns/spree_cm_commissioner/order_integration.rb +0 -33
  62. data/app/models/spree_cm_commissioner/integration.rb +0 -29
  63. data/app/models/spree_cm_commissioner/integration_mapping.rb +0 -41
  64. data/app/models/spree_cm_commissioner/integration_sync_session.rb +0 -15
  65. data/app/models/spree_cm_commissioner/integrations/stadium_x_v1.rb +0 -37
  66. data/app/overrides/spree/admin/shared/sub_menu/_integrations/external_integrations.html.erb.deface +0 -6
  67. data/app/services/spree_cm_commissioner/integrations/base/sync_manager.rb +0 -69
  68. data/app/services/spree_cm_commissioner/integrations/base/sync_result.rb +0 -183
  69. data/app/services/spree_cm_commissioner/integrations/polling.rb +0 -70
  70. data/app/services/spree_cm_commissioner/integrations/polling_scheduler.rb +0 -79
  71. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/external_client/client.rb +0 -152
  72. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/inventory/unstock_inventory.rb +0 -83
  73. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb +0 -113
  74. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_zones.rb +0 -215
  75. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/base.rb +0 -20
  76. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/league.rb +0 -19
  77. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/match.rb +0 -95
  78. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/ticket.rb +0 -81
  79. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/ticket_image.rb +0 -19
  80. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/zone.rb +0 -90
  81. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_manager.rb +0 -35
  82. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/full_sync_strategy.rb +0 -38
  83. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/incremental_sync_strategy.rb +0 -44
  84. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/webhook_sync_strategy.rb +0 -16
  85. data/app/services/spree_cm_commissioner/telegram_alerts/integration_sync_failure.rb +0 -49
  86. data/app/views/spree/admin/integration_mappings/_integration_mappings.html.erb +0 -107
  87. data/app/views/spree/admin/integration_mappings/index.html.erb +0 -33
  88. data/app/views/spree/admin/integration_sessions/_integration_sync_sessions.html.erb +0 -116
  89. data/app/views/spree/admin/integration_sessions/index.html.erb +0 -42
  90. data/app/views/spree/admin/integrations/_form.html.erb +0 -104
  91. data/app/views/spree/admin/integrations/_stadium_x_v1_fields.html.erb +0 -29
  92. data/app/views/spree/admin/integrations/edit.html.erb +0 -45
  93. data/app/views/spree/admin/integrations/index.html.erb +0 -75
  94. data/app/views/spree/admin/integrations/new.html.erb +0 -25
  95. data/db/migrate/20251017094845_create_cm_integrations.rb +0 -22
  96. data/db/migrate/20251017101555_create_cm_integration_sync_sessions.rb +0 -68
  97. data/db/migrate/20251017101605_create_cm_integration_mappings.rb +0 -52
  98. data/lib/spree_cm_commissioner/test_helper/factories/integration_factory.rb +0 -25
  99. data/lib/spree_cm_commissioner/test_helper/factories/integration_mapping_factory.rb +0 -14
  100. data/lib/spree_cm_commissioner/test_helper/factories/integration_sync_session_factory.rb +0 -7
@@ -1,95 +0,0 @@
1
- class SpreeCmCommissioner::Integrations::StadiumXV1
2
- module Resources
3
- class Match < Base
4
- attr_accessor :_id,
5
- :home_name,
6
- :home_logo,
7
- :away_name,
8
- :away_logo,
9
- :home_score,
10
- :away_score,
11
- :date,
12
- :time,
13
- :stadium,
14
- :week,
15
- :league_id,
16
- :club_id,
17
- :discount_ticket,
18
- :on_sale,
19
- :is_ended,
20
- :allow_predition,
21
- :file,
22
- :created_by,
23
- :updated_by,
24
- :zones,
25
- :promotion,
26
- :poster,
27
- :league
28
-
29
- def initialize(attributes = {})
30
- super(attributes)
31
-
32
- @on_sale = attributes['on_sale'] != false
33
- @is_ended = attributes['is_ended'] == true || attributes['is_ended'] == 'true'
34
- @allow_predition = attributes['allow_predition'] == true || attributes['allow_predition'] == 'true'
35
- @league = League.new(attributes['league']) if attributes['league'].is_a?(Hash)
36
- end
37
-
38
- def meta_title
39
- return nil if home_name.blank? || away_name.blank?
40
-
41
- "#{home_name} vs #{away_name} - #{display_match_datetime}"
42
- end
43
-
44
- def meta_description
45
- return nil if home_name.blank? || away_name.blank?
46
-
47
- location = stadium.present? ? " at #{stadium}" : ''
48
- league_info = league&.name.present? ? " - #{league.name}" : ''
49
-
50
- "#{home_name} vs #{away_name}#{league_info} on #{display_match_datetime}#{location}. Book tickets now!"
51
- end
52
-
53
- def display_match_datetime
54
- match_datetime&.strftime('%B %d, %Y at %I:%M %p')
55
- end
56
-
57
- def match_datetime
58
- return nil unless @date && @time
59
-
60
- Time.zone.parse("#{@date} #{@time}")
61
- rescue StandardError
62
- nil
63
- end
64
-
65
- def to_h
66
- {
67
- _id: _id,
68
- home_name: home_name,
69
- home_logo: home_logo,
70
- away_name: away_name,
71
- away_logo: away_logo,
72
- home_score: home_score,
73
- away_score: away_score,
74
- date: date,
75
- time: time,
76
- stadium: stadium,
77
- week: week,
78
- league_id: league_id,
79
- club_id: club_id,
80
- discount_ticket: discount_ticket,
81
- on_sale: on_sale,
82
- is_ended: is_ended,
83
- allow_predition: allow_predition,
84
- file: file,
85
- created_by: created_by,
86
- updated_by: updated_by,
87
- zones: zones&.map(&:to_h),
88
- promotion: promotion,
89
- poster: poster,
90
- league: league&.to_h
91
- }.compact
92
- end
93
- end
94
- end
95
- end
@@ -1,81 +0,0 @@
1
- class SpreeCmCommissioner::Integrations::StadiumXV1
2
- module Resources
3
- class Ticket < Base
4
- attr_accessor :_id,
5
- :match_id,
6
- :uid,
7
- :first_uid,
8
- :generated_by,
9
- :club_id,
10
- :zone_id,
11
- :league_id,
12
- :token_id,
13
- :payment_method,
14
- :ticket_type,
15
- :remark,
16
- :is_used,
17
- :is_online,
18
- :used_at,
19
- :is_expired,
20
- :created_at,
21
- :updated_at,
22
- :cashback,
23
- :__v
24
-
25
- def initialize(attributes = {})
26
- super(attributes)
27
-
28
- @is_used = attributes['is_used'] == true || attributes['is_used'] == 'true'
29
- @is_online = attributes['is_online'] != false
30
- @is_expired = attributes['is_expired'] == true || attributes['is_expired'] == 'true'
31
- @created_at = parse_timestamp(attributes['created_at'])
32
- @updated_at = parse_timestamp(attributes['updated_at'])
33
- @used_at = parse_timestamp(attributes['used_at'])
34
- end
35
-
36
- def to_h
37
- {
38
- _id: _id,
39
- match_id: match_id,
40
- uid: uid,
41
- first_uid: first_uid,
42
- generated_by: generated_by,
43
- club_id: club_id,
44
- zone_id: zone_id,
45
- league_id: league_id,
46
- token_id: token_id,
47
- payment_method: payment_method,
48
- ticket_type: ticket_type,
49
- remark: remark,
50
- is_used: is_used,
51
- is_online: is_online,
52
- used_at: used_at&.iso8601,
53
- is_expired: is_expired,
54
- created_at: created_at&.iso8601,
55
- updated_at: updated_at&.iso8601,
56
- cashback: cashback,
57
- __v: __v
58
- }.compact
59
- end
60
-
61
- private
62
-
63
- # Parses timestamp values from the Stadium X API response.
64
- # The API returns timestamps in two formats:
65
- # 1. Hash format with 'low' and 'high' properties (Long type from backend): {"low"=>239159874, "high"=>411, "unsigned"=>false}
66
- # 2. Numeric format (milliseconds since epoch): 1702353644000
67
- # Converts millisecond timestamps to Time objects in the application's timezone.
68
- # Returns nil if the value is blank or in an unsupported format.
69
- def parse_timestamp(value)
70
- return nil if value.blank?
71
-
72
- if value.is_a?(Hash)
73
- timestamp_ms = (value['high'].to_i << 32) | value['low'].to_i
74
- Time.zone.at(timestamp_ms / 1000)
75
- elsif value.is_a?(Numeric)
76
- Time.zone.at(value / 1000)
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,19 +0,0 @@
1
- class SpreeCmCommissioner::Integrations::StadiumXV1
2
- module Resources
3
- class TicketImage < Base
4
- attr_accessor :zone_id,
5
- :ticket_image
6
-
7
- def initialize(attributes = {})
8
- super(attributes)
9
- end
10
-
11
- def to_h
12
- {
13
- zone_id: zone_id,
14
- ticket_image: ticket_image
15
- }.compact
16
- end
17
- end
18
- end
19
- end
@@ -1,90 +0,0 @@
1
- class SpreeCmCommissioner::Integrations::StadiumXV1
2
- module Resources
3
- class Zone < Base
4
- attr_accessor :_id,
5
- :title,
6
- :color_brand,
7
- :total_seats,
8
- :online_price,
9
- :walkin_price,
10
- :match_id,
11
- :club_id,
12
- :is_active,
13
- :created_by,
14
- :updated_by,
15
- :created_at,
16
- :updated_at,
17
- :end_datetime,
18
- :is_earlybird,
19
- :start_datetime,
20
- :available_seats,
21
- :ticket_image
22
-
23
- def initialize(attributes = {})
24
- super(attributes)
25
-
26
- @total_seats = attributes['total_seats'].to_i
27
- @available_seats = attributes['available_seats'].to_i
28
- @online_price = attributes['online_price'].to_f
29
- @walkin_price = attributes['walkin_price'].to_f
30
- @is_active = attributes['is_active'] != false
31
- @color_brand = valid_hex_color?(attributes['color_brand']) ? attributes['color_brand'].upcase : nil
32
-
33
- @created_at = Time.zone.at(attributes['created_at'] / 1000) if attributes['created_at'].present?
34
- @updated_at = Time.zone.at(attributes['updated_at'] / 1000) if attributes['updated_at'].present?
35
-
36
- @start_datetime = Time.zone.parse(attributes['start_datetime']) if attributes['start_datetime'].present?
37
- @end_datetime = Time.zone.parse(attributes['end_datetime']) if attributes['end_datetime'].present?
38
- @ticket_image = TicketImage.new(attributes['ticket_image']) if attributes['ticket_image'].is_a?(Hash)
39
- end
40
-
41
- # Manually set the match_id on the zone object.
42
- # This is needed because the API does not return match_id but it's required for ticket creation.
43
- # This is a temporary workaround until the API returns the match_id.
44
- def set_match_id(match_id) # rubocop:disable Naming/AccessorMethodName
45
- @match_id = match_id
46
- end
47
-
48
- def to_hash
49
- hash = {
50
- '_id' => _id,
51
- 'title' => title,
52
- 'color_brand' => color_brand,
53
- 'total_seats' => total_seats,
54
- 'online_price' => online_price,
55
- 'walkin_price' => walkin_price,
56
- 'match_id' => match_id,
57
- 'club_id' => club_id,
58
- 'is_active' => is_active,
59
- 'created_by' => created_by,
60
- 'updated_by' => updated_by,
61
- 'created_at' => created_at&.iso8601,
62
- 'updated_at' => updated_at&.iso8601,
63
- 'end_datetime' => end_datetime&.iso8601,
64
- 'is_earlybird' => is_earlybird,
65
- 'start_datetime' => start_datetime&.iso8601,
66
- 'available_seats' => available_seats,
67
- 'ticket_image' => ticket_image&.to_h
68
- }.compact
69
-
70
- hash['ticket_image'] = hash['ticket_image'].transform_keys(&:to_s) if hash['ticket_image']
71
-
72
- hash
73
- end
74
-
75
- alias to_h to_hash
76
-
77
- private
78
-
79
- # Validates if a color value is a valid hex color code.
80
- # Accepts formats: #RRGGBB, #RRGGBBAA, RRGGBB, RRGGBBAA (with or without # prefix)
81
- # Returns true only if the value is a valid hex color, false otherwise.
82
- def valid_hex_color?(value)
83
- return false if value.blank?
84
-
85
- hex_pattern = /\A#?([0-9a-fA-F]{6}|[0-9a-fA-F]{8})\z/
86
- hex_pattern.match?(value.to_s)
87
- end
88
- end
89
- end
90
- end
@@ -1,35 +0,0 @@
1
- class SpreeCmCommissioner::Integrations::StadiumXV1
2
- class SyncManager < ::SpreeCmCommissioner::Integrations::Base::SyncManager
3
- # override
4
- def sync_full!
5
- run_execution(:full) do
6
- SyncStrategies::FullSyncStrategy.new(
7
- client: @client,
8
- integration: @integration
9
- ).call
10
- end
11
- end
12
-
13
- # override
14
- def sync_incremental!
15
- run_execution(:incremental) do
16
- SyncStrategies::IncrementalSyncStrategy.new(
17
- client: @client,
18
- integration: @integration
19
- ).call
20
- end
21
- end
22
-
23
- # override
24
- def sync_webhook!(event_type:, event_data:)
25
- run_execution(:webhook) do
26
- SyncStrategies::WebhookSyncStrategy.new(
27
- client: @client,
28
- integration: @integration,
29
- event_type: event_type,
30
- event_data: event_data
31
- ).call
32
- end
33
- end
34
- end
35
- end
@@ -1,38 +0,0 @@
1
- class SpreeCmCommissioner::Integrations::StadiumXV1
2
- module SyncStrategies
3
- # Full sync strategy - syncs all matches from external system.
4
- #
5
- # Runs on a schedule (e.g., daily) to fetch and update all matches from Stadium X V1 API.
6
- # After full sync, IncrementalSyncStrategy will sync zone data one match at a time.
7
- #
8
- # Example flow:
9
- # 1. Full sync runs at 2:00 AM
10
- # - Fetches all matches from Stadium X V1
11
- # - Creates/updates match records
12
- # - Creates integration mappings
13
- # 2. Incremental sync runs every 10 seconds
14
- # - Syncs zone data for one match per interval
15
- # - Keeps data fresh without overwhelming the system
16
- class FullSyncStrategy
17
- def initialize(client:, integration:)
18
- @client = client
19
- @integration = integration
20
- @sync_result = ::SpreeCmCommissioner::Integrations::Base::SyncResult.new
21
- end
22
-
23
- def call
24
- begin
25
- Polling::SyncMatches.new(
26
- client: @client,
27
- integration: @integration,
28
- sync_result: @sync_result
29
- ).call
30
- rescue StandardError => e
31
- @sync_result.record_error(e)
32
- end
33
-
34
- @sync_result
35
- end
36
- end
37
- end
38
- end
@@ -1,44 +0,0 @@
1
- class SpreeCmCommissioner::Integrations::StadiumXV1
2
- module SyncStrategies
3
- # Incremental sync strategy - syncs zones one match at a time.
4
- #
5
- # Runs every 10 seconds to sync zone data incrementally. Instead of syncing all matches
6
- # at once (which would be slow), we sync one match per interval in round-robin order.
7
- #
8
- # Example with 3 matches:
9
- # 10:00:00 - Sync zones for Match #1 (oldest last_synced_at)
10
- # 10:00:10 - Sync zones for Match #2
11
- # 10:00:20 - Sync zones for Match #3
12
- # 10:00:30 - Sync zones for Match #1 again (cycle repeats)
13
- #
14
- # This ensures all matches get synced regularly without overwhelming the system.
15
- class IncrementalSyncStrategy
16
- def initialize(client:, integration:)
17
- @client = client
18
- @integration = integration
19
- @sync_result = ::SpreeCmCommissioner::Integrations::Base::SyncResult.new
20
- end
21
-
22
- def call
23
- begin
24
- oldest_sync_mapping = Spree::Taxon.find_oldest_active_mapping(integration_id: @integration.id)
25
- return @sync_result if oldest_sync_mapping.nil?
26
-
27
- @sync_result.increment_metric(:match, :synced)
28
-
29
- Polling::SyncZones.new(
30
- integration: @integration,
31
- client: @integration.client,
32
- sync_result: @sync_result
33
- ).call(external_match_id: oldest_sync_mapping.external_id)
34
-
35
- oldest_sync_mapping.update!(last_synced_at: Time.current)
36
- rescue StandardError => e
37
- @sync_result.record_error(e)
38
- end
39
-
40
- @sync_result
41
- end
42
- end
43
- end
44
- end
@@ -1,16 +0,0 @@
1
- class SpreeCmCommissioner::Integrations::StadiumXV1
2
- module SyncStrategies
3
- class WebhookSyncStrategy
4
- def initialize(client:, integration:, event_type:, event_data:)
5
- @client = client
6
- @integration = integration
7
- @event_type = event_type
8
- @event_data = event_data
9
- end
10
-
11
- def call
12
- # TODO: Implement webhook sync logic
13
- end
14
- end
15
- end
16
- end
@@ -1,49 +0,0 @@
1
- module SpreeCmCommissioner
2
- module TelegramAlerts
3
- class IntegrationSyncFailure
4
- prepend ::Spree::ServiceModule::Base
5
-
6
- # Send Telegram alert for integration sync failure
7
- # @param error_message [String] The error message
8
- # @param data [Hash] Additional context data (e.g., sync_type, match_id, event_type)
9
- def call(error_message:, data: {})
10
- chat_id = ENV.fetch('EXCEPTION_NOTIFIER_TELEGRAM_CHANNEL_ID', nil)
11
- return failure(nil, 'Telegram chat ID not configured') if chat_id.blank?
12
-
13
- telegram_client = ::Telegram.bots[:exception_notifier]
14
- return failure(nil, 'Telegram bot not configured') if telegram_client.blank?
15
-
16
- telegram_client.send_message(
17
- chat_id: chat_id,
18
- parse_mode: 'HTML',
19
- text: format_message(error_message, data)
20
- )
21
-
22
- success(message: 'Alert sent successfully')
23
- rescue StandardError => e
24
- failure(nil, "Failed to send Telegram alert: #{e.message}")
25
- end
26
-
27
- private
28
-
29
- def format_message(error_message, data)
30
- text = []
31
-
32
- text << '🚨 <b>Integration Sync Failed</b>'
33
-
34
- # Render all data fields dynamically
35
- data.each do |key, value|
36
- next if value.blank?
37
-
38
- formatted_key = key.to_s.humanize
39
- text << "<b>#{formatted_key}:</b> <code>#{value}</code>"
40
- end
41
-
42
- text << "<b>Error:</b> <code>#{error_message}</code>"
43
- text << "<b>Time:</b> <code>#{Time.current.iso8601}</code>"
44
-
45
- text.compact.join("\n")
46
- end
47
- end
48
- end
49
- end
@@ -1,107 +0,0 @@
1
- <div class="table-responsive">
2
- <table class="table table-sm" id="listing_integration_mappings" data-hook>
3
- <thead class="text-muted">
4
- <tr>
5
- <th><%= Spree.t(:id) %></th>
6
- <th><%= Spree.t(:external_id) %></th>
7
- <th><%= Spree.t(:internal_type) %></th>
8
- <th><%= Spree.t(:internal_id) %></th>
9
- <th><%= Spree.t(:status) %></th>
10
- <th><%= Spree.t(:last_synced_at) %></th>
11
- <th><%= Spree.t(:created_at) %></th>
12
- <th><%= Spree.t(:updated_at) %></th>
13
- <th></th>
14
- </tr>
15
- </thead>
16
-
17
- <tbody>
18
- <% mappings = defined?(@mappings) ? @mappings : integration.integration_mappings.order(updated_at: :desc).limit(25) %>
19
- <% mappings.each do |mapping| %>
20
- <tr id="integration_mapping_<%= mapping.id %>">
21
- <td><%= mapping.id %></td>
22
- <td><%= mapping.external_id %></td>
23
- <td><%= mapping.internal_type %></td>
24
- <td>
25
- <%= integration_mapping_internal_link(mapping) %>
26
- </td>
27
- <td><%= mapping.status %></td>
28
- <td><%= mapping.last_synced_at %></td>
29
- <td><%= mapping.created_at %></td>
30
- <td><%= mapping.updated_at %></td>
31
-
32
- <td class="actions">
33
- <% if mapping.external_payload.present? %>
34
- <%= link_to_with_icon 'activity.svg', Spree.t("admin.external_integrations.view_result"), "#mapping_payload_modal_#{mapping.id}",
35
- class: 'btn btn-light btn-sm',
36
- no_text: true,
37
- data: { toggle: 'modal', target: "#mapping_payload_modal_#{mapping.id}" },
38
- title: Spree.t("admin.external_integrations.external_payload") %>
39
- <% end %>
40
- </td>
41
- </tr>
42
- <% end %>
43
- </tbody>
44
- </table>
45
-
46
- <% if mappings.empty? %>
47
- <small class="form-text text-muted"><%= Spree.t("admin.external_integrations.no_results") %></small>
48
- <% end %>
49
-
50
- <% if defined?(@mappings) && @mappings.respond_to?(:total_pages) %>
51
- <div class="mt-3">
52
- <%= paginate @mappings, theme: 'admin-twitter-bootstrap-4' %>
53
- </div>
54
- <% end %>
55
- </div>
56
-
57
- <% mappings.each do |mapping| %>
58
- <% if mapping.external_payload.present? %>
59
- <div
60
- class="modal fade"
61
- id="mapping_payload_modal_<%= mapping.id %>"
62
- tabindex="-1"
63
- role="dialog"
64
- aria-labelledby="mapping_payload_modal_label_<%= mapping.id %>"
65
- aria-hidden="true"
66
- >
67
- <div class="modal-dialog modal-lg" role="document">
68
- <div class="modal-content">
69
- <div class="modal-header">
70
- <h5
71
- class="modal-title"
72
- id="mapping_payload_modal_label_<%= mapping.id %>"
73
- >
74
- <%= Spree.t("admin.external_integrations.external_payload") %> - Mapping #<%= mapping.id %>
75
- </h5>
76
-
77
- <button
78
- type="button"
79
- class="close"
80
- data-dismiss="modal"
81
- aria-label="Close"
82
- >
83
- <span aria-hidden="true">&times;</span>
84
- </button>
85
- </div>
86
-
87
- <div class="modal-body">
88
- <pre
89
- class="small mb-0 p-2 bg-light border rounded"
90
- style="max-height: 500px; overflow-y: auto;"
91
- ><code><%= JSON.pretty_generate(mapping.external_payload) %></code></pre>
92
- </div>
93
-
94
- <div class="modal-footer">
95
- <button
96
- type="button"
97
- class="btn btn-secondary"
98
- data-dismiss="modal"
99
- >
100
- <%= Spree.t(:close) %>
101
- </button>
102
- </div>
103
- </div>
104
- </div>
105
- </div>
106
- <% end %>
107
- <% end %>
@@ -1,33 +0,0 @@
1
- <% content_for :page_title do %>
2
- <%= link_to Spree.t('external_integrations'), spree.admin_integrations_url %> / <%= @integration.name %>
3
- <% end %>
4
-
5
- <% content_for :page_tabs do %>
6
- <li class="nav-item">
7
- <%= link_to Spree.t(:edit),
8
- edit_admin_integration_path(@integration),
9
- class: "nav-link" %>
10
- </li>
11
-
12
- <li class="nav-item">
13
- <%= link_to Spree.t(:integration_sync_sessions),
14
- admin_integration_sessions_path(@integration),
15
- class: "nav-link" %>
16
- </li>
17
-
18
- <li class="nav-item">
19
- <%= link_to Spree.t(:integration_mappings),
20
- admin_integration_mappings_path(@integration),
21
- class: "nav-link active" %>
22
- </li>
23
- <% end %>
24
-
25
- <div data-hook="admin_integrations_mappings" class="card mb-3">
26
- <div class="card-header">
27
- <h5 class="card-title mb-0 h6"><%= Spree.t(:integration_mappings) %></h5>
28
- </div>
29
-
30
- <div class="card-body">
31
- <%= render partial: 'integration_mappings', locals: { integration: @integration } %>
32
- </div>
33
- </div>