Imports System
Imports System.Net
Imports System.Web.Services.Protocols
Imports OrderAbnReqSampleCode.OrderSubmissionWebService
Imports System.IO

' Class OrderAbnReqSample submits lab order (HL7 messages) to the MedPlus
' Hub platform.
'
' Upon its construction, this class will submit an order to the Orders Service

Public Class OrderAbnReqSample

    ' USERNAME designates the Hub user name used to
    ' authenticate to the Hub web service
    Private Const USERNAME As String = "ORDR_USR"

    ' PASSWORD designates the password associated with
    ' the Hub user when authenticating to the web service
    Private Const PASSWORD As String = "passw0rd"

    ' WEB_SERVICE_URL designates the end point used to
    ' connect to the Hub's Orders web service
    Private Const WEB_SERVICE_URL As String = "https://cert.hub.care360.com/orders/submission/service"

    ' SENDING_APPLICATION designates the application that 
    ' is sending the order message to Hub
    Private Const SENDING_APPLICATION As String = "HUBWS"

    ' SENDING_FACILITY designates the account number provided to you 
    ' by Quest for the businessunit you are ordering tests with
    Private Const SENDING_FACILITY As String = "2135800"

    ' RECEIVING_FACILITY designates the business unit 
    ' within Quest from which the labs are being ordered
    Private Const RECEIVING_FACILITY As String = "HOU"

    ' The HL7 Order message template - The following "template" is used in
    ' constucting the Order.
    ' 
    ' 0 = sending application (field 3) 
    ' 1 = sending facility (field 4) represents the account with Quest Diagnostics 
    ' 2 = receiving facility (field 6) The Quest Business Unit for above account 
    ' 3 = date time (field 7) 
    ' 4 = message control id (field 10) Unique Number identifying this order message
    Private Shared ORDER_MESSAGE As String = "MSH|^~\&|{0}|{1}||{2}|{3:yyyyMMddHHmm}||ORM^O01|{4}|P|2.3" + Chr(13) + _
                                             "PID|1|11111|||TEST^WIFE||19451212|M|||||3102222222||||||123456789|" + Chr(13) + _
                                             "IN1|1||AUHSC|AETNA|123 ANYSTREET^2^CHICAGO^IL^60305|||A12345||||||||TEST^HUSBAND^|2||123 ANYSTREET^^CHICAGO^IL^60305|||||||||||||||||P123456R|||||||||||T|" + Chr(13) + _
                                             "GT1|1||TEST^HUSBAND^||123 ANYSTREET^^CHICAGO^IL^60305|3102222222||19451212|M|" + Chr(13) + _
                                             "ORC|NW|{4}||||||||||OTH030^MICHIGAN^JOHN^^^^^UPIN|" + Chr(13) + _
                                             "OBR|1|{4}||^^^6399^CBC|||20051223094800|||||||||OTH030^MICHIGAN^JOHN^^^^^UPIN|||||||||||1^^^^^R|" + Chr(13) + _
                                             "DG1|1|ICD|0039|SALMONELLA INFECTION NOS|" + Chr(13) + _
                                             "OBX|1||^^^A123^SOME OBSERVATION||||||||P" + Chr(13) + _
                                             "ORC|NW|{4}||||||||||OTH030^MICHIGAN^JOHN^^^^^UPIN|" + Chr(13) + _
                                             "OBR|1|{4}||^^^10809^TISSUE|||20051223094800|||||||||OTH030^MICHIGAN^JOHN^^^^^UPIN|||||||||||1^^^^^R|" + Chr(13)

    Public Sub New()
        Try
            ' calling getOrderDocuments, sends the order to the hub
            Console.WriteLine("Calling getOrderDocuments...")
            sendOrder()

        Catch ex As Exception
            Console.WriteLine(ex.Message)

        End Try
    End Sub

    ' The sendOrder function handles the interactions with the Hub’s SOAP interface
    Public Sub sendOrder()
        Dim webService As OrderSubmissionService = Nothing

        Try
            '-------------------------------------------------------
            'STEP 1: CREATE WEB SERVICE REFS, SET PARAMS
            '-------------------------------------------------------
            webService = New OrderSubmissionService
        Catch except As Exception
            Console.Write(except.StackTrace)
            webService = Nothing
        End Try

        If Not (webService Is Nothing) Then
            Dim response As orderSupportServiceResponse = Nothing
            Dim orderRequest As orderSupportServiceRequest = Nothing

            Try
                '------------------------------------------------------------------
                'STEP 2: CREATE CREDENTIALS OBJECT CONTAINING USERNAME AND PASSWORD
                '------------------------------------------------------------------
                webService.Credentials = New NetworkCredential(USERNAME, PASSWORD)

                ' By default the client will attempt to call the web service without 
                ' sending the credentials. If the server returns a 401 HTTP response, 
                ' the client makes the call again with the credentials. If we set 
                ' PreAuthenticate to True, the client will include the credentials on 
                ' the initial call and eliminate this extra processing.
                '
                ' This should probably be set in the web service object's constructor,
                ' but has been included here to demonstrate.
                webService.PreAuthenticate = True

                If WEB_SERVICE_URL.Length > 0 Then
                    webService.Url = WEB_SERVICE_URL
                End If

                '------------------------------------------------------------------
                'STEP 3: call function that will create the WebService Order Object
                '------------------------------------------------------------------
                orderRequest = getWebServiceOrderDocumentsRequest()

                '--------------------------------------------------------------
                'STEP 4: call WebService function that submits order to the Hub
                '--------------------------------------------------------------
                response = webService.getOrderDocuments(orderRequest)

            Catch soapEx As SoapException
                Dim exceptionMessage As String = soapEx.Detail.InnerText.Replace("" & _
                Microsoft.VisualBasic.Chr(10) & "", "" & Microsoft.VisualBasic.Chr(13) & "" & _
                Microsoft.VisualBasic.Chr(10) & "")
                Console.Write(exceptionMessage)
            End Try

            If Not (response Is Nothing) Then
                '------------------------------------------------
                'STEP 5: Examine response coming back for the Hub
                '------------------------------------------------
                Console.WriteLine("Status: <{0}>.", response.status)
                Console.WriteLine("Transaction Id: <{0}>.", response.orderTransactionUid)
                Console.WriteLine("Message Control Id: <{0}>.", response.messageControlId)
                Console.WriteLine("Response Message: <{0}>.", response.responseMsg)
                If (Not response.orderSupportDocuments Is Nothing) And response.orderSupportDocuments.Length > 0 Then

                    Console.WriteLine("Document Type: " + response.orderSupportDocuments(0).documentType)
                    Console.WriteLine("Document Status: " + response.orderSupportDocuments(0).requestStatus)
                    Console.WriteLine("Document Message: " + response.orderSupportDocuments(0).responseMessage)
                    Console.WriteLine(vbCrLf + "HL7 Order ACK: " + vbCrLf + Replace(System.Text.Encoding.Default.GetString(response.hl7OrderAck), vbCr, vbCrLf) + vbCrLf)

                    If (Not response.orderSupportDocuments(0).documentData Is Nothing) Then
                        DisplayPDF(response.orderSupportDocuments(0).documentData)
                    End If

                End If

                If Not (response.validationErrors Is Nothing) Then
                    Dim valErr As String
                    For Each valErr In response.validationErrors
                        Console.WriteLine("Validation Error: <{0}>.", valErr)
                    Next
                End If
            Else
                Console.WriteLine("Failed to properly call submitOrder WebService method.")
            End If
        End If
    End Sub

    ' the getWebServiceOrderDocumentsRequest function creates a proper Order object that will be submitted
    ' to the Hub
    Private Function getWebServiceOrderDocumentsRequest() As orderSupportServiceRequest
        Dim retval As New orderSupportServiceRequest
        Dim orderMessage As String = Nothing
        Dim orderByteArray As Byte()

        ' Create Order Mesage by passing in facility information
        orderMessage = buildOrderMessage(SENDING_APPLICATION, SENDING_FACILITY, RECEIVING_FACILITY)

        ' Convert String to a Byte array and return in an Order object
        orderByteArray = System.Text.Encoding.ASCII.GetBytes(orderMessage)
        retval.hl7Order = orderByteArray

        ' Request ABN and REQ for order
        Dim supportRequests(2) As String
        supportRequests.SetValue("ABN", 0)
        supportRequests.SetValue("REQ", 1)
        supportRequests.SetValue("AOE", 2)
        retval.orderSupportRequests = supportRequests

        Return retval
    End Function

    'the buildOrderMessage function replaces values in the ORDER_MESSAGE template to create
    'a valid HL7 Order message
    Private Function buildOrderMessage(ByVal sendingApplication As String, _
                                       ByVal sendingFacility As String, _
                                       ByVal receivingFacility As String) As String
        ' 'now' is used for 2 purposes here
        ' 1 to specify the time that the message was created
        ' 2 to create a unique message control ID and order number
        Dim now As System.DateTime = System.DateTime.Now
        ' parameters for replacement in the template
        Dim msgParams(5) As Object

        msgParams(0) = sendingApplication
        msgParams(1) = sendingFacility
        msgParams(2) = receivingFacility
        msgParams(3) = now
        msgParams(4) = now.Ticks
        Return String.Format(ORDER_MESSAGE, msgParams)
    End Function

    Private Sub DisplayPDF(ByVal pdfBytes As Byte())
        Try
            Dim sFileName As String = "tmp.PDF"
            Dim fs As New FileStream(sFileName, FileMode.OpenOrCreate)
            Dim bw As New BinaryWriter(fs)

            bw.Write(pdfBytes)
            bw.Close()
            fs.Close()

            Process.Start("tmp.PDF")
        Catch ex As Exception
            MsgBox("Error displaying pdf:" + vbNewLine + ex.Message, MsgBoxStyle.OkOnly, "ABN/REQ Client")

        End Try
    End Sub

End Class
