Hi Ahmad,

Maybe something like this?

Method SetEncounter(line, ByRef newLine, ByRef remainder, pFileType, pLineNumber) As %Status {

Set tSC = $$$OK

Set tNewField = ""

For i=2:1:$LENGTH(line) {

    Set word = $PIECE(line, "|", i)

    If i=2 {Set newField = word}

    Else {Set newField = newField_"^"_word}

    If i>8 Quit // If you don;t care what happens with columns 9 and after

}

Set remainder = $PIECE(line, "|", 9, $LENGTH(line))

Set newLine = tNewField_"^"_remainder

Quit tSC

// Here we go through the line by examining each field of your column, starting with column 2. So we just build your output with each iteration. You probably have to save your original line and and grab the remainder from it to concatenate with new line

I would also add better JSON support with %JSON.Adapter (the lack of which currently causes a lot of struggle for us on the older version)

I am seeing this in EnsLib.HPPT.InboundAdapter:

/// Set this property from onInit() in your Service class to make the adapter parse form variables from the form body in case of a form POST
Property ParseBodyFormVars As %Boolean;

So you just need to implement the OnInit() method as described here:

https://cedocs.intersystems.com/latest/csp/docbook/Doc.View.cls?KEY=EHTT...

I realize that the docs provide very little... just looked through them myself. So I found more posts that you might find helpful:

https://community.intersystems.com/post/uploading-and-downloading-files-...

https://community.intersystems.com/post/restful-way-data-transfer

I think the first post may be all you need... just put the upload part into the OnProcessnput() of your custom business service. You can also see similar code in the 2nd article, when you scroll to where it talks about form data.

Good luck!

Is your use case such that someone is posting data to your Server? If you use Ensemble, you probably benefit by reading: https://cedocs.intersystems.com/latest/csp/docbook/Doc.View.cls?KEY=EHTTP_preface
 

If you use Cache Web Services and you are building a custom REST-based service, please read:  https://cedocs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GREST_services

Basically, it sounds like you need to build REST-based Web Service that can receive http requests with attachments.  I assume that you already have a commercial Web Server (like Apache) where you can authenticate requests to your system and set up SSL certification if needed.

Hi Victor,

I assume that you need Dynamic Objects in order to create some JSON Output (so you can call %ToJSON() on the object to create a JSON string). So in my opinion, the complexity of your JSON object will drive these decisions - for example, how deeply nested will your JSON need to be?

From some familiarity with TextReader, it records every XML Element into a Property. So in theory, each Property can have its corresponding Dynamic Object which will be a Name/Value pair: Name = Name of Property; Value = Value of Property (i,e. XML Text Node)

It is hard to say more without seeing your XML structure or your JSON Spec. You may find the following links helpful:

https://community.intersystems.com/post/convert-xml-json

https://community.intersystems.com/post/size-limitation-tojson-large-stream

https://community.intersystems.com/post/how-could-we-include-json-object...

Hi Virat,

If you are working in Cache, you can try to use Set tXMLList = $LISTFROMSTRING(a, "</RollNo>"). 

Then, iterate over the list:

while $LISTNEXT(tXMLList,ptr,value) {

    Set $P(value,">",*) = "***"

}

This pulls the last substring after ">" which would be your numerical value.

Hi Gevorg,

I had recently encountered a use case like yours where we needed to connect to an FTP server and retrieve files from it. We tried to used EnsLib.FTP.PassthroughService but found it impractical. The service performance was very slow and we would wait minute before the file was actually picked up. We ended up running a shell script that would connect to the FTP server, mget all of the files and copy them to a local directory where EnsLibFile.PassthroughService would take care of them.

I wonder whether you were able to resolve your problem with FTP?

Hi Bukhtiar,

You can validate against a defined HL7 Schema without any code changes. Each HL7 Business Service has a property Message Schema Category. It's a drop-down menu and you can pick any schema to validate against. For example, your message is 2.3.1 so you can pick "2.3.1" to validate against that schema. If message contains segments that are not part of the schema, or if segments are in wrong order you will messages displayed in Ensemble with captions such as "Unrecognized segment found in ...". It will display all "good" segments that it validated in blue and all "unrecognized" segments in black. If you know you will have segments that are not part of standard schemas, you can create custom schemas based on the standard ones.

Your custom validation code is probably going to live on a Business Process. I would create a business rule that would define your custom business process as a target so you can send your messages for validation there. You can also combine this with the Validation property on the RoutingEngine class... there is a whole list of options that are available to also validate the message on the Router.

Hi Yone,

It looks your Business Process does not do anything with the message. Can you activate tracing on it (to make sure that your OBX transform is working)? 

Also, looking at code in EnsLib.HL7.Service.Standard I am seeing that this type of Business Service would send the message to Business Process asynchronously in almost all cases:

If $Case(..AckMode,

"Never":1,

"Immed":1,

"Byte":1,

"Msh":'$IsObject(tMSH)||$Case(tMSH.GetValueAt(16),"AL":0,"SU":0,"ER":0,:1),:0)

; ApplicationAcknowledgmentType="Never"
   #; Send Async; no reply required
   $$$SyncCommitSet(tSyncCommit)
   For iTarget=1:1:$L(..TargetConfigNames, ",")

      Set tOneTarget=$ZStrip($P(..TargetConfigNames,",",iTarget),"<>W") Continue:""=tOneTarget
      $$$sysTRACE("Sending HL7 Message "_pDocIn_" / "_pDocIn.%Id()_" from "_pDocIn.Source_" to '"_tOneTarget_"'")
      Set tSC1=..SendRequestAsync(tOneTarget,pDocIn) Set:$$$ISERR(tSC1) tSC=$$$ADDSC(tSC,tSC1)
   }

  #; other code ...

}

Else {
    #; Send Synchronous; reply required - for Application ACK mode (either explicit or MSH-requested)
   If ""'=tReplyCode||..ImmediateByteAck {

  #; other code ...

}

You may need to route your transformed message forward to an EnsLib.HL7.Operation.TCPOperation, which can then throw the message to an IP address where the original message came from. Most HL7 Ensemble transactions are implemented this way. It is counterintuitive but HL7 Business Services and Business Operations are sort of one way - only forward (at least when we try to forward real data... Acknowledgements can be returned with the proper settings on the Business Service).

Hi Mark,

Try to add to your Else statement something that would check for the existence of a returned ResultSet as in

If '$IsObject (rs) (make it false or true depending on your logic)

Then if no result set it should error our without waiting if you do not direct a retry in ReplyCodeActions on the Operation.