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_ordersObject



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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'app/controllers/api/v1/edi_messages_controller.rb', line 35

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

#testObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/controllers/api/v1/edi_messages_controller.rb', line 12

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_ordersObject



27
28
29
30
31
32
33
# File 'app/controllers/api/v1/edi_messages_controller.rb', line 27

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