Class: SpreeCmCommissioner::Integrations::StadiumXV1::Inventory::UnstockInventory

Inherits:
Object
  • Object
show all
Includes:
Spree::ServiceModule::Base
Defined in:
app/services/spree_cm_commissioner/integrations/stadium_x_v1/inventory/unstock_inventory.rb

Instance Method Summary collapse

Instance Method Details

#call(integration:, order:, line_items:) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/inventory/unstock_inventory.rb', line 6

def call(integration:, order:, line_items:)
  ApplicationRecord.transaction do
    line_items.each do |line_item|
      raise SpreeCmCommissioner::Integrations::SyncError, 'Invalid guests' if line_item.guests.size != line_item.quantity

      sync_line_item!(integration, order, line_item)
    end

    success(order: order, line_items: line_items)
  end
rescue SpreeCmCommissioner::Integrations::SyncError,
       SpreeCmCommissioner::Integrations::ExternalClientError => e
  failure(nil, e.message)
end

#group_ticket_qr_data(tickets) ⇒ Object



76
77
78
79
80
81
82
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/inventory/unstock_inventory.rb', line 76

def group_ticket_qr_data(tickets)
  {
    match_id: tickets.first.match_id,
    ticket_ids: tickets.map(&:_id).sort,
    is_online: true
  }.to_json
end

#sync_guests!(guests, tickets, integration) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/inventory/unstock_inventory.rb', line 61

def sync_guests!(guests, tickets, integration)
  guests.each_with_index do |guest, index|
    ticket = tickets[index]
    next if ticket.blank?

    guest_mapping = guest.integration_mappings.find_or_initialize_by(
      external_id: ticket._id,
      integration: integration
    )

    guest_mapping.external_qr_data = group_ticket_qr_data([ticket])
    guest_mapping.mark_as_active!(external_payload: ticket.to_h)
  end
end

#sync_line_item!(integration, order, line_item) ⇒ Object

Raises:



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/inventory/unstock_inventory.rb', line 21

def sync_line_item!(integration, order, line_item)
  zone_mapping = line_item.product.integration_mappings.find_by(integration_id: integration.id)
  raise SpreeCmCommissioner::Integrations::SyncError, 'Integration mapping not found for product' if zone_mapping.nil?

  external_zone_id = zone_mapping.external_id
  raise SpreeCmCommissioner::Integrations::SyncError, 'zone_id is required' if external_zone_id.blank?

  external_match_id = zone_mapping.external_payload&.dig('match_id')
  raise SpreeCmCommissioner::Integrations::SyncError, 'match_id is required' if external_match_id.blank?

  external_club_id = zone_mapping.external_payload&.dig('club_id')
  raise SpreeCmCommissioner::Integrations::SyncError, 'club_id is required' if external_club_id.blank?

  tickets = integration.client.create_tickets!(
    match_id: external_match_id,
    user_id: order.number,
    club_id: external_club_id,
    zone_id: external_zone_id,
    quantity: line_item.quantity
  )

  # External system did not create the correct number of tickets, we cannot proceed as it would lead to data inconsistency between systems.
  # We raise an error to rollback the transaction & we can manually investigate the issue.
  if tickets.size != line_item.quantity
    raise SpreeCmCommissioner::Integrations::SyncError,
          "Created tickets count (#{tickets.size}) does not match line item quantity (#{line_item.quantity})"
  end

  # Zipped to `tickets` positionally in sync_guests! — without an explicit order, Postgres
  # doesn't guarantee row order, so guest/ticket pairing could flip between runs.
  sync_guests!(line_item.guests.order(:id), tickets, integration)

  line_item_mapping = line_item.integration_mappings.find_or_initialize_by(
    integration: integration,
    external_id: tickets.map(&:_id).sort.join(',')
  )
  line_item_mapping.external_qr_data = group_ticket_qr_data(tickets)
  line_item_mapping.mark_as_active!(external_payload: {})
end