Scott Roth · Feb 5, 2019 go to post

You can use split on ZC02, get the length, then for each number that it split you create a separate DFT message.

Scott Roth · Jan 10, 2019 go to post

I didn't originally write the code but it works. My guess is my teammate who wrote it was trying to compensate for partial values, as in decimals.

Scott Roth · Jan 10, 2019 go to post

Here is a method we built for our use.

ClassMethod IsNumeric(value As %String) As %Boolean
{
//Load value into local var tNumber
set tNumber = value
//Use $extract to get the FULL VALUE into an internal format for $isvalidnum
set tFullValue = $EXTRACT(tNumber,1,$length(tNumber))
//Use $isvalidnum to check if the full value is numeric (ex: 123456789 = true, 123456789x = false)
set tNumberIsValid = $ISVALIDNUM(tFullValue)
//At this point, we simply return tNumberIsValid (it will either be 1, true or 0, false)
quit tNumberIsValid
}
 

Scott Roth · Jan 4, 2019 go to post

It seems Node .js is not going to be a viable option. My systems folks said it was compliled with a different GCC than what we have loaded on our AIX Server. If we were to load Node.js it would mess up the rest of the scripting (PERL, Shell) we do on the server.

Javascript was just one idea, I bet there are many other types of code that can be used to adjust an image resolution. Is there anything that can be called from Atelier without having to install a bunch of software on the server?

Scott Roth · Jan 3, 2019 go to post

I guess I am not following. I have created class files in the past through Studio to call those globals I referenced before. I am not familiar with the CRUD method, but a simple SET ^PERSON(1) = "MIKE|MALE|Developer" should be able to set your global, and when you do a GET to pull the information out of the global you can use PIECE to split the string apart by the | . Someone out here in the development community might have a better answer for you.

Scott Roth · Jan 3, 2019 go to post

Others can correct me if I am wrong, but everything Intersystems is moving to under the IRIS name.  Think of IRIS as a container with everything running under it.  Health Information Exchange (HIE), Cache Object Script, Globals, Ensemble, and etc run under what they call IRIS.

Zen is Intersystems way of creating Web Pages that talk directly with Cache.

You can use and call globals from any one of the products that you might be using. Globals works across the board, and is just another way of storing the data. In your above example think of the Person global as a variable you can call and retrieve the data

I have a global called OSUWMCLDAP that has various properties I use in some of my class files. I call this global from my class file ie like the following...

Here is examples I use in my class files to retrieve the data from the global.

#define LDAPServer $Get(^OSUMCLDAP("Server"))

Or

$Get(^OSUMCLDAP("Domain"))

Scott Roth · Dec 26, 2018 go to post

I haven't really dove into Node,js, but I will look into it.

Thanks

Scott

Scott Roth · Dec 20, 2018 go to post

Here is the same code but from the Studio (class view)

<assign value='##class(%Stream.GlobalCharacter).%New()' property='tStream' action='set' />
<assign value='source.GetFieldStreamRaw(.tStream,"ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).AlternateText",.tRemainder)' property='tSC' action='set' />
<if condition='..Length($get(tSC))&gt;0' >
<true>
<assign value='"1"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:SetIDOBX}' action='set' />
<assign value='"ED"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ValueType}' action='set' />
<assign value='"7"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationIdentifier.Identifier}' action='set' />
<assign value='"URL"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationIdentifier.Text}' action='set' />
<assign value='"EXTLRR"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationIdentifier.NameofCodingSystem}' action='set' />
<assign value='"1"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationSubID}' action='set' />
<assign value='"PDF"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).Identifier}' action='set' />
<assign value='"TMSAUDIO"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).Text}' action='set' />
<assign value='"PDF"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).NameofCodingSystem}' action='set' />
<assign value='"Base64"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).AlternateIdentifier}' action='set' />
<assign value='target.StoreFieldStreamRaw(tStream,"ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).AlternateText", tRemainder)' property='tSC' action='set' />
<assign value='""' property='$P(tRemainder,"|",11)' action='set' />
</true>
</if>

Scott Roth · Dec 19, 2018 go to post

With the help from WRC we converted the OBX stream to a GlobalCharacter Stream. See below as an example.

Scott Roth · Dec 10, 2018 go to post

Without Proxy...

0 +«npiregistry.cms.hhs.gov:443

With Proxy

0 3Â %<WRITE>zSend+179^%Net.HttpRequest.1

Scott Roth · Dec 10, 2018 go to post

I think I am definately being blocked along the process somewhere. I tried the above commands as Sean mentioned with a proxy and without one, but I keep running into issues.

