Sunday, September 11, 2011

vistarpc4r Tutorial 2: Users, Locations, Patients, Dates

This second tutorial continues where we left off in tutorial #1, and assumes you have an OpenVistA system setup on Ubuntu.  
Many of the VistA RPC calls you can make though vistarpc4r require either a patient, provider, location or date.  In some cases, all of them.  Most VistA flavors come with some sample patients, providers or locations, but if you are developing software to work with VistA, you probably need to create some of your own.  

However.....standard VistA does not include a RPC to create ANY of them.  There are a variety of reasons, many non-technical ones regarding politics surrounding Federal software development can be read at the Hardhats google group.  I prefer to think it is because the actual users of CPRS aren't the ones creating the patients, and user accounts, so no need, no build.  

But....I have at least one work around.

So first, users, or usually referred to as providers.

User creation
For user creation, it's terminal time(although I believe Astronaut has a user config tool)
I need super providers for my development sandbox.  By that I mean, they have the ability to do just about everything in the VistA GUI.  For me that means a provider that can sign orders containing narcotics.  
I prefer Fileman to create users so:

$ openvista open
OPEN> D P^DI               # start Fileman
Login as man,sys
Select Option 1:  Add/Edit Entries
Select the NEW PERSON file
Edit All Fields                   # which is painful, but you won't miss anything
Select NEW PERSON NAME  - type in your new users name in LAST,FIRST format
You will then start going through fields.  ? and ?? give good answers as to what is expected.  
But some key fields:
ACCESS:  basically your login name
VERIFY:   a password
KEYS:  PROVIDER, ORES    # these are necessary to sign orders
SECONDARY MENU OPTIONS:  OR CPRS GUI CHART
PRIMARY MENU OPTION:  RGWBMAIN
CPRS TAB: RPT
CPRS TAB: COR

AUTHORIZED TO WRITE MED ORDERS:  YES

DEA: 2 letters, followed by 7 numbers, but there is an algorithm
ELECTRONIC SIGNATURE CODE:  A string the user types in to verify its them.  like JSMITH

Once you create one, you can clone it!
Go into EVE, which is D ^ZU, instead of D P^DI
Select User management
Select Grant access by profile 
Use your existing user as a template, and create new users!
Don't forget to change for each user: Access, verifyDEA, Signature

Add Locations(no RPC for this either)
Adding a location is a similiar experience to adding your first user. In this case edit file 44, the location file. Fill out what makes sense. Again ? and ?? will show you fairly good help.

Add Patients
So I have a RPC for this, but I don't feel good about. VistA does not come with one out of the box, but the Astronaut folks have created one. For my purposes, I needed to be able to add a lot of patients in bulk(but very few providers and locations). So I jammed the Astronaut modification into my plain vanilla OpenVista.
KIDS is the name of VistA's patching capability. People can bundle up their code changes as KIDS builds and distribute them for people to patch their system. In this case, I grabbed the KIDS build out of the Astronaut source tree installed it.

Grab kids.ov.tar.gz from

From that archive, we need the 0.8-2/TMG1-1.0-2d.KIDS file. Make sure it is on the OpenVistA server.
From the archive, I followed the commands in the file 0.8-2/TMG1-1.0-2d.TOY.sh
First we load the new code into the instance:

$ openvista open
OPEN> S DUZ=1,DUZ(0)="@"
OPEN> D ^XPDIL
# enter the path and filename for the KIDS file
# answer YES
OPEN>  h  # to halt

Then we install the code so that it runs and is available
$ openvista open
OPEN> S DUZ=1,DUZ(0)="@"
OPEN> D ^XPDI
TMG1*1.0*2
NO
NO
OPEN> h

During this installation process, you WILL GET ERRORS.  Wierd, nasty looking errors.  That is the part I don't feel good about.  But the add patient RPC works!!!!  

To use:
broker.call_s("TMG ADD PATIENT", [ [ 
    ["\"COMBINED NAME\"", "Test,Patient"],
    ["\"DOB\"", "12/1/68"],
    ["\"SEX\"", "M"],
    ["\"SS_NUM\"", "000000000"]
    ]]
The RPC returns the DFN, or internal identifier(which is an integer), for this new patient. 

For bulk loading, our experience is that the RPC breaks after a number of consecutive calls.  It looks like a timing bug.  Surrounding the call with the usual BEGIN/RESCUE/END, and resetting the connection works. 

Fileman Dates
Lastly, most of the RPCs that require dates for their arguments need them in Fileman format. Fileman format means take your usual YYYYMMDD.HHMMSS format and subtract 17000000.  For example, 20110911.090123 would be entered as 3110911.090123

Well, that gives you some basic infrastructure.  Enjoy.
Up next will be reviewing some specific RPCs that give you lists of stuff.



3 comments:

Pete said...

I'm not that familiar with the TMG set of RCPs or how the arguments of TMG ADD PATIENT are expected, but it looks like it might expect one parameter with key/value pairs (on the MUMPS side, looking like a single variable with single string subscripts).

I would prefer a Hash literal syntax for the call you have there:

broker.call_s "TMG ADD PATIENT",
[{
"COMBINED NAME" => "Test,Patient",
"DOB" => "8/23/82"
}]

Thoughts?

Anonymous said...

I agree with you. When I originally designed it, that's how I had it. The problem I ran into was that in some situations it appeared that the order of key/value pairs in the M multiple seemed to matter, which I couldn't guarantee with a hash. Saving problems and vitals to VistA, for example, use a key/value pair that looks like:
["1", GMPFLD(.12)=\"A^A\""],
["2", "GMPFLD(.13)=\"3110521^\""],
where the keys must be sent over the wire in increasing numerical order. However, in hindsight, in that case, if it was a hash, I could convert it to an array of tuples and sort on the key.
The other potential issue is on word processing fields. These general consist of one entry in the multiple declaring that there are word processing entries, and how many there are, and then additional entries in the multiple for each row of word processing text. I suspected, but never confirmed, that VistA would not like getting WP rows before I told it how many to expect. The parsing of the multiple sent over the wire appears to be generally fragile and uniquely handled for each RPC.
I haven't done an exhaustive search of where multiples are passed into RPCs to know if there are other guaranteed ordering situations.

I'd like to make call_a and call_s work like select_tag in Rails, where you can pass it Arrays of strings, arrays of tuple, hashes, etc.. and it does sensible things with each structure.

Do you know much about whether the ordering of elements in multiples may be required in some situations?

Pete said...

Well, Hash is ordered in Ruby 1.9, so you can still support the hash syntax with the big fat warning that doing so *may* introduce bugs when run on Ruby 1.8.

I'm not familiar with the XWB logic that parses RPC input, unfortunately.