Class: Api::V1::EdiMessagesController

Inherits:
BaseController
  • Object
show all
Includes:
ActionController::HttpAuthentication::Basic::ControllerMethods
Defined in:
app/controllers/api/v1/edi_messages_controller.rb

Overview

Controller: edi messages.

Constant Summary collapse

API_ACCOUNT_LOGIN_WHITELIST =

Api account login whitelist.

['mft_gateway'].freeze

Instance Method Summary collapse

Methods inherited from BaseController

#catalog_for_request, #error!, #locale_for_request, #logger, #render_bad_request_response, #render_internal_server_error, #render_not_found_response, #render_result, #render_unprocessable_entity_response, #set_locale, #store_for_request, #underscore_params

Instance Method Details

#purchase_ordersvoid

This method returns an undefined value.

POST /api/v1/edi_messages/purchase_orders — receives a raw EDI 850/PO
order batch for partner, persists it as an EdiCommunicationLog, and
confirms durability before ACKing so the sender doesn't lose the delivery
on a silent commit failure.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'app/controllers/api/v1/edi_messages_controller.rb', line 49

def purchase_orders
  raw_body = request.raw_post
  logger.info "Api::V1::EdiMessagesController#purchase_orders, request.raw_post length: #{raw_body&.length}"
  partner = params[:partner]&.to_sym
  logger.info "Api::V1::EdiMessagesController#purchase_orders, partner: #{partner}"

  return render json: { status: "Could not find EDI partner '#{partner}'" }, status: :not_found unless Edi::BaseOrchestrator.partners.any? { |k, _v| k == partner }

  edi_log = EdiCommunicationLog.new(partner: partner,
                                    category: 'order_batch',
                                    data: JSON.parse(raw_body).to_json,
                                    data_type: 'json',
                                    transmit_datetime: Time.current)
  if @test
    logger.info 'Api::V1::EdiMessagesController#purchase_orders, test, setting to auto-archive.'
    edi_log.notes = 'Test order_batch from API endpoint, auto-archiving'
    edi_log.state = 'archived'
  end
  edi_log.save!

  # Confirm the PO is durably committed BEFORE we ACK 200 to MFT Gateway. A
  # silent fake-success commit (see Durability) would otherwise make MFT
  # believe the order was delivered and never retry, losing it with no trace.
  # On failure this raises into the rescue below → 500 → MFT re-delivers.
  Durability.confirm_persisted!(EdiCommunicationLog,
                                { id: edi_log.id, partner: partner, category: 'order_batch' },
                                context: { controller: 'edi_messages', action: 'purchase_orders' })

  logger.info "saved 850/PO/order batch to edi log #{edi_log.id}"
  render json: { status: 'OK', transation_id: edi_log.id, json: edi_log.data }, status: :ok
rescue JSON::ParserError, ActiveRecord::RecordInvalid => e
  logger.error "EDI partner #{partner} purchase_orders rejected: #{e.class}: #{e.message}"
  notify_edi_api_failure(partner: partner, error: e, raw_body: raw_body, context: "Invalid payload / validation failure (#{e.class})")
  unless performed?
    render json: {
      status: 'Could not parse or successfully process JSON payload.',
      message: e.message
    }, status: :bad_request
  end
rescue StandardError => e
  ErrorReporting.critical(e, { message: "EdiMessagesController.purchase_orders unhandled error", controller: 'edi_messages', action: 'purchase_orders' })
  notify_edi_api_failure(partner: partner, error: e, raw_body: raw_body, context: 'Unhandled exception in purchase_orders')
  render json: { status: 'Internal error', message: e.message }, status: :internal_server_error unless performed?
end

#testvoid

This method returns an undefined value.

GET/POST /api/v1/edi_messages/test — connectivity/auth check for a given
partner, without processing any payload.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'app/controllers/api/v1/edi_messages_controller.rb', line 16

def test
  partner = params[:partner]&.to_sym
  logger.debug "Api::V1::EdiMessagesController#test, partner: #{partner}"
  if partner && Edi::BaseOrchestrator.partners.any? { |k, _v| k == partner }
    render json: { status: 'OK' }, status: :ok
  elsif partner
    render json: { status: "Could not find EDI partner '#{partner}'" }, status: :not_found
  else
    render json: { status: 'Access Denied.' }, status: :forbidden
  end
rescue StandardError => e
  ErrorReporting.error(e, "EdiMessagesController.test error")
  render json: { status: 'Internal error', message: e.message }, status: :internal_server_error unless performed?
end

#test_purchase_ordersvoid

This method returns an undefined value.

POST /api/v1/edi_messages/test_purchase_orders — same path as
#purchase_orders, but auto-archives the log instead of processing it.



35
36
37
38
39
40
41
# File 'app/controllers/api/v1/edi_messages_controller.rb', line 35

def test_purchase_orders
  @test = true # just set this as a test so we can auto-archive and not process
  purchase_orders
rescue StandardError => e
  ErrorReporting.error(e, "EdiMessagesController.test_purchase_orders error")
  render json: { status: 'Internal error', message: e.message }, status: :internal_server_error unless performed?
end