Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

Home

Guy Feigin

Welcome to your wiki!

This is the default page, edit it as you see fit. To add a new page simply reference it within brackets, e.g.: [SamplePage].

The wiki uses Markdown syntax.

Project Admins:


  • Guy Feigin
    Guy Feigin
    2013-03-05

    This project aims to enable developer of mumps to use c sharp as their GUI for their client. I've searched a lot for a way to develop in modern GUI IDE's and save the data at the MUMPS database but couldn't find something that works, so i tried this approach.
    I've hardly wrote any code myself, but rather used solutions other have made.
    for the MUMPS i used a openvista server.
    and for the client i used openvista cis. so, basically it's a Medsphere solutin.
    explanation here are for setting up the system, writing procedures at the server side and caliing them and returning data from them

    check out the wiki about changes to the broker !

     
    Last edit: Guy Feigin 2013-03-19
  • Guy Feigin
    Guy Feigin
    2013-03-05

    client project files installation :
    in oreder to develop the client side please download the sample project from here:
    https://sourceforge.net/projects/csharptomumps/files/latest/download
    unzip the files and open the project in visual studio ( i use visual studio 2010 express which is free )

     
    Last edit: Guy Feigin 2013-03-13
  • Guy Feigin
    Guy Feigin
    2013-03-05

    checking the installation :
    run the openvista appliance.
    open up a terminal window.
    type at the prompt :
    demo@ubuntu:~$ ifconfig
    see which ip address the appliance got.look for inet addr. i got ip 192.168.1.80 but it changes every time you start the virtual machine.
    now run the c sharp project (cSharpToMumps). at the menu open the ip form and enter the ip 192.168.1.80. press o.k. now open the menu that is left to the ip.
    it's in hebrew, i will change that to english or u can.

    (this is basically Sam Habiel code : https://groups.google.com/group/hardhats/tree/browse_frm/month/2010-04/c643e4ff131f0d49?rnum=161&_done=%2Fgroup%2Fhardhats%2Fbrowse_frm%2Fmonth%2F2010-04%3F)

    insert a breakpoint at this location :
    private void connect(string serverIp, int serverPort)
    {
    try
    {

                serverIp = ipString;
                //serverIp : "192.168.32.134", serverPort : 9201
                // Connect 
                Mdc = new DataConnection("RPCTest1a",
                        serverIp, serverPort, true);
    
                Console.WriteLine("Connected!");
                // Enter Access and Verify Codes
    

    and now step over the lines by entering f10 and see if you connect to the server.
    if you examine the res variable you should see that it's value is like that :
    42
    0
    0

    0
    0

    Good morning USER,PHYSICIAN
    You last signed on today at 05:45

     
    Last edit: Guy Feigin 2013-03-05
  • Guy Feigin
    Guy Feigin
    2013-03-11

    O.k. if you got so far the things are good. we were able to establish a communication between our client project to the openvista (mumps) server.
    Now we would like to create routines at the mumps that will do something at the mumps server. those routines will be able to get data from the c sharp, use the data on the mumps routine, do something (usually get or set to the database) and return data to the c sharp.
    look at this lines of code at the csharp project :
    try
    {
    DConnection.DConnection dc = DConnection.DConnection.GetInstance();

                string[] args = { Convert.ToString(fromDate), Convert.ToString(toDate) };
                string context = "ACRIV";
                string res = dc.Mdc.CallRPC("XWB CREATE CONTEXT",
                    RpcFormatter.FormatArgs(false, Cypher.Encrypt(context)));
                res = dc.Mdc.CallRPC("ACRIV GETLIST",
                    RpcFormatter.FormatArgs(true, args));
                strs = Regex.Split(res, "\r\n");
    
                return strs;
            }
    

    you have to create a context. the bane of the context here is ACRIV.
    but you have first create this context at the openvista server. don't worry you will have to do it only once. i'm hoping that one of the vista guys will tell me how to by pass all of these security, but for now on go to the vista server appliance, open a terminal, type :
    demo@ubuntu:~$ openvista open

    OPEN>
    now u have a MUMPS prompt.
    i will explain based on this article :
    https://medsphere.org/docs/DOC-1397
    https://medsphere.org/message/4260#4260

     
    Last edit: Guy Feigin 2013-03-12
  • Guy Feigin
    Guy Feigin
    2013-03-12

    This document is based on :
    https://medsphere.org/docs/DOC-1397

    and

    http://medsphere.org/message/4126

    and also on http://www.va.gov/vdl/documents/Infrastructure/Remote_Proc_Call_Broker_(RPC)/xwb1_1p47getting_started.pdf

    and on Sam Habiels code

    OPEN>D P^DI

    MSC FileMan 22.1036

    Select OPTION: MAN,SYS ??

    Select OPTION: 1 ENTER OR EDIT FILE ENTRIES

    Input to what File: OPTION// (9685 entries)
    EDIT WHICH FIELD: ALL//

    Select OPTION NAME: ACRIV
    Located in the A (Local) namespace.
    Are you adding 'ACRIV' as a new OPTION (the 9686TH)? No// Y (Yes)
    OPTION MENU TEXT: ACRIV
    MENU TEXT: ACRIV//
    Select TRANSLATION:
    Select FOREIGN DESCRIPTION LANGUAGE:
    OUT OF ORDER MESSAGE:
    LOCK:
    REVERSE/NEGATIVE LOCK:
    DESCRIPTION:
    THERE ARE NO LINES!
    Edit? NO//
    CREATOR: MANAGER,SYSTEM//
    HELP FRAME:
    PRIORITY:
    PROHIBITED TIMES:
    Select TIMES PROHIBITED:
    Select TIME PERIOD:
    RESTRICT DEVICES?:
    Select PERMITTED DEVICE:
    TYPE: ??
    Choose from:
    A action
    E edit
    I inquire
    M menu
    P print
    R run routine
    O protocol
    Q protocol menu
    X extended action
    S server
    L limited
    C ScreenMan
    W Window
    Z Window Suite
    B Broker (Client/Server)
    TYPE: B Broker (Client/Server)
    Select ITEM:
    Short Menu Text:
    DISPLAY OPTION?:
    PACKAGE:
    DELEGABLE:
    EXIT ACTION:
    ENTRY ACTION:
    XQUIT MESSAGE:
    THERE ARE NO LINES!
    Edit? NO//
    XQUIT EXECUTABLE:
    WINDOW:
    ROUTINE:
    HEADER:
    DIC {DIC}:
    DIC(0):
    DIC(A):
    DIC(B):
    DIC(S):
    DIC(W):
    D.:
    DIC(DR):
    DR{DDS}:
    DDSFILE:
    DDSFILE(1):
    DDSPAGE:
    DDSPARM:
    DIE:
    DR {DIE}:
    DR():
    NO UP-ARROW:
    DIE(W):
    DIC {DIP}:
    PG:
    L.:
    FLDS:
    BY:
    FR:
    TO:
    DHD:
    DCOPIES:
    DIS(0):
    DIS(1):
    DIS(2):
    DIS(3):
    IOP:
    DHIT:
    DIOBEG:
    DIOEND:
    DISUPNO:
    DIPCRIT:
    DIASKHD:
    DISTEMP:
    DIC {DIQ}:
    DR {DIQ}:
    DIQ(0):
    SUPRESS DEVICE PROMPT:
    ORDER PRINT ACTION:
    ORDER CANCEL ACTION:
    ORDER PURGE ACTION:
    INDEPENDENTLY INVOCABLE:
    QUEUED TO RUN AT WHAT TIME:
    DEVICE FOR QUEUED JOB OUTPUT:
    RESCHEDULING FREQUENCY:
    *QUEUED TO RUN ON VOLUME SET:
    SCHEDULING RECOMMENDED:
    KEEP FROM DELETING:
    SERVER BULLETIN:
    SERVER ACTION:
    SERVER MAIL GROUP:
    SERVER AUDIT:
    SUPRESS BULLETIN:
    SERVER REPLY:
    SAVE REQUEST:
    SERVER DEVICE:
    ZTSK RETENTION DAYS:
    ICON:
    TITLE:
    Select RPC: ??
    You may enter a new RPC, if you wish
    This subfile is used to register the Remote Procedures registered
    to a particular Broker-type option. It is a pointer to the
    Remote Procedure File.

    Choose from:
    ACKQAUD1
    ACKQAUD2
    ACKQAUD4
    ACKQROES
    ACKQROESD
    ANRV CREATE OUTCOME
    ANRV FULLSSN
    ANRV GET OUTCOME TEXT
    ANRV GET PT OUTCOMES
    ANRV GET PTALL
    ANRV GET PTLAST5
    ANRV GUI PARAMETER
    ANRV OUTCOME SECTION TEXT
    ANRV PTINFO CORE
    ANRV SET RECORD STATUS
    ANRV TANRVMESSAGE
    ANRV TANRVPATIENT
    ANRV TANRVUSER
    DDR DELETE ENTRY
    DDR FILER to continue or '^' to exit:
    DDR FIND1
    DDR FINDER
    DDR GET DD HELP
    DDR GETS ENTRY DATA
    DDR KEY VALIDATOR
    DDR LISTER
    DDR LOCK/UNLOCK NODE
    DDR VALIDATOR
    DENTV ADA CODES QUICK
    DENTV ADD QL ENTRY
    DENTV DD FIELD UPDATE
    DENTV DD GET 228
    DENTV DD GET DATA
    DENTV DD GET/ADD RECORD
    DENTV DD SECURITY KEY
    DENTV DELETE HISTORY ENTRY
    DENTV DELETE QL ENTRY
    DENTV DELETE TRANSACTIONS
    DENTV DENT HISTORY ENC
    DENTV DENTAL CLASSIFICATIONS
    DENTV DENTAL PROVIDER
    to continue or '^' to exit: ^
    You may enter a new REMOTE PROCEDURE, if you wish
    NAME MUST BE 3-30 CHARACTERS, NOT NUMERIC OR STARTING WITH
    PUNCTUATION

    Select RPC: ACRIV
    Are you adding 'ACRIV' as a new REMOTE PROCEDURE (the 2240TH)? No// Y (Yes)
    Are you adding 'ACRIV' as a new RPC (the 1ST for this OPTION)? No// Y (Yes)
    RPCKEY:
    RULES:
    Select RPC:
    PRIMARY MENU:
    PROTECTED VARIABLES:
    *SPECIAL QUEUEING:
    DEFAULT WORKSPACE TYPE:
    MENU BEHAVIOR:
    PACKAGE:
    ACTION PANEL:

    Select OPTION NAME:

    Select OPTION:
    OPEN>

    after we have created the context we try to run the code and get this message from the RPC broker :

    public string[] acRivGetList(string fromDate,string toDate)
    {
    string[] strs = new string[20];
    string[] tmp = new string[3];

            try
            {
                DConnection.DConnection dc = DConnection.DConnection.GetInstance();
    
                string[] args = { Convert.ToString(fromDate), Convert.ToString(toDate) };
                string context = "ACRIV";
    

    here we have error : string res = dc.Mdc.CallRPC("XWB CREATE CONTEXT",
    RpcFormatter.FormatArgs(false, Cypher.Encrypt(context)));
    res = dc.Mdc.CallRPC("ACRIV GETLIST",
    RpcFormatter.FormatArgs(true, args));
    strs = Regex.Split(res, "\r\n");

                return strs;
            }
            catch (Exception e)
            {
                //Console.WriteLine(e.Message);
                return strs;
            }
        }
    

    we catch the exception and get this error :
    [Medsphere.OpenVista.Remoting.RpcSecurityException] = {"User USER,PHYSICIAN does not have access to option ACRIV"}

    It seems that we have to add this option, ACRIV, to the user USER,PHYSICIAN.
    How do we do that ?

    https://medsphere.org/docs/DOC-1397

    OPEN>D P^DI

    MSC FileMan 22.1030

    Identity = MAN,SYS  MANAGER,SYSTEM     pb          SYSTEM MANAGER

    Select OPTION: 1 ENTER OR EDIT FILE ENTRIES

    Input to what File: NEW PERSON//NEW PERSON          (56 entries)
    EDIT WHICH FIELD: ALL// 203  SECONDARY MENU OPTIONS  (multiple)
       EDIT WHICH SECONDARY MENU OPTIONS SUB-FIELD: ALL// .01  SECONDARY MENU OPTION
    S
       THEN EDIT SECONDARY MENU OPTIONS SUB-FIELD:
    THEN EDIT FIELD:

    Select NEW PERSON NAME: USER,DASHBOARD       DBU
    Select SECONDARY MENU OPTIONS: MSC PATIENT DASHBOARD       MSC PATIENT DASHBOARD
      Are you adding 'MSC PATIENT DASHBOARD' as
        a new SECONDARY MENU OPTIONS (the 1ST for this NEW PERSON)? No// Y  (Yes)
    Select SECONDARY MENU OPTIONS:

    Select NEW PERSON NAME:

    Select OPTION:
    OPEN>halt
    OPEN>D P^DI

    MSC FileMan 22.1036

    Select OPTION: 1 ENTER OR EDIT FILE ENTRIES

    Input to what File: OPTION// NEW PERSON (56 entries)
    EDIT WHICH FIELD: ALL// 203 SECONDARY MENU OPTIONS (multiple)
    EDIT WHICH SECONDARY MENU OPTIONS SUB-FIELD: ALL// .01 SECONDARY MENU OPTION
    S
    THEN EDIT SECONDARY MENU OPTIONS SUB-FIELD:
    THEN EDIT FIELD:

    Select NEW PERSON NAME: USER,PHYSICIAN PU M.D.
    Select SECONDARY MENU OPTIONS: MSC RM PHARM CALCULATOR
    // ACRIV ACRIV
    Are you adding 'ACRIV' as a new SECONDARY MENU OPTIONS? No// Y (Yes)
    Select SECONDARY MENU OPTIONS:

    Select NEW PERSON NAME:

    Select OPTION:

    now that we have assigned ACRIV option to the user we get 1 in the res variable.

    string res = dc.Mdc.CallRPC("XWB CREATE CONTEXT",
    RpcFormatter.FormatArgs(false, Cypher.Encrypt(context)));

    in the next line, however, we have a problem.
    res = dc.Mdc.CallRPC("ACRIV GETLIST",
    RpcFormatter.FormatArgs(true, args));

    we get an exception :
    {"Remote Procedure 'ACRIV GETLIST' doesn't exist on the server."}

    this is because first, we didn't even wrote this procedure, and second, we didn't tell the vista where is the procedure and who can run it.

    1. Write the routine :
      open a text editor and paste this code to it :

    ACRIV ; AC - ACCOUNTING RIV- RIVHIT
    ; PROGRAM COPPIED FROM CRCUST
    Q
    ;
    ;
    BUILD1 ;לבנות יום על סמך אותו יום בשבוע שעבר
    S A="" F S A=$O(^ACRIV(20130222,A)) Q:A="" S B="" F S B=$O(^ACRIV(20130222,A,B)) Q:B="" S ^ACRIV(20130301,A,B)="__"
    Q
    ;
    GETLIST(RES,FDT,TDT) ;
    ;
    ;
    KILL ^TEMP($J,"ACRIVLIST")
    ;
    N D,LN,NAME,REC,FDTL,TDTL
    N CLINIQ,METAPEL,IND
    S LNUMREC="",LNUMREC=$G(NUMREC)
    ;SET THE TEMP FILE
    S D="",LN=""
    S FDTL=FDT-1
    S TDTL=TDT
    F S FDTL=$O(^ACRIV(FDTL)) Q:FDTL="" D
    . I FDTL]TDTL Q
    . S CLINIQ=""
    . F S CLINIQ=$O(^ACRIV(FDTL,CLINIQ)) Q:CLINIQ="" D
    . . S METAPEL=""
    . . F S METAPEL=$O(^ACRIV(FDTL,CLINIQ,METAPEL)) Q:METAPEL="" D
    . . . S REC=^ACRIV(FDTL,CLINIQ,METAPEL)
    . . . S LN=LN+1
    . . . S ^TEMP($J,"ACRIVLIST",LN)=FDTL_D_CLINIQ_D_METAPEL_D_REC
    ;READ THE TEMP FILE
    S LN=0 ;SAVE RES(0) FOR RESULT O.K
    S IND=""
    F S IND=$O(^TEMP($J,"ACRIVLIST",IND)) Q:IND="" D
    . S REC=^TEMP($J,"ACRIVLIST",IND)
    . ;--------------------
    . S LN=LN+1
    . S RES(LN)=REC
    ;----------------------
    S RES(0)=1 ;O.K
    Q
    ;SET ALL CUSTOMER RECORDS
    SETALL(RES,ARRAY) ;
    N DT,CLINIC,METAPEL,REC,D
    S D="
    "
    S CLINIC=$G(ARRAY("CLINIC"))
    S DT=$G(ARRAY("DT"))
    S METAPEL=$G(ARRAY("METAPEL"))
    ;
    if CLINIC="" S RES="-1""""CLINIC IS A MANDATORY PARAM" Q
    if DT="" S RES="-1"
    """DT IS A MANDATORY PARAM" Q
    if METAPEL="" S RES="-1""""METAPEL IS A MANDATORY PARAM" Q
    ;
    S $P(REC,D,1)=$G(ARRAY("LISTED"))
    S $P(REC,D,2)=$G(ARRAY("ARRIVED"))
    S $P(REC,D,3)=$G(ARRAY("REMARKS"))
    S $P(REC,D,4)=$G(ARRAY("NEW"))
    S $P(REC,D,5)=$G(ARRAY("RETURNING"))
    S $P(REC,D,6)=$G(ARRAY("CREDITMEDUVAH")) ; REPORTED BY METAPLIM
    S $P(REC,D,7)=$G(ARRAY("CREDITBAPHOAL")) ; REPORTED BY US
    ;
    S ^ACRIV(DT,CLINIC,METAPEL)=REC
    S RES=1 ;ALL IS O.K
    Q
    SETGR(RES,ARRAY) ;
    N DT,CLINIC,METAPEL,REC,D
    S D="
    "
    S CLINIC=$G(ARRAY("CLINIC"))
    S DT=$G(ARRAY("DT"))
    S METAPEL=$G(ARRAY("METAPEL"))
    ;
    if CLINIC="" S RES="-1""""CLINIC IS A MANDATORY PARAM" Q
    if DT="" S RES="-1"
    """DT IS A MANDATORY PARAM" Q
    if METAPEL="" S RES="-1"""_"METAPEL IS A MANDATORY PARAM" Q
    ;
    S REC=$G(^ACRIV(DT,CLINIC,METAPEL))
    ;
    S $P(REC,D,4)=$G(ARRAY("NEW"))
    S $P(REC,D,5)=$G(ARRAY("RETURNING"))
    S $P(REC,D,7)=$G(ARRAY("CREDITBAPHOAL")) ; REPORTED BY US
    ;
    S ^ACRIV(DT,CLINIC,METAPEL)=REC
    S RES=1 ;ALL IS O.K
    Q

    save the routine to :
    /opt/openvista/open/routines under the name ACRIV.m, as a text file

    compile it :

    OPEN>ZL "ACRIV"

    now when we run the code on this line
    res = dc.Mdc.CallRPC("ACRIV GETLIST",
    RpcFormatter.FormatArgs(true, args));
    we get
    [Medsphere.OpenVista.Remoting.RpcSecurityException] = {"Remote Procedure 'ACRIV GETLIST' doesn't exist on the server."}

    we need to tell the rpc broker that the routine exist
    http://www.va.gov/vdl/documents/Infrastructure/Remote_Proc_Call_Broker_(RPC)/xwb1_1p47getting_started.pdf

    add the rotuine to the vista/rpcroker :

    OPEN>D P^DI

    MSC FileMan 22.1036

    Select OPTION: 1 ENTER OR EDIT FILE ENTRIES

    Input to what File: NEW PERSON// 8994 REMOTE PROCEDURE
    (2240 entries)
    EDIT WHICH FIELD: ALL// .01 NAME
    THEN EDIT FIELD: .02 TAG
    THEN EDIT FIELD: .03 ROUTINE
    THEN EDIT FIELD: .08 WORD WRAP ON
    THEN EDIT FIELD: .04 RETURN VALUE TYPE
    THEN EDIT FIELD:
    STORE THESE FIELDS IN TEMPLATE:

    Select REMOTE PROCEDURE NAME: ACRIV GETLIST
    Are you adding 'ACRIV GETLIST' as a new REMOTE PROCEDURE (the 2241ST)? No// Y

    (Yes)
    TAG: GETLIST
    ROUTINE: ACRIV
    WORD WRAP ON: ??
    Affects GLOBAL ARRAY and WORD PROCESSING return value types only. If set
    to
    FALSE, all data values are returned in a single concatenated string in
    Results[0]. If set to TRUE, each array node on the M side is returned as
    a
    distinct array item in the Results property of the TRPCBroker.

        If you're returning some text to the client and you'd rather let the
        memo box of the client control the wrapping of lines, set WORD WRAP ON
        to FALSE.  On the other hand, if you want to preserve line breaks as the
    

    y
    exist on the server, set WORD WRAP ON to TRUE.

     Choose from: 
       0        FALSE
       1        TRUE
    

    WORD WRAP ON: 0 FALSE
    RETURN VALUE TYPE: ??
    This field tells RPC Broker how to process the resulting data from the c
    all.

        SINGLE VALUE: Broker will return the value of the return parameter (firs
    

    t
    parameter in the formal list). For example,
    TAG(RESULT) ;
    S RESULT="DOE, JOHN"
    Q

        ARRAY: Using $ORDER Broker will traverse the return parameter (first
           parameter in the formal list), returning all elements of the array.
           For example,
               TAG(RESULT)     ;
                       S RESULT(1)="ONE"
                       S RESULT(2)="TWO"
                       Q
    
        WORD PROCESSING: This type is treated exactly the same way as the ARRAY,
           with one exception that the WORD WRAP ON field is used to
           control whether each line returned is terminated with CR + LF charact
    

    ers.
    See WORD WRAP ON field description for more information.

        GLOBAL ARRAY: Return value parameter should be set to a closed global
           reference in ^TMP. The global's data nodes will be traversed using
           $QUERY, and all data values on global nodes descendant from the globa
    

    l
    reference are returned. This type is especially useful for returning
    data
    from VA FileMan word processing fields, where each line is on a
    0-subscripted node.

           Important: The global reference you pass is killed by the Broker at t
    

    he
    end of RPC Execution as part of RPC cleanup. Do not pass a
    global reference that is not in ^TMP or that should not be
    killed.

           This type is useful for returning large amounts of data to the client
    

    ,
    where using the ARRAY type can exceed the symbol table limit and cras
    h
    your RPC.
    to continue or '^' to exit:
    For example, to return sign-on introductory text you could do this,
    TAG(RESULT) ;
    M RESULT=^XTV(8989.3,1,"INTRO")
    K RESULT(0) ;this node is not needed
    Q

        GLOBAL INSTANCE: Using this type Broker will return the value of a globa
    

    l
    node. For example the following code will return the whole 0th node
    from the NEW PERSON file for the current user.
    TAG(RESULT) ;
    S RESULT=$NA(^VA(200,DUZ,0))
    Q

     Choose from: 
       1        SINGLE VALUE
       2        ARRAY
       3        WORD PROCESSING
       4        GLOBAL ARRAY
       5        GLOBAL INSTANCE
    

    RETURN VALUE TYPE: 2 ARRAY

    Select REMOTE PROCEDURE NAME:

    Select OPTION:
    OPEN>%GTM-I-CTRLC, CTRL_C encountered

    OPEN>

    now run :
    and again what you get is quite annoying :
    e = {"The remote procedure ACRIV GETLIST is not registered to the option ACRIV."}

    we will add it :

    OPEN>D P^DI

    MSC FileMan 22.1036

    Select OPTION: 1 ENTER OR EDIT FILE ENTRIES

    Input to what File: REMOTE PROCEDURE// 19 OPTION (9686 entries)
    EDIT WHICH FIELD: ALL// .01 NAME
    THEN EDIT FIELD: RPC (multiple)
    EDIT WHICH RPC SUB-FIELD: ALL// .01 RPC
    THEN EDIT RPC SUB-FIELD:
    THEN EDIT FIELD:

    Select OPTION NAME: ACRIV ACRIV
    NAME: ACRIV//

    Select RPC: ACRIV GETLIST
    Are you adding 'ACRIV GETLIST' as a new RPC (the 2ND for this OPTION)? No// Y

    (Yes)
    Select RPC:

    Select OPTION NAME:

    Select OPTION:
    OPEN>

    and this time, walla !!! it's working

    if you think it's a lot of work just to write some procedures, you may be right
    but on the other hand you got a fully working robust mumps and c sharp framework

    I think security checks and routine registration can be bypassed somehow