USER>set req=##class(%Net.HttpRequest).%New()
USER>set req.SSLConfiguration="npiregistry"
USER>set req.Server="npiregistry.cms.hhs.gov"
USER>set req.Https=1
USER>set req.Port=443
USER>set sc=req.Get("/api?city=baltimore&postal_code=212")
USER>write req.HttpResponse.Data.Read(300000)
WRITE req.HttpResponse.Data.Read(300000)
^
<INVALID OREF>

USER>set req=##class(%Net.HttpRequest).%New()
USER>set req.ProxyServer="10.127.20.41"
USER>set req.ProxyPort="8080"
USER>set req.SSLConfiguration="npiregistry"
USER>set req.Server="npiregistry.cms.hhs.gov"
USER>set req.Https=1
USER>set req.Port=443
USER>set sc=req.Get("/api?city=baltimore&postall_code=212")
USER>write req.HttpResponse.Data.Read(300000)
WRITE req.HttpResponse.Data.Read(300000)
^
<INVALID OREF>

Scott Roth · Dec 7, 2018 go to post

Does this only work on certain Ensemble versions? I tried it on 2015.2.2 and was getting SYNTAX errors.

Scott Roth · Dec 5, 2018 go to post

Yes I created a blank SSL/TLS confirguration called npireigstry just like you mentioned above.

I wrote out sc after executing the GET and got the following...

write sc0  [Š%<WRITE>zSend+199^%Net.HttpRequest.1 'USER #$^zSend+199^%Net.HttpRequest.1 +1 $^zGet+1^%Net.HttpRequest.1 +1X^@ +1$D^zExecute+15^%Studio.General.1 +1X^@ +1 D^runMtdLow+22^%SYS.BINDSRV +1 D^popFrame+199^%SYS.BINDSRV +1!D^ServerLoop+23^%SYS.BINDSRV +2!D^SuperConnect+34^%SYS.DBSRV +1"D^SuperServer+112^%SYS.SERVER +1

Any Idea on what this error could be?

Scott Roth · Dec 3, 2018 go to post

Sean,

I tried running through your example above. When I got to set results={} ,I got the following error. Does this mean I could not get a connection outside my firewall at the Hospital?

USER>set req=##class(%Net.HttpRequest).%New()
 USER>set req.SSLConfiguration="npiregistry"
 USER>set sc=req.Get("https://npiregistry.cms.hhs.gov/api?city=balimore&postal_code=212")
 USER>set results={}.%FromJSON(req.HttpResponse.Data)
 <THROW>%FromJSON+37^%Library.DynamicAbstractObject.1 *%Exception.General Premature end of data 12 Line 1 Offset 0
USER 2e1>write results.%Get("result_count")
 WRITE results.%Get("result_count")
^
<UNDEFINED>^%Library.DynamicAbstractObject.1 *results
USER 2e1>set results={}.%FromJSON(req.HttpResponse.Data)
 <THROW>%FromJSON+37^%Library.DynamicAbstractObject.1 *%Exception.General Premature end of data 12 Line 1 Offset 0

Thanks

Scott

Scott Roth · Nov 19, 2018 go to post

Yes I would think the easiest way would be to create a record mapper structure, then use the DTL to map your HL7 fields to where they need to be, then send it to a EnsLib.RecordMap.Operation.FileOperation.

Record Mapper

DTL

Scott Roth · Nov 18, 2018 go to post

Eduard, where can I see the code for ZSTART AND ZSTOP?

Thanks

Scott

Scott Roth · Nov 15, 2018 go to post

Yes the JDBC Gateways within the Production do stop and start when Cache' is going down and coming back up, but I am talking at the %SYS level,

Without the JDBC Gateway Server running a lot of the JDBC Gateway's (Services) start failing in the production which causes us issues.

ZSTART and ZSTOP are kind of vague, how does that fit into ccontrol start and ccontrol stop. Is there any setting where this can be set to automatic?

Scott

Scott Roth · Oct 12, 2018 go to post

The majority of my Ancillary billing files in HL7 are batch. In the structure I have just made FHS, BHS,FTS,FHS all optional. In my DTL, I am only processing those messages that truly begin with a MSH segment.

Scott Roth · Sep 24, 2018 go to post

In a lot of places I use...

ConvertDateTime (val,in,out,file)

 

..ConvertDateTime(source.{Z01(1):DateOfBirth},"%Y%m%d","%q(1)")

%q(1) is the format.

We had a consultant write this for us as well...

 

ClassMethod FormatStringToSQLDate(InDate As %String) As %String [ Final ]
{
If InDate=""
{
set OutDate="1900-01-01 00:00:00"
}
else
{
set DateLength=..Length(InDate)
if (DateLength > 7) && (DateLength < 15)
{
set YYYY=..SubString(InDate,1,4)
set mm=..SubString(InDate,5,6)
set dd=..SubString(InDate,7,8)
set OutDate=YYYY_"-"_mm_"-"_dd
if DateLength=8
{
set OutDate=OutDate_" 00:00:00"
}
if DateLength=10
{
set HH=..SubString(InDate,9,10)
set OutDate=OutDate_" "_HH_":00:00"
}
if DateLength=12
{
set HH=..SubString(InDate,9,10)
set MM=..SubString(InDate,11,12)
set OutDate=OutDate_" "_HH_":"_MM_":00"
}
if DateLength=14
{
set HH=..SubString(InDate,9,10)
set MM=..SubString(InDate,11,12)
set SS=..SubString(InDate,13,14)
set OutDate=OutDate_" "_HH_":"_MM_":"_SS
}
}
else
{
set OutDate="1900-01-01 00:00:00"
}
}
Quit OutDate
}
}
 

