Changeset 508 for ccr/trunk/p/C0CMED6.m


Ignore:
Timestamp:
May 21, 2009, 1:12:11 PM (15 years ago)
Author:
George Lilly
Message:

formatting for Version 1

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ccr/trunk/p/C0CMED6.m

    r424 r508  
    11C0CMED6 ; WV/CCDCCR/SMH - Meds from RPMS: Outpatient Meds;01/10/09
    2         ;;0.1;CCDCCR;;JUL 16,2008;
    3         ; Copyright 2008 WorldVistA.  Licensed under the terms of the GNU
    4         ; General Public License See attached copy of the License.
    5         ;
    6         ; This program is free software; you can redistribute it and/or modify
    7         ; it under the terms of the GNU General Public License as published by
    8         ; the Free Software Foundation; either version 2 of the License, or
    9         ; (at your option) any later version.
    10         ;
    11         ; This program is distributed in the hope that it will be useful,
    12         ; but WITHOUT ANY WARRANTY; without even the implied warranty of
    13         ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14         ; GNU General Public License for more details.
    15         ;
    16         ; You should have received a copy of the GNU General Public License along
    17         ; with this program; if not, write to the Free Software Foundation, Inc.,
    18         ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    19         ;
    20         W "NO ENTRY FROM TOP",!
    21         Q
    22         ;
     2 ;;1.0;C0C;;May 19, 2009;
     3 ; Copyright 2008 WorldVistA.  Licensed under the terms of the GNU
     4 ; General Public License See attached copy of the License.
     5 ;
     6 ; This program is free software; you can redistribute it and/or modify
     7 ; it under the terms of the GNU General Public License as published by
     8 ; the Free Software Foundation; either version 2 of the License, or
     9 ; (at your option) any later version.
     10 ;
     11 ; This program is distributed in the hope that it will be useful,
     12 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 ; GNU General Public License for more details.
     15 ;
     16 ; You should have received a copy of the GNU General Public License along
     17 ; with this program; if not, write to the Free Software Foundation, Inc.,
     18 ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     19 ;
     20 W "NO ENTRY FROM TOP",!
     21 Q
     22 ;
    2323EXTRACT(MINXML,DFN,OUTXML,FLAGS)         ; EXTRACT MEDICATIONS INTO PROVIDED XML TEMPLATE
    24         ;
    25         ; MINXML and OUTXML are passed by name so globals can be used
    26         ; MINXML will contain only the medications skeleton of the overall template
    27         ; FLAGS are: MEDALL(bool)^MEDLIMIT(int)^MEDACTIVE(bool)^MEDPENDING(bool)
    28         ; FLAGS are set-up in C0CMED.
    29         ;
    30         ; MEDS is return array from RPC.
    31         ; MAP is a mapping variable map (store result) for each med
    32         ; MED is holds each array element from MEDS(J), one medicine
    33         ; J is a counter.
    34         ;
    35         ; GETRXS^BEHORXFN(ARRAYNAME,DFN,DAYS) will be the the API used.
    36         ; This API has been developed by Medsphere for IHS for getting
    37         ; Medications from RPMS. It has most of what we need.
    38         ; API written by Doug Martin when he worked for Medsphere (thanks Doug!)
    39         ; -- ARRAYNAME is passed by name (required)
    40         ; -- DFN is passed by value (required)
    41         ; -- DAYS is passed by value (optional; if not passed defaults to 365)
    42         ;
    43         ; Return:
    44         ; ~Type^PharmID^Drug^InfRate^StopDt^RefRem^TotDose^UnitDose^OrderID
    45         ; ^Status^LastFill^Chronic^Issued^Rx #^Provider^
    46         ; Status Reason^DEA Handling
    47         ;
    48         N MEDS,MEDS1,MAP
    49         D GETRXS^BEHORXFN("MEDS1",DFN,$P($P(FLAGS,U,2),"-",2)) ; 2nd piece of FLAGS is # of days to retrieve, which comes in the form "T-360"
    50         N ALL S ALL=+FLAGS
    51         N ACTIVE S ACTIVE=$P(FLAGS,U,3)
    52         N PENDING S PENDING=$P(FLAGS,U,4)
    53         S @OUTXML@(0)=0  ;By default, no meds
    54         ; If MEDS1 is not defined, then no meds
    55         I '$D(MEDS1) QUIT
    56         I DEBUG ZWR MEDS1,MINXML
    57         N MEDCNT S MEDCNT=0 ; Med Count
    58         ; The next line is a super line. It goes through the array return
    59         ; and if the first characters are ~OP, it grabs the line.
    60         ; This means that line is for a dispensed Outpatient Med.
    61         ; That line has the metadata about the med that I need.
    62         ; The next lines, however many, are the med and the sig.
    63         ; I won't be using those because I have to get the sig parsed exactly.
    64         N J S J="" F  S J=$O(MEDS1(J)) Q:J=""  I $E(MEDS1(J),1,3)="~OP" S MEDCNT=MEDCNT+1 S MEDS(MEDCNT)=MEDS1(J)
    65         K MEDS1
    66         S MEDCNT="" ; Initialize for $Order
    67         F  S MEDCNT=$O(MEDS(MEDCNT)) Q:MEDCNT=""  D  ; for each medication in the list
    68         . I 'ALL,ACTIVE,$P(MEDS(MEDCNT),U,10)'="ACTIVE" QUIT
    69         . I 'ALL,PENDING,$P(MEDS(MEDCNT),U,10)'="PENDING" QUIT
    70         . I DEBUG W "MEDCNT IS ",MEDCNT,!
    71         . S MAP=$NA(^TMP("C0CCCR",$J,"MEDMAP",MEDCNT))
    72         . ; K @MAP DO NOT KILL HERE, WAS CLEARED IN C0CMED
    73         . I DEBUG W "MAP= ",MAP,!
    74         . S @MAP@("MEDOBJECTID")="MED"_MEDCNT ; MEDCNT FOR ID
    75         . S @MAP@("MEDISSUEDATETXT")="Issue Date"
    76         . S @MAP@("MEDISSUEDATE")=$$FMDTOUTC^C0CUTIL($P(MEDS(MEDCNT),U,13))
    77         . S @MAP@("MEDLASTFILLDATETXT")="Last Fill Date"
    78         . S @MAP@("MEDLASTFILLDATE")=$$FMDTOUTC^C0CUTIL($P(MEDS(MEDCNT),U,11))
    79         . S @MAP@("MEDRXNOTXT")="Prescription Number"
    80         . S @MAP@("MEDRXNO")=$P(MEDS(MEDCNT),U,14)
    81         . S @MAP@("MEDTYPETEXT")="Medication"
    82         . S @MAP@("MEDDETAILUNADORNED")=""  ; Leave blank, field has its uses
    83         . S @MAP@("MEDSTATUSTEXT")=$P(MEDS(MEDCNT),U,10)
    84         . ; Provider only provided in API as text, not DUZ.
    85         . ; We need to get DUZ from filman file 52 (Prescription)
    86         . ; Field 4; IEN is Piece 2 of Meds stripped of trailing characters.
    87         . ; Note that I will use RXIEN several times later
    88         . N RXIEN S RXIEN=+$P(MEDS(MEDCNT),U,2)
    89         . S @MAP@("MEDSOURCEACTORID")="ACTORPROVIDER_"_$$GET1^DIQ(52,RXIEN,4,"I")
    90         . S @MAP@("MEDPRODUCTNAMETEXT")=$P(MEDS(MEDCNT),U,3)
    91         . ; --- RxNorm Stuff
    92         . ; 176.001 is the file for Concepts; 176.003 is the file for
    93         . ; sources (i.e. for RxNorm Version)
    94         . ;
    95         . ; I use 176.001 for the Vista version of this routine (files 1-3)
    96         . ; Since IHS does not have VUID's, I will be getting RxNorm codes
    97         . ; using NDCs. My specially crafted index (sounds evil) named "NDC"
    98         . ; is in file 176.002. The file is called RxNorm NDC to VUID.
    99         . ; Except that I don't need the VUID, but it's there if I need it.
    100         . ;
    101         . ; We obviously need the NDC. That is easily obtained from the prescription.
    102         . ; Field 27 in file 52
    103         . N NDC S NDC=$$GET1^DIQ(52,RXIEN,27,"I")
    104         . ; I discovered that file 176.002 might give you two codes for the NDC
    105         . ; One for the Clinical Drug, and one for the ingredient.
    106         . ; So the plan is to get the two RxNorm codes, and then find from
    107         . ; file 176.001 which one is the Clinical Drug.
    108         . ; ... I refactored this into GETRXN
    109         . N RXNORM,SRCIEN,RXNNAME,RXNVER
    110         . I +NDC,$D(^C0CRXN) D  ; $Data is for Systems that don't have our RxNorm file yet.
    111         . . S RXNORM=$$GETRXN(NDC)
    112         . . S SRCIEN=$$FIND1^DIC(176.003,,,"RXNORM","B")
    113         . . S RXNNAME=$$GET1^DIQ(176.003,SRCIEN,6)
    114         . . S RXNVER=$$GET1^DIQ(176.003,SRCIEN,7)
    115         . ;
    116         . E  S (RXNORM,RXNNAME,RXNVER)=""
    117         . ; End if/else block
    118         . S @MAP@("MEDPRODUCTNAMECODEVALUE")=RXNORM
    119         . S @MAP@("MEDPRODUCTNAMECODINGINGSYSTEM")=RXNNAME
    120         . S @MAP@("MEDPRODUCTNAMECODEVERSION")=RXNVER
    121         . ; --- End RxNorm section
    122         . ;
    123         . ; Brand name is 52 field 6.5
    124         . S @MAP@("MEDBRANDNAMETEXT")=$$GET1^DIQ(52,RXIEN,6.5)
    125         . ;
    126         . ; Next I need Med Form (tab, cap etc), strength (250mg)
    127         . ; concentration for liquids (250mg/mL)
    128         . ; Since IHS does not have any of the new calls that
    129         . ; Vista has, I will be doing a crosswalk:
    130         . ; File 52, field 6 is Drug IEN in file 50
    131         . ; File 50, field 22 is VA Product IEN in file 50.68
    132         . ; In file 50.68, I will get the following:
    133         . ; -- 1: Dosage Form
    134         . ; -- 2: Strength
    135         . ; -- 3: Units
    136         . ; -- 8: Dispense Units
    137         . ; -- Conc is 2 concatenated with 3
    138         . ;
    139         . ; *** If Drug is not matched to NDF, then VA Product will be "" ***
    140         . ;
    141         . N MEDIEN S MEDIEN=$$GET1^DIQ(52,RXIEN,6,"I") ; Drug IEN in 50
    142         . N VAPROD S VAPROD=$$GET1^DIQ(50,MEDIEN,22,"I") ; VA Product in file 50.68
    143         . I +VAPROD D
    144         . . S @MAP@("MEDSTRENGTHVALUE")=$$GET1^DIQ(50.68,VAPROD,2)
    145         . . S @MAP@("MEDSTRENGTHUNIT")=$$GET1^DIQ(50.68,VAPROD,3)
    146         . . S @MAP@("MEDFORMTEXT")=$$GET1^DIQ(50.68,VAPROD,1)
    147         . . S @MAP@("MEDCONCVALUE")=@MAP@("MEDSTRENGTHVALUE")
    148         . . S @MAP@("MEDCONCUNIT")=@MAP@("MEDSTRENGTHUNIT")
    149         . E  D
    150         . . S @MAP@("MEDSTRENGTHVALUE")=""
    151         . . S @MAP@("MEDSTRENGTHUNIT")=""
    152         . . S @MAP@("MEDFORMTEXT")=""
    153         . . S @MAP@("MEDCONCVALUE")=""
    154         . . S @MAP@("MEDCONCUNIT")=""
    155         . ; End Strengh/Conc stuff
    156         . ;
    157         . ; Quantity is in the prescription, field 7
    158         . S @MAP@("MEDQUANTITYVALUE")=$$GET1^DIQ(52,RXIEN,7)
    159         . ; Dispense unit is in the drug file, field 14.5
    160         . S @MAP@("MEDQUANTITYUNIT")=$$GET1^DIQ(50,MEDIEN,14.5)
    161         . ;
    162         . ; --- START OF DIRECTIONS ---
    163         . ; Sig data not in any API :-(  Oh yes, you can get the whole thing, but...
    164         . ; we want the components.
    165         . ; It's in multiple 113 in the Prescription File (52)
    166         . ; #.01 DOSAGE ORDERED [1F]                    "20"
    167         . ; #1 DISPENSE UNITS PER DOSE [2N]     "1"
    168         . ; #2 UNITS [3P:50.607]                                "MG"
    169         . ; #3 NOUN [4F]                                                "TABLET"
    170         . ; #4 DURATION [5F]                                    "10D"
    171         . ; #5 CONJUNCTION [6S]                                 "AND"
    172         . ; #6 ROUTE [7P:51.2]                          "ORAL"
    173         . ; #7 SCHEDULE [8F]                                    "BID"
    174         . ; #8 VERB [9F]                                                "TAKE"
    175         . ;
    176         . ; Will use GETS^DIQ to get fields.
    177         . ; Data comes out like this:
    178         . ; SAMINS(52.0113,"1,23,",.01)=20
    179         . ; SAMINS(52.0113,"1,23,",1)=1
    180         . ; SAMINS(52.0113,"1,23,",2)="MG"
    181         . ; SAMINS(52.0113,"1,23,",3)="TABLET"
    182         . ; SAMINS(52.0113,"1,23,",4)="5D"
    183         . ; SAMINS(52.0113,"1,23,",5)="THEN"
    184         . ;
    185         . N RAWDATA
    186         . D GETS^DIQ(52,RXIEN,"113*",,"RAWDATA","DIERR")
    187         . D:$D(DIERR) ^%ZTER  ; Log if there's an error in retrieving sig field
    188         . ; none the less, continue; some parts are retrievable.
    189         . N FMSIG M FMSIG=RAWDATA(52.0113) ; Merge into subfile...
    190         . K RAWDATA
    191         . N FMSIGNUM S FMSIGNUM="" ; Sigline number in fileman.
    192         . ; FMSIGNUM gets outputted as "IEN,RXIEN,".
    193         . ; DIRCNT is the proper Sigline numer.
    194         . ; SIGDATA is the simplfied array.
    195         . F  S FMSIGNUM=$O(FMSIG(FMSIGNUM)) Q:FMSIGNUM=""  D
    196         . . N DIRCNT S DIRCNT=$P(FMSIGNUM,",")
    197         . . N SIGDATA M SIGDATA=FMSIG(FMSIGNUM)
    198         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDIRECTIONDESCRIPTIONTEXT")=""  ; This is reserved for systems not able to generate the sig in components.
    199         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDOSEINDICATOR")="1"  ; means that we are specifying it. See E2369-05.
    200         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDELIVERYMETHOD")=$G(SIGDATA(8))
    201         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDOSEVALUE")=$G(SIGDATA(.01))
    202         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDOSEUNIT")=$G(SIGDATA(2))
    203         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDRATEVALUE")=""  ; For inpatient
    204         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDRATEUNIT")=""  ; For inpatient
    205         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDVEHICLETEXT")=""  ; For inpatient
    206         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDIRECTIONROUTETEXT")=$G(SIGDATA(6))
    207         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDFREQUENCYVALUE")=$G(SIGDATA(7))
    208         . . ; Invervals... again another call.
    209         . . ; In the wisdom of the original programmers, the schedule is a free text field
    210         . . ; However, it gets translated by a call to the administration schedule file
    211         . . ; to see if that schedule exists.
    212         . . ; That's the same thing I am going to do.
    213         . . ; Search B index of 51.1 (Admin Schedule) with schedule
    214         . . ; First, remove "PRN" if it exists (don't ask, that's how the file
    215         . . ; works; I wouldn't do it that way).
    216         . . N SCHNOPRN S SCHNOPRN=$G(SIGDATA(7))
    217         . . I SCHNOPRN["PRN" S SCHNOPRN=$E(SCHNOPRN,1,$F(SCHNOPRN,"PRN")-5)
    218         . . ; Super call below:
    219         . . ; 1=File 51.1 3=Field 2 (Frequency in Minutes)
    220         . . ; 4=Packed format, Exact Match 5=Lookup Value
    221         . . ; 6=# of entries to return 7=Index 10=Return Array
    222         . . ;
    223         . . ; I do not account for the fact that two schedules can be
    224         . . ; spelled identically (ie duplicate entry). In that case,
    225         . . ; I get the first. That's just a bad pharmacy pkg maintainer.
    226         . . N C0C515
    227         . . D FIND^DIC(51.1,,"@;2","PX",SCHNOPRN,1,"B",,,"C0C515")
    228         . . N INTERVAL S INTERVAL="" ; Default
    229         . . ; If there are entries found, get it
    230         . . I +$G(C0C515("DILIST",0)) S INTERVAL=$P(C0C515("DILIST",1,0),U,2)
    231         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDINTERVALVALUE")=INTERVAL
    232         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDINTERVALUNIT")="Minute"
    233         . . ; Duration is 10M minutes, 10H hours, 10D for Days
    234         . . ; 10W for weeks, 10L for months. I smell $Select
    235         . . ; But we don't need to do that if there isn't a duration
    236         . . I +$G(SIGDATA(4)) D
    237         . . . N DURUNIT S DURUNIT=$E(SIGDATA(4),$L(SIGDATA(4))) ; get last char
    238         . . . N DURTXT S DURTXT=$S(DURUNIT="M":"Minutes",DURUNIT="H":"Hours",DURUNIT="D":"Days",DURUNIT="W":"Weeks",DURUNIT="L":"Months",1:"Days")
    239         . . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDURATIONVALUE")=+SIGDATA(4)
    240         . . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDURATIONUNIT")=DURTXT
    241         . . E  D
    242         . . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDURATIONVALUE")=""
    243         . . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDURATIONUNIT")=""
    244         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPRNFLAG")=$G(SIGDATA(4))["PRN"
    245         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMOBJECTID")="" ; when avail
    246         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMTYPETXT")=""
    247         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMDESCRIPTION")=""
    248         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMCODEVALUE")=""
    249         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMCODINGSYSTEM")=""
    250         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMCODINGVERSION")=""
    251         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMSOURCEACTORID")=""
    252         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDSTOPINDICATOR")="" ; not stored
    253         . . ; Another confusing line; I am pretty bad:
    254         . . ; If there is another entry in the FMSIG array (i.e. another line
    255         . . ; in the sig), set the direction count indicator.
    256         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDIRSEQ")=""  ; Default
    257         . . S:+$O(FMSIG(FMSIGNUM)) @MAP@("M","DIRECTIONS",DIRCNT,"MEDDIRSEQ")=DIRCNT
    258         . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDMULDIRMOD")=$G(SIGDATA(5))
    259         . ;
    260         . ; --- END OF DIRECTIONS ---
    261         . ;
    262         . ; Med instructions is a WP field, thus the acrobatics
    263         . ; Notice buffer overflow protection set at 10,000 chars
    264         . ; -- 1. Med Patient Instructions
    265         . N MEDPTIN1 S MEDPTIN1=$$GET1^DIQ(52,RXIEN,115,,"MEDPTIN1")
    266         . N MEDPTIN2,J  S (MEDPTIN2,J)=""
    267         . I $L(MEDPTIN1) F  S J=$O(@MEDPTIN1@(J)) Q:J=""  Q:$L(MEDPTIN2)>10000  S MEDPTIN2=MEDPTIN2_@MEDPTIN1@(J)_" "
    268         . S @MAP@("MEDPTINSTRUCTIONS")=MEDPTIN2
    269         . K J
    270         . ; -- 2. Med Provider Instructions
    271         . N MEDPVIN1 S MEDPVIN1=$$GET1^DIQ(52,RXIEN,39,,"MEDPVIN1")
    272         . N MEDPVIN2,J S (MEDPVIN2,J)=""
    273         . I $L(MEDPVIN1) F  S J=$O(@MEDPVIN1@(J)) Q:J=""  Q:$L(MEDPVIN2)>10000  S MEDPVIN2=MEDPVIN2_@MEDPVIN1@(J)_" "
    274         . S @MAP@("MEDFULLFILLMENTINSTRUCTIONS")=MEDPVIN2
    275         . ;
    276         . ; Remaining refills
    277         . S @MAP@("MEDRFNO")=$P(MEDS(MEDCNT),U,6)
    278         . ; ------ END OF MAPPING
    279         . ;
    280         . ; ------ BEGIN XML INSERTION
    281         . N RESULT S RESULT=$NA(^TMP("C0CCCR",$J,"MAPPED"))
    282         . K @RESULT
    283         . D MAP^C0CXPATH(MINXML,MAP,RESULT)
    284         . ; D PARY^C0CXPATH(RESULT)
    285         . ; MAPPING DIRECTIONS
    286         . N MEDDIR1,DIRXML1 S DIRXML1="MEDDIR1" ; VARIABLE AND NAME VARIABLE TEMPLATE
    287         . N MEDDIR2,DIRXML2 S DIRXML2="MEDDIR2" ; VARIABLE AND NAME VARIABLE RESULT
    288         . D QUERY^C0CXPATH(MINXML,"//Medications/Medication/Directions",DIRXML1)
    289         . D REPLACE^C0CXPATH(RESULT,"","//Medications/Medication/Directions")
    290         . ; N MDZ1,MDZNA
    291         . N DIRCNT S DIRCNT=""
    292         . I +$O(@MAP@("M","DIRECTIONS",DIRCNT)) D  ; IF THERE ARE DIRCTIONS
    293         . . F DIRCNT=$O(@MAP@("M","DIRECTIONS",DIRCNT)) D  ; FOR EACH DIRECTION
    294         . . . S MDZNA=$NA(@MAP@("M","DIRECTIONS",DIRCNT))
    295         . . . D MAP^C0CXPATH(DIRXML1,MDZNA,DIRXML2)
    296         . . . D INSERT^C0CXPATH(RESULT,DIRXML2,"//Medications/Medication")
    297         . D:MEDCNT=1 CP^C0CXPATH(RESULT,OUTXML) ; First one is a copy
    298         . D:MEDCNT>1 INSINNER^C0CXPATH(OUTXML,RESULT) ; AFTER THE FIRST, INSERT INNER XML
    299         N MEDTMP,MEDI
    300         D MISSING^C0CXPATH(OUTXML,"MEDTMP") ; SEARCH XML FOR MISSING VARS
    301         I MEDTMP(0)>0 D  ; IF THERE ARE MISSING VARS - MARKED AS @@X@@
    302         . W "MEDICATION MISSING ",!
    303         . F MEDI=1:1:MEDTMP(0) W MEDTMP(MEDI),!
    304         Q
    305         ;
     24 ;
     25 ; MINXML and OUTXML are passed by name so globals can be used
     26 ; MINXML will contain only the medications skeleton of the overall template
     27 ; FLAGS are: MEDALL(bool)^MEDLIMIT(int)^MEDACTIVE(bool)^MEDPENDING(bool)
     28 ; FLAGS are set-up in C0CMED.
     29 ;
     30 ; MEDS is return array from RPC.
     31 ; MAP is a mapping variable map (store result) for each med
     32 ; MED is holds each array element from MEDS(J), one medicine
     33 ; J is a counter.
     34 ;
     35 ; GETRXS^BEHORXFN(ARRAYNAME,DFN,DAYS) will be the the API used.
     36 ; This API has been developed by Medsphere for IHS for getting
     37 ; Medications from RPMS. It has most of what we need.
     38 ; API written by Doug Martin when he worked for Medsphere (thanks Doug!)
     39 ; -- ARRAYNAME is passed by name (required)
     40 ; -- DFN is passed by value (required)
     41 ; -- DAYS is passed by value (optional; if not passed defaults to 365)
     42 ;
     43 ; Return:
     44 ; ~Type^PharmID^Drug^InfRate^StopDt^RefRem^TotDose^UnitDose^OrderID
     45 ; ^Status^LastFill^Chronic^Issued^Rx #^Provider^
     46 ; Status Reason^DEA Handling
     47 ;
     48 N MEDS,MEDS1,MAP
     49 D GETRXS^BEHORXFN("MEDS1",DFN,$P($P(FLAGS,U,2),"-",2)) ; 2nd piece of FLAGS is # of days to retrieve, which comes in the form "T-360"
     50 N ALL S ALL=+FLAGS
     51 N ACTIVE S ACTIVE=$P(FLAGS,U,3)
     52 N PENDING S PENDING=$P(FLAGS,U,4)
     53 S @OUTXML@(0)=0  ;By default, no meds
     54 ; If MEDS1 is not defined, then no meds
     55 I '$D(MEDS1) QUIT
     56 I DEBUG ZWR MEDS1,MINXML
     57 N MEDCNT S MEDCNT=0 ; Med Count
     58 ; The next line is a super line. It goes through the array return
     59 ; and if the first characters are ~OP, it grabs the line.
     60 ; This means that line is for a dispensed Outpatient Med.
     61 ; That line has the metadata about the med that I need.
     62 ; The next lines, however many, are the med and the sig.
     63 ; I won't be using those because I have to get the sig parsed exactly.
     64 N J S J="" F  S J=$O(MEDS1(J)) Q:J=""  I $E(MEDS1(J),1,3)="~OP" S MEDCNT=MEDCNT+1 S MEDS(MEDCNT)=MEDS1(J)
     65 K MEDS1
     66 S MEDCNT="" ; Initialize for $Order
     67 F  S MEDCNT=$O(MEDS(MEDCNT)) Q:MEDCNT=""  D  ; for each medication in the list
     68 . I 'ALL,ACTIVE,$P(MEDS(MEDCNT),U,10)'="ACTIVE" QUIT
     69 . I 'ALL,PENDING,$P(MEDS(MEDCNT),U,10)'="PENDING" QUIT
     70 . I DEBUG W "MEDCNT IS ",MEDCNT,!
     71 . S MAP=$NA(^TMP("C0CCCR",$J,"MEDMAP",MEDCNT))
     72 . ; K @MAP DO NOT KILL HERE, WAS CLEARED IN C0CMED
     73 . I DEBUG W "MAP= ",MAP,!
     74 . S @MAP@("MEDOBJECTID")="MED"_MEDCNT ; MEDCNT FOR ID
     75 . S @MAP@("MEDISSUEDATETXT")="Issue Date"
     76 . S @MAP@("MEDISSUEDATE")=$$FMDTOUTC^C0CUTIL($P(MEDS(MEDCNT),U,13))
     77 . S @MAP@("MEDLASTFILLDATETXT")="Last Fill Date"
     78 . S @MAP@("MEDLASTFILLDATE")=$$FMDTOUTC^C0CUTIL($P(MEDS(MEDCNT),U,11))
     79 . S @MAP@("MEDRXNOTXT")="Prescription Number"
     80 . S @MAP@("MEDRXNO")=$P(MEDS(MEDCNT),U,14)
     81 . S @MAP@("MEDTYPETEXT")="Medication"
     82 . S @MAP@("MEDDETAILUNADORNED")=""  ; Leave blank, field has its uses
     83 . S @MAP@("MEDSTATUSTEXT")=$P(MEDS(MEDCNT),U,10)
     84 . ; Provider only provided in API as text, not DUZ.
     85 . ; We need to get DUZ from filman file 52 (Prescription)
     86 . ; Field 4; IEN is Piece 2 of Meds stripped of trailing characters.
     87 . ; Note that I will use RXIEN several times later
     88 . N RXIEN S RXIEN=+$P(MEDS(MEDCNT),U,2)
     89 . S @MAP@("MEDSOURCEACTORID")="ACTORPROVIDER_"_$$GET1^DIQ(52,RXIEN,4,"I")
     90 . S @MAP@("MEDPRODUCTNAMETEXT")=$P(MEDS(MEDCNT),U,3)
     91 . ; --- RxNorm Stuff
     92 . ; 176.001 is the file for Concepts; 176.003 is the file for
     93 . ; sources (i.e. for RxNorm Version)
     94 . ;
     95 . ; I use 176.001 for the Vista version of this routine (files 1-3)
     96 . ; Since IHS does not have VUID's, I will be getting RxNorm codes
     97 . ; using NDCs. My specially crafted index (sounds evil) named "NDC"
     98 . ; is in file 176.002. The file is called RxNorm NDC to VUID.
     99 . ; Except that I don't need the VUID, but it's there if I need it.
     100 . ;
     101 . ; We obviously need the NDC. That is easily obtained from the prescription.
     102 . ; Field 27 in file 52
     103 . N NDC S NDC=$$GET1^DIQ(52,RXIEN,27,"I")
     104 . ; I discovered that file 176.002 might give you two codes for the NDC
     105 . ; One for the Clinical Drug, and one for the ingredient.
     106 . ; So the plan is to get the two RxNorm codes, and then find from
     107 . ; file 176.001 which one is the Clinical Drug.
     108 . ; ... I refactored this into GETRXN
     109 . N RXNORM,SRCIEN,RXNNAME,RXNVER
     110 . I +NDC,$D(^C0CRXN) D  ; $Data is for Systems that don't have our RxNorm file yet.
     111 . . S RXNORM=$$GETRXN(NDC)
     112 . . S SRCIEN=$$FIND1^DIC(176.003,,,"RXNORM","B")
     113 . . S RXNNAME=$$GET1^DIQ(176.003,SRCIEN,6)
     114 . . S RXNVER=$$GET1^DIQ(176.003,SRCIEN,7)
     115 . ;
     116 . E  S (RXNORM,RXNNAME,RXNVER)=""
     117 . ; End if/else block
     118 . S @MAP@("MEDPRODUCTNAMECODEVALUE")=RXNORM
     119 . S @MAP@("MEDPRODUCTNAMECODINGINGSYSTEM")=RXNNAME
     120 . S @MAP@("MEDPRODUCTNAMECODEVERSION")=RXNVER
     121 . ; --- End RxNorm section
     122 . ;
     123 . ; Brand name is 52 field 6.5
     124 . S @MAP@("MEDBRANDNAMETEXT")=$$GET1^DIQ(52,RXIEN,6.5)
     125 . ;
     126 . ; Next I need Med Form (tab, cap etc), strength (250mg)
     127 . ; concentration for liquids (250mg/mL)
     128 . ; Since IHS does not have any of the new calls that
     129 . ; Vista has, I will be doing a crosswalk:
     130 . ; File 52, field 6 is Drug IEN in file 50
     131 . ; File 50, field 22 is VA Product IEN in file 50.68
     132 . ; In file 50.68, I will get the following:
     133 . ; -- 1: Dosage Form
     134 . ; -- 2: Strength
     135 . ; -- 3: Units
     136 . ; -- 8: Dispense Units
     137 . ; -- Conc is 2 concatenated with 3
     138 . ;
     139 . ; *** If Drug is not matched to NDF, then VA Product will be "" ***
     140 . ;
     141 . N MEDIEN S MEDIEN=$$GET1^DIQ(52,RXIEN,6,"I") ; Drug IEN in 50
     142 . N VAPROD S VAPROD=$$GET1^DIQ(50,MEDIEN,22,"I") ; VA Product in file 50.68
     143 . I +VAPROD D
     144 . . S @MAP@("MEDSTRENGTHVALUE")=$$GET1^DIQ(50.68,VAPROD,2)
     145 . . S @MAP@("MEDSTRENGTHUNIT")=$$GET1^DIQ(50.68,VAPROD,3)
     146 . . S @MAP@("MEDFORMTEXT")=$$GET1^DIQ(50.68,VAPROD,1)
     147 . . S @MAP@("MEDCONCVALUE")=@MAP@("MEDSTRENGTHVALUE")
     148 . . S @MAP@("MEDCONCUNIT")=@MAP@("MEDSTRENGTHUNIT")
     149 . E  D
     150 . . S @MAP@("MEDSTRENGTHVALUE")=""
     151 . . S @MAP@("MEDSTRENGTHUNIT")=""
     152 . . S @MAP@("MEDFORMTEXT")=""
     153 . . S @MAP@("MEDCONCVALUE")=""
     154 . . S @MAP@("MEDCONCUNIT")=""
     155 . ; End Strengh/Conc stuff
     156 . ;
     157 . ; Quantity is in the prescription, field 7
     158 . S @MAP@("MEDQUANTITYVALUE")=$$GET1^DIQ(52,RXIEN,7)
     159 . ; Dispense unit is in the drug file, field 14.5
     160 . S @MAP@("MEDQUANTITYUNIT")=$$GET1^DIQ(50,MEDIEN,14.5)
     161 . ;
     162 . ; --- START OF DIRECTIONS ---
     163 . ; Sig data not in any API :-(  Oh yes, you can get the whole thing, but...
     164 . ; we want the components.
     165 . ; It's in multiple 113 in the Prescription File (52)
     166 . ; #.01 DOSAGE ORDERED [1F]                   "20"
     167 . ; #1 DISPENSE UNITS PER DOSE [2N]    "1"
     168 . ; #2 UNITS [3P:50.607]                               "MG"
     169 . ; #3 NOUN [4F]                                               "TABLET"
     170 . ; #4 DURATION [5F]                                   "10D"
     171 . ; #5 CONJUNCTION [6S]                                "AND"
     172 . ; #6 ROUTE [7P:51.2]                                 "ORAL"
     173 . ; #7 SCHEDULE [8F]                                   "BID"
     174 . ; #8 VERB [9F]                                               "TAKE"
     175 . ;
     176 . ; Will use GETS^DIQ to get fields.
     177 . ; Data comes out like this:
     178 . ; SAMINS(52.0113,"1,23,",.01)=20
     179 . ; SAMINS(52.0113,"1,23,",1)=1
     180 . ; SAMINS(52.0113,"1,23,",2)="MG"
     181 . ; SAMINS(52.0113,"1,23,",3)="TABLET"
     182 . ; SAMINS(52.0113,"1,23,",4)="5D"
     183 . ; SAMINS(52.0113,"1,23,",5)="THEN"
     184 . ;
     185 . N RAWDATA
     186 . D GETS^DIQ(52,RXIEN,"113*",,"RAWDATA","DIERR")
     187 . D:$D(DIERR) ^%ZTER  ; Log if there's an error in retrieving sig field
     188 . ; none the less, continue; some parts are retrievable.
     189 . N FMSIG M FMSIG=RAWDATA(52.0113) ; Merge into subfile...
     190 . K RAWDATA
     191 . N FMSIGNUM S FMSIGNUM="" ; Sigline number in fileman.
     192 . ; FMSIGNUM gets outputted as "IEN,RXIEN,".
     193 . ; DIRCNT is the proper Sigline numer.
     194 . ; SIGDATA is the simplfied array.
     195 . F  S FMSIGNUM=$O(FMSIG(FMSIGNUM)) Q:FMSIGNUM=""  D
     196 . . N DIRCNT S DIRCNT=$P(FMSIGNUM,",")
     197 . . N SIGDATA M SIGDATA=FMSIG(FMSIGNUM)
     198 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDIRECTIONDESCRIPTIONTEXT")=""  ; This is reserved for systems not able to generate the sig in components.
     199 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDOSEINDICATOR")="1"  ; means that we are specifying it. See E2369-05.
     200 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDELIVERYMETHOD")=$G(SIGDATA(8))
     201 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDOSEVALUE")=$G(SIGDATA(.01))
     202 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDOSEUNIT")=$G(SIGDATA(2))
     203 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDRATEVALUE")=""  ; For inpatient
     204 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDRATEUNIT")=""  ; For inpatient
     205 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDVEHICLETEXT")=""  ; For inpatient
     206 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDIRECTIONROUTETEXT")=$G(SIGDATA(6))
     207 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDFREQUENCYVALUE")=$G(SIGDATA(7))
     208 . . ; Invervals... again another call.
     209 . . ; In the wisdom of the original programmers, the schedule is a free text field
     210 . . ; However, it gets translated by a call to the administration schedule file
     211 . . ; to see if that schedule exists.
     212 . . ; That's the same thing I am going to do.
     213 . . ; Search B index of 51.1 (Admin Schedule) with schedule
     214 . . ; First, remove "PRN" if it exists (don't ask, that's how the file
     215 . . ; works; I wouldn't do it that way).
     216 . . N SCHNOPRN S SCHNOPRN=$G(SIGDATA(7))
     217 . . I SCHNOPRN["PRN" S SCHNOPRN=$E(SCHNOPRN,1,$F(SCHNOPRN,"PRN")-5)
     218 . . ; Super call below:
     219 . . ; 1=File 51.1 3=Field 2 (Frequency in Minutes)
     220 . . ; 4=Packed format, Exact Match 5=Lookup Value
     221 . . ; 6=# of entries to return 7=Index 10=Return Array
     222 . . ;
     223 . . ; I do not account for the fact that two schedules can be
     224 . . ; spelled identically (ie duplicate entry). In that case,
     225 . . ; I get the first. That's just a bad pharmacy pkg maintainer.
     226 . . N C0C515
     227 . . D FIND^DIC(51.1,,"@;2","PX",SCHNOPRN,1,"B",,,"C0C515")
     228 . . N INTERVAL S INTERVAL="" ; Default
     229 . . ; If there are entries found, get it
     230 . . I +$G(C0C515("DILIST",0)) S INTERVAL=$P(C0C515("DILIST",1,0),U,2)
     231 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDINTERVALVALUE")=INTERVAL
     232 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDINTERVALUNIT")="Minute"
     233 . . ; Duration is 10M minutes, 10H hours, 10D for Days
     234 . . ; 10W for weeks, 10L for months. I smell $Select
     235 . . ; But we don't need to do that if there isn't a duration
     236 . . I +$G(SIGDATA(4)) D
     237 . . . N DURUNIT S DURUNIT=$E(SIGDATA(4),$L(SIGDATA(4))) ; get last char
     238 . . . N DURTXT S DURTXT=$S(DURUNIT="M":"Minutes",DURUNIT="H":"Hours",DURUNIT="D":"Days",DURUNIT="W":"Weeks",DURUNIT="L":"Months",1:"Days")
     239 . . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDURATIONVALUE")=+SIGDATA(4)
     240 . . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDURATIONUNIT")=DURTXT
     241 . . E  D
     242 . . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDURATIONVALUE")=""
     243 . . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDURATIONUNIT")=""
     244 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPRNFLAG")=$G(SIGDATA(4))["PRN"
     245 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMOBJECTID")="" ; when avail
     246 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMTYPETXT")=""
     247 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMDESCRIPTION")=""
     248 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMCODEVALUE")=""
     249 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMCODINGSYSTEM")=""
     250 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMCODINGVERSION")=""
     251 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDPROBLEMSOURCEACTORID")=""
     252 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDSTOPINDICATOR")="" ; not stored
     253 . . ; Another confusing line; I am pretty bad:
     254 . . ; If there is another entry in the FMSIG array (i.e. another line
     255 . . ; in the sig), set the direction count indicator.
     256 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDDIRSEQ")=""  ; Default
     257 . . S:+$O(FMSIG(FMSIGNUM)) @MAP@("M","DIRECTIONS",DIRCNT,"MEDDIRSEQ")=DIRCNT
     258 . . S @MAP@("M","DIRECTIONS",DIRCNT,"MEDMULDIRMOD")=$G(SIGDATA(5))
     259 . ;
     260 . ; --- END OF DIRECTIONS ---
     261 . ;
     262 . ; Med instructions is a WP field, thus the acrobatics
     263 . ; Notice buffer overflow protection set at 10,000 chars
     264 . ; -- 1. Med Patient Instructions
     265 . N MEDPTIN1 S MEDPTIN1=$$GET1^DIQ(52,RXIEN,115,,"MEDPTIN1")
     266 . N MEDPTIN2,J  S (MEDPTIN2,J)=""
     267 . I $L(MEDPTIN1) F  S J=$O(@MEDPTIN1@(J)) Q:J=""  Q:$L(MEDPTIN2)>10000  S MEDPTIN2=MEDPTIN2_@MEDPTIN1@(J)_" "
     268 . S @MAP@("MEDPTINSTRUCTIONS")=MEDPTIN2
     269 . K J
     270 . ; -- 2. Med Provider Instructions
     271 . N MEDPVIN1 S MEDPVIN1=$$GET1^DIQ(52,RXIEN,39,,"MEDPVIN1")
     272 . N MEDPVIN2,J S (MEDPVIN2,J)=""
     273 . I $L(MEDPVIN1) F  S J=$O(@MEDPVIN1@(J)) Q:J=""  Q:$L(MEDPVIN2)>10000  S MEDPVIN2=MEDPVIN2_@MEDPVIN1@(J)_" "
     274 . S @MAP@("MEDFULLFILLMENTINSTRUCTIONS")=MEDPVIN2
     275 . ;
     276 . ; Remaining refills
     277 . S @MAP@("MEDRFNO")=$P(MEDS(MEDCNT),U,6)
     278 . ; ------ END OF MAPPING
     279 . ;
     280 . ; ------ BEGIN XML INSERTION
     281 . N RESULT S RESULT=$NA(^TMP("C0CCCR",$J,"MAPPED"))
     282 . K @RESULT
     283 . D MAP^C0CXPATH(MINXML,MAP,RESULT)
     284 . ; D PARY^C0CXPATH(RESULT)
     285 . ; MAPPING DIRECTIONS
     286 . N MEDDIR1,DIRXML1 S DIRXML1="MEDDIR1" ; VARIABLE AND NAME VARIABLE TEMPLATE
     287 . N MEDDIR2,DIRXML2 S DIRXML2="MEDDIR2" ; VARIABLE AND NAME VARIABLE RESULT
     288 . D QUERY^C0CXPATH(MINXML,"//Medications/Medication/Directions",DIRXML1)
     289 . D REPLACE^C0CXPATH(RESULT,"","//Medications/Medication/Directions")
     290 . ; N MDZ1,MDZNA
     291 . N DIRCNT S DIRCNT=""
     292 . I +$O(@MAP@("M","DIRECTIONS",DIRCNT)) D  ; IF THERE ARE DIRCTIONS
     293 . . F DIRCNT=$O(@MAP@("M","DIRECTIONS",DIRCNT)) D  ; FOR EACH DIRECTION
     294 . . . S MDZNA=$NA(@MAP@("M","DIRECTIONS",DIRCNT))
     295 . . . D MAP^C0CXPATH(DIRXML1,MDZNA,DIRXML2)
     296 . . . D INSERT^C0CXPATH(RESULT,DIRXML2,"//Medications/Medication")
     297 . D:MEDCNT=1 CP^C0CXPATH(RESULT,OUTXML) ; First one is a copy
     298 . D:MEDCNT>1 INSINNER^C0CXPATH(OUTXML,RESULT) ; AFTER THE FIRST, INSERT INNER XML
     299 N MEDTMP,MEDI
     300 D MISSING^C0CXPATH(OUTXML,"MEDTMP") ; SEARCH XML FOR MISSING VARS
     301 I MEDTMP(0)>0 D  ; IF THERE ARE MISSING VARS - MARKED AS @@X@@
     302 . W "MEDICATION MISSING ",!
     303 . F MEDI=1:1:MEDTMP(0) W MEDTMP(MEDI),!
     304 Q
     305 ;
    306306GETRXN(NDC)     ; Extrinsic Function; PUBLIC; NDC to RxNorm
    307         ;; Get RxNorm Concept Number for a Given NDC
    308         ;
    309         S NDC=$TR(NDC,"-")  ; Remove dashes
    310         N RXNORM,C0CZRXN,DIERR
    311         D FIND^DIC(176.002,,"@;.01","PX",NDC,"*","NDC",,,"C0CZRXN","DIERR")
    312         I $D(DIERR) D ^%ZTER BREAK
    313         S RXNORM(0)=+C0CZRXN("DILIST",0) ; RxNorm(0) will be # of entries
    314         N I S I=0
    315         F  S I=$O(C0CZRXN("DILIST",I)) Q:I=""  S RXNORM(I)=$P(C0CZRXN("DILIST",I,0),U,2)
    316         ; At this point, RxNorm(0) is # of entries; RxNorm(1...) are the entries
    317         ; If RxNorm(0) is 1, then we only have one entry, and that's it.
    318         I RXNORM(0)=1 QUIT RXNORM(1)  ; RETURN RXNORM(1)
    319         ; Otherwise, we need to find out which one is the semantic
    320         ; clinical drug. I built an index on 176.001 (RxNorm Concepts)
    321         ; for that purpose.
    322         I RXNORM(0)>1 D
    323         . S I=0
    324         . F  S I=$O(RXNORM(I)) Q:I=""  D  Q:$G(RXNORM)
    325         . . N RXNIEN S RXNIEN=$$FIND1^DIC(176.001,,,RXNORM(I),"SCD")
    326         . . I +$G(RXNIEN)=0 QUIT  ; try the next entry...
    327         . . E  S RXNORM=RXNORM(I) QUIT  ; We found the right code
    328         QUIT +$G(RXNORM)  ; RETURN RXNORM; if we couldn't find a clnical drug, return with 0
    329        
     307 ;; Get RxNorm Concept Number for a Given NDC
     308 ;
     309 S NDC=$TR(NDC,"-")  ; Remove dashes
     310 N RXNORM,C0CZRXN,DIERR
     311 D FIND^DIC(176.002,,"@;.01","PX",NDC,"*","NDC",,,"C0CZRXN","DIERR")
     312 I $D(DIERR) D ^%ZTER BREAK
     313 S RXNORM(0)=+C0CZRXN("DILIST",0) ; RxNorm(0) will be # of entries
     314 N I S I=0
     315 F  S I=$O(C0CZRXN("DILIST",I)) Q:I=""  S RXNORM(I)=$P(C0CZRXN("DILIST",I,0),U,2)
     316 ; At this point, RxNorm(0) is # of entries; RxNorm(1...) are the entries
     317 ; If RxNorm(0) is 1, then we only have one entry, and that's it.
     318 I RXNORM(0)=1 QUIT RXNORM(1)  ; RETURN RXNORM(1)
     319 ; Otherwise, we need to find out which one is the semantic
     320 ; clinical drug. I built an index on 176.001 (RxNorm Concepts)
     321 ; for that purpose.
     322 I RXNORM(0)>1 D
     323 . S I=0
     324 . F  S I=$O(RXNORM(I)) Q:I=""  D  Q:$G(RXNORM)
     325 . . N RXNIEN S RXNIEN=$$FIND1^DIC(176.001,,,RXNORM(I),"SCD")
     326 . . I +$G(RXNIEN)=0 QUIT  ; try the next entry...
     327 . . E  S RXNORM=RXNORM(I) QUIT  ; We found the right code
     328 QUIT +$G(RXNORM)  ; RETURN RXNORM; if we couldn't find a clnical drug, return with 0
     329 
Note: See TracChangeset for help on using the changeset viewer.