Scott Roth · Sep 18, 2018 go to post

We've have done something similar but wrote a function to do the looping... This example loops through a given segment and field and looks that value up against a lookup table. This could be modified for your use. This is the only way I know to do the looping within the BusinessRule.

ClassMethod GroupIDExists(pHL7Msg As EnsLib.HL7.Message, pSegment As %String, pField As %String, pLookupTable As %String) As %Boolean
{
            #dim tSeg as EnsLib.HL7.Segment
            
            set tSegCount = pHL7Msg.SegCountGet()
            set = 1
            Set tFound = 0
            //get new values
            set tval=""
            while ((<= tSegCount) && (tval="")) {
                         
                        set tSeg = pHL7Msg.GetSegmentAt(i)
                        if (tSeg.Name = pSegment) {
                                    set tID = tSeg.GetValueAt(pField)
                                    set tval= ..Lookup(pLookupTable, tID)
                                                            
                        }
                        set = + 1
            }
            if (tval '= "")
            {
                        1
            }
            quit 0
}

Scott Roth · Sep 13, 2018 go to post

I am not familiar with that function.

This is how I am looking up a repeatable segment against a lookup table.

ClassMethod GroupIDExists(pHL7Msg As EnsLib.HL7.Message, pSegment As %String, pField As %String, pLookupTable As %String) As %Boolean
{
            #dim tSeg as EnsLib.HL7.Segment
            
            set tSegCount = pHL7Msg.SegCountGet()
            set = 1
            Set tFound = 0
            //get new values
            set tval=""
            while ((<= tSegCount) && (tval="")) {
                         
                        set tSeg = pHL7Msg.GetSegmentAt(i)
                        if (tSeg.Name = pSegment) {
                                    set tID = tSeg.GetValueAt(pField)
                                    set tval= ..Lookup(pLookupTable, tID)
                                                            
                        }
                        set = + 1
            }
            if (tval '= "")
            {
                        1
            }
            quit 0
}

Not sure how you would do that with XECUTE

Scott Roth · Sep 13, 2018 go to post

This is not in a translation. We want to write a function to loop through a repeating segment and compare it to a string value within a Routing Rule. I've done this before as a lookup against a table but not compare strings before.

Scott Roth · Sep 13, 2018 go to post

Are you connecting from a Windows Client to a Windows LDAP server? Or is it an Unix Client to a Windows LDAP server? Its a matter of using Binds vs SimpleBinds. I am wondering if that is causing your error. I use Delegated Authentication through LDAP using a TLS certificate so my setup maybe more complicated than yours.

Scott Roth · Aug 30, 2018 go to post

Was this ever pushed forward as true development? I know you have been working on it sometime, and wanted to see if I could take a look at it for my organization.

Thanks

Scott

Scott Roth · Aug 16, 2018 go to post

I got jTDS working through using Squirrel SQL Client, I am just now trying to transpose that over to Ensemble to see if I can get it to work.

Scott Roth · Aug 15, 2018 go to post

Maybe I didn't describe this right. I am trying to go from No Authentication to a Windows Authentication account. Has anyone done this? if so can you share your part of your URL to see what I am possibly missing.

Thanks

Scott

Scott Roth · Jul 24, 2018 go to post

Yes I was. That would explain the syntax issue. I have verified that the SimpleBinds without StartTLSs works fine. I have added some additional print statements to see where the issue might lie. The code gets past the Init, and SetOption, but then dies on the StartTLSs.

LD=1
SetOption=Success
-11,ldap_StartTLSs(Certificate) - Connect error

I went ahead and opened a ticket up with WRC to see if they could help. Thanks everyone.

Scott Roth · Jul 23, 2018 go to post

I am still struggling to get this to work. If I go through %SYS and manually try to start a TLS connection in AIX to my LDAP server I am getting...

s Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSCACERTFILE,"/ensemble/TestClin/mgr/LDAPKeyStore/OSUWMC_CA.pem") - Error <SYNTAX>

Does the certificate need to be in a certain directory for this to work as the examples suggested " /usr/share/ssl/certs/...."?