- ACHSTX11 ; IHS/ITSC/PMF - EXPORT DATA. Extract
- ;;3.1;CONTRACT HEALTH MGMT SYSTEM;;JUN 11, 2001
- ;
- ;we get here if we are going to do an export. REexporting
- ;goes through another program.
- ;
- ;
- ;I've looked at this process a whole lot, and this is the easiest
- ;way of doing things that I can find. What's going to happen is
- ;that we will examine each transaction that has occurred from the
- ;start date to the end date. We will decide if this transaction
- ;of this document will generate any records for export.
- ;
- ;If it does, we create them right away. This is easy to do at this
- ;point because we have already pulled most of the info about this
- ;document from the detabase already. What it means, though, is that
- ;the calls will get pretty deep. Remember that when reading the
- ;program for the first time and don't let it get you lost.
- ;
- ;When the records get created, they get put into different globals.
- ;When allll of the records are created, we then take them out of
- ;those globals and put them into ^ACHSDATA (the type 2 records are
- ;already in that global.) This is done so that the final result
- ;will be a list of all of the type 2s then all of the type 3s, then
- ;all of the type 4s, etc.
- ;
- ;
- ;Deciding which records get created is complicated. We have made it
- ;as simple as possible, but it is still complicated. None of the
- ;records get generated due to exactly the same set of circumstances.
- ;Instead, the circumstances overlap in some places and not in others.
- ;When the code comes to that part of it, this is explained further.
- ;
- ;These programs are written more for clarity than for expediancy. It
- ;would be easy to make some some changes and save a few milliseconds,
- ;but you would then not want to read the program.
- ;
- ;init some stuff. If it fails, quit
- D INIT I STOP Q
- ;
- ;remove two lines for testing !!!!!
- ;D EXPRT
- ;I STOP Q
- ;
- ;
- ;W @IOF,!,ACHS("*"),!?30,"EXPORT CHS DATA",!,ACHS("*"),!
- ;
- ;record the start and end dates FDT is first date, LDT is last date
- ;S ACHSFDT=ACHSBDT,ACHSLDAT=ACHSEDT
- ;
- ;for test!!!!!
- S ACHSBDT=ACHSSBD,ACHSEDT=ACHSSED
- ;
- ;for each day from start to end date, look for...
- F S ACHSBDT=$O(^ACHSF(DUZ(2),"TB",ACHSBDT)) Q:ACHSBDT=""!(ACHSBDT>ACHSEDT) D EXTRCT
- ;
- K DOLH,PMFCOUNT
- Q
- ;
- EXTRCT ;
- ;if this is the first day, set record count to 0
- S:ACHSRCT=0 ACHSFDT=ACHSBDT
- ;
- ;for each transaction type except ZAs and IPs, do...
- S ACHSTY="" F S ACHSTY=$O(^ACHSF(DUZ(2),"TB",ACHSBDT,ACHSTY)) Q:ACHSTY="" I ACHSTY'="ZA",(ACHSTY'="IP") D EXTR2
- Q
- ;
- EXTR2 ;
- ;for each document of this type on this day...
- S ACHSDIEN=0 F S ACHSDIEN=$O(^ACHSF(DUZ(2),"TB",ACHSBDT,ACHSTY,ACHSDIEN)) Q:ACHSDIEN="" D EXTR3
- Q
- EXTR3 ;
- ;go fetch the data on this document. if it's not okay, stop
- D ^ACHSDOCR I 'OK Q
- D ^ACHSVNDR I 'OK Q
- ;
- ;if this is a blanket order, stop
- I BLNKT=2 D KLL^ACHSDOCR,KLL^ACHSVNDR Q
- ;
- ;now that we have document data build some other pieces
- S ACHSCTY=ACHSTY
- S ACHSDOCN="0"_$P(ACHSDOCR,U,14)_ACHSFC_$E($P(ACHSDOCR,U)+100000,2,6)
- ;
- ;for each transaction within this trans type on the
- ; document for today...
- S TNUM=0 F S TNUM=$O(^ACHSF(DUZ(2),"TB",ACHSBDT,ACHSTY,ACHSDIEN,TNUM)) Q:TNUM="" D EXTR4
- D KLL^ACHSDOCR,KLL^ACHSVNDR
- Q
- ;
- EXTR4 ;EP from ACHSTX2R
- ;
- ;fo continuity with other programs, use DA for that last subscript
- S DA=TNUM
- ;
- ;for test
- ;W !,ACHSBDT,?15,ACHSTY,?30,ACHSDIEN,?45,TNUM R YAYA
- ;
- I $P($H,",",2)-TIME>3 W " ." S TIME=$P($H,",",2)
- ;
- ;make sure that the transaction that "TB" is pointing to actually
- ;exists
- I 'ACHSREEX,'$D(^ACHSF(DUZ(2),"D",ACHSDIEN,"T",DA,0)) K ^ACHSF(DUZ(2),"TB",ACHSBDT,ACHSTY,ACHSDIEN,DA) Q
- ;
- S ACHSTRAN=^ACHSF(DUZ(2),"D",ACHSDIEN,"T",DA,0)
- ;
- ;get the initial payment amount and format it
- S ACHSIPA=$P(^ACHSF(DUZ(2),"D",ACHSDIEN,"T",DA,0),U,4)
- S ACHSIPA=$P(ACHSIPA,".",1)_$E($P(ACHSIPA,".",2)_"00",1,2),ACHSIPA=$E(ACHSIPA+1000000000000,2,13)
- ;
- ;if the type is Cancel, don't use it. use the trans type instead
- I ACHSCTY="C" S ACHSCTY=$P(^ACHSF(DUZ(2),"D",ACHSDIEN,"T",DA,0),U,5)
- ;
- ;now decide if this document will generate some records.
- ;each record type gets created or not based on several
- ;parameters. Not all of the records use all of the
- ;parameters, though. So there is OVERLAP in the way
- ;records qualify, but it's a complicated pattern of
- ;overlap. You will see it the the next programs called.
- ;
- ;
- ;When we are done here, the transactions that got made will be
- ;in various different globals.
- ;Also, there will be an entry in ^ACHSXPRT that looks like this:
- ;
- ;^ACHSXPRT(ACHSDIEN,DA)=r2^r3^r4^r5^r6^r7
- ;
- ;where ACHSDIEN is the internal sequence number of the document
- ; DA is the transaction subscript
- ; rx is the action taken on the document for trans type x
- ; for example, if r4 = "", we did not creat a type 4 trans
- ; and we don't know why.
- ; SHOULD NOT OCCUR.
- ; if r5 = 0, that means a type 5 trans was created
- ; a 0 ALWAYS means trans created.
- ; if r3 = 17, then the trans was not created
- ; for reason #17
- ;
- ;for test
- S SDA=DA
- ;
- ;
- ;AFTER the export file is created, BUT NOT BEFORE, we take the info
- ;in ^ACHSXPRT and record it in ^ACHSTXST for permanent storage.
- ;
- ;each of the routines we call expect ACHSDOCR and the standard
- ;document variables, which are returned unchanged, and the
- ;routines will return RET with their outcome
- S LIST="" F NUM=2:1:7 S ROUT="^ACHSTX"_NUM_NUM,RET="" D @ROUT S $P(LIST,U,NUM)=+RET
- ;
- ;SDA for test
- S ^ACHSXPRT(DOLRH,ACHSDIEN,SDA)=LIST K SDA
- ;
- Q
- ;
- EXPRT ;
- ;set up for exporting, as opposed to REexporting
- ;
- ;beginning date starts as the end date of the last export
- S P=$O(^ACHSTXST(DUZ(2),1,""),-1)
- I P'="" S ACHSBDT=$P(^ACHSTXST(DUZ(2),1,P,0),U,3)
- ;if there is no last export, set the start date to 1/1/1800
- I P="" S ACHSBDT=1000101
- ;
- ;now get the ending date. There is no easy way to get it.
- ;go through each child below the "AR" cross reference to get a
- ;register number. then use that register number to see when it
- ;was last closed - that's the "W" cross reference. As you get
- ;each one, see if it's later than the end date you got and, if
- ;it is, keep it.
- ;
- S DA=9999998-DT-1 F S DA=$O(^ACHS(9,DUZ(2),"FY",ACHSCFY,"AR",DA)) Q:DA=""!('DA) D
- . S DCR="" F S DCR=$O(^ACHS(9,DUZ(2),"FY",ACHSCFY,"AR",DA,DCR)) Q:DCR=""!('DCR) D
- .. S DAT=$G(^ACHS(9,DUZ(2),"FY",ACHSCFY,"W",DCR,0))
- .. I $P(DAT,U,2)>ACHSEDT S ACHSEDT=$P(DAT,U,2)
- .. Q
- . Q
- K DAT,DCR
- I 'ACHSEDT W !!,*7,*7,"DCR REGISTER ERROR YOU MUST CLOSE YOUR REGISTERS FIRST" D RTRN^ACHS S STOP=1 Q
- Q
- ;
- INIT ;EP from ACHSTX2R
- ;set up basic vars with default values and in other ways
- ;get set to do this function
- ;
- ;S (ACHSDCR,ACHSEDT,ACHSBDT)=0,ACHSRR=""
- ;
- ;get the authorizing facility number. will be in one of two
- ;places in the AUTTLOC global: either in the entry for this
- ;facility, or in the entry for the area office facility. site
- ;parm makes the difference
- S ACHSAFAC=$P(^AUTTLOC(DUZ(2),0),U,10)
- I $$PARM^ACHS(2,25)="Y" S ACHSAFAC=$P(^ACHSF(DUZ(2),0),U,12) I ACHSAFAC'="" S ACHSAFAC=$P($G(^AUTTLOC(ACHSAFAC,0)),U,10)
- ;if it's not set by now, tell them about it and stop
- I 'ACHSAFAC W !!,*7,*7,"AUTHORIZING FACILITY CODE ERROR - JOB CANCELLED" S STOP=1 Q
- ;
- ;we use a couple of parms several times, including a busy loop, so
- ;lets load them once and keep the values around. other parms we
- ;just use once or twice
- S ACHSF209=$$PARM^ACHS(2,9)="Y",ACHSF211=$$PARM^ACHS(2,11)="Y",ACHSF212=$$PARM^ACHS(2,12)="Y"
- ;
- ;parm 2,9 says whether we are export statistical data or not.
- ;if so, go get some object class codes
- I ACHSF209 D
- . F ACHS="252F","254V" S ACHS(ACHS)=$O(^ACHS(3,DUZ(2),1,"B",ACHS,0))
- . ; if this is a 638 facility, get even more object class codes
- . I ACHSF638="Y" F ACHS="252G","252R","254D","254L","254M" S ACHS(ACHS)=$O(^ACHS(3,DUZ(2),1,"B",ACHS,0))
- . Q
- ;
- ;this array keeps track of how many records of each type we create.
- ;init the counts to zero
- F ACHS=2:1:7 S ACHSRTYP(ACHS)=0
- ;
- Q
- ;
- ACHSTX11 ; IHS/ITSC/PMF - EXPORT DATA. Extract
- +1 ;;3.1;CONTRACT HEALTH MGMT SYSTEM;;JUN 11, 2001
- +2 ;
- +3 ;we get here if we are going to do an export. REexporting
- +4 ;goes through another program.
- +5 ;
- +6 ;
- +7 ;I've looked at this process a whole lot, and this is the easiest
- +8 ;way of doing things that I can find. What's going to happen is
- +9 ;that we will examine each transaction that has occurred from the
- +10 ;start date to the end date. We will decide if this transaction
- +11 ;of this document will generate any records for export.
- +12 ;
- +13 ;If it does, we create them right away. This is easy to do at this
- +14 ;point because we have already pulled most of the info about this
- +15 ;document from the detabase already. What it means, though, is that
- +16 ;the calls will get pretty deep. Remember that when reading the
- +17 ;program for the first time and don't let it get you lost.
- +18 ;
- +19 ;When the records get created, they get put into different globals.
- +20 ;When allll of the records are created, we then take them out of
- +21 ;those globals and put them into ^ACHSDATA (the type 2 records are
- +22 ;already in that global.) This is done so that the final result
- +23 ;will be a list of all of the type 2s then all of the type 3s, then
- +24 ;all of the type 4s, etc.
- +25 ;
- +26 ;
- +27 ;Deciding which records get created is complicated. We have made it
- +28 ;as simple as possible, but it is still complicated. None of the
- +29 ;records get generated due to exactly the same set of circumstances.
- +30 ;Instead, the circumstances overlap in some places and not in others.
- +31 ;When the code comes to that part of it, this is explained further.
- +32 ;
- +33 ;These programs are written more for clarity than for expediancy. It
- +34 ;would be easy to make some some changes and save a few milliseconds,
- +35 ;but you would then not want to read the program.
- +36 ;
- +37 ;init some stuff. If it fails, quit
- +38 DO INIT
- IF STOP
- QUIT
- +39 ;
- +40 ;remove two lines for testing !!!!!
- +41 ;D EXPRT
- +42 ;I STOP Q
- +43 ;
- +44 ;
- +45 ;W @IOF,!,ACHS("*"),!?30,"EXPORT CHS DATA",!,ACHS("*"),!
- +46 ;
- +47 ;record the start and end dates FDT is first date, LDT is last date
- +48 ;S ACHSFDT=ACHSBDT,ACHSLDAT=ACHSEDT
- +49 ;
- +50 ;for test!!!!!
- +51 SET ACHSBDT=ACHSSBD
- SET ACHSEDT=ACHSSED
- +52 ;
- +53 ;for each day from start to end date, look for...
- +54 FOR
- SET ACHSBDT=$ORDER(^ACHSF(DUZ(2),"TB",ACHSBDT))
- IF ACHSBDT=""!(ACHSBDT>ACHSEDT)
- QUIT
- DO EXTRCT
- +55 ;
- +56 KILL DOLH,PMFCOUNT
- +57 QUIT
- +58 ;
- EXTRCT ;
- +1 ;if this is the first day, set record count to 0
- +2 IF ACHSRCT=0
- SET ACHSFDT=ACHSBDT
- +3 ;
- +4 ;for each transaction type except ZAs and IPs, do...
- +5 SET ACHSTY=""
- FOR
- SET ACHSTY=$ORDER(^ACHSF(DUZ(2),"TB",ACHSBDT,ACHSTY))
- IF ACHSTY=""
- QUIT
- IF ACHSTY'="ZA"
- IF (ACHSTY'="IP")
- DO EXTR2
- +6 QUIT
- +7 ;
- EXTR2 ;
- +1 ;for each document of this type on this day...
- +2 SET ACHSDIEN=0
- FOR
- SET ACHSDIEN=$ORDER(^ACHSF(DUZ(2),"TB",ACHSBDT,ACHSTY,ACHSDIEN))
- IF ACHSDIEN=""
- QUIT
- DO EXTR3
- +3 QUIT
- EXTR3 ;
- +1 ;go fetch the data on this document. if it's not okay, stop
- +2 DO ^ACHSDOCR
- IF 'OK
- QUIT
- +3 DO ^ACHSVNDR
- IF 'OK
- QUIT
- +4 ;
- +5 ;if this is a blanket order, stop
- +6 IF BLNKT=2
- DO KLL^ACHSDOCR
- DO KLL^ACHSVNDR
- QUIT
- +7 ;
- +8 ;now that we have document data build some other pieces
- +9 SET ACHSCTY=ACHSTY
- +10 SET ACHSDOCN="0"_$PIECE(ACHSDOCR,U,14)_ACHSFC_$EXTRACT($PIECE(ACHSDOCR,U)+100000,2,6)
- +11 ;
- +12 ;for each transaction within this trans type on the
- +13 ; document for today...
- +14 SET TNUM=0
- FOR
- SET TNUM=$ORDER(^ACHSF(DUZ(2),"TB",ACHSBDT,ACHSTY,ACHSDIEN,TNUM))
- IF TNUM=""
- QUIT
- DO EXTR4
- +15 DO KLL^ACHSDOCR
- DO KLL^ACHSVNDR
- +16 QUIT
- +17 ;
- EXTR4 ;EP from ACHSTX2R
- +1 ;
- +2 ;fo continuity with other programs, use DA for that last subscript
- +3 SET DA=TNUM
- +4 ;
- +5 ;for test
- +6 ;W !,ACHSBDT,?15,ACHSTY,?30,ACHSDIEN,?45,TNUM R YAYA
- +7 ;
- +8 IF $PIECE($HOROLOG,",",2)-TIME>3
- WRITE " ."
- SET TIME=$PIECE($HOROLOG,",",2)
- +9 ;
- +10 ;make sure that the transaction that "TB" is pointing to actually
- +11 ;exists
- +12 IF 'ACHSREEX
- IF '$DATA(^ACHSF(DUZ(2),"D",ACHSDIEN,"T",DA,0))
- KILL ^ACHSF(DUZ(2),"TB",ACHSBDT,ACHSTY,ACHSDIEN,DA)
- QUIT
- +13 ;
- +14 SET ACHSTRAN=^ACHSF(DUZ(2),"D",ACHSDIEN,"T",DA,0)
- +15 ;
- +16 ;get the initial payment amount and format it
- +17 SET ACHSIPA=$PIECE(^ACHSF(DUZ(2),"D",ACHSDIEN,"T",DA,0),U,4)
- +18 SET ACHSIPA=$PIECE(ACHSIPA,".",1)_$EXTRACT($PIECE(ACHSIPA,".",2)_"00",1,2)
- SET ACHSIPA=$EXTRACT(ACHSIPA+1000000000000,2,13)
- +19 ;
- +20 ;if the type is Cancel, don't use it. use the trans type instead
- +21 IF ACHSCTY="C"
- SET ACHSCTY=$PIECE(^ACHSF(DUZ(2),"D",ACHSDIEN,"T",DA,0),U,5)
- +22 ;
- +23 ;now decide if this document will generate some records.
- +24 ;each record type gets created or not based on several
- +25 ;parameters. Not all of the records use all of the
- +26 ;parameters, though. So there is OVERLAP in the way
- +27 ;records qualify, but it's a complicated pattern of
- +28 ;overlap. You will see it the the next programs called.
- +29 ;
- +30 ;
- +31 ;When we are done here, the transactions that got made will be
- +32 ;in various different globals.
- +33 ;Also, there will be an entry in ^ACHSXPRT that looks like this:
- +34 ;
- +35 ;^ACHSXPRT(ACHSDIEN,DA)=r2^r3^r4^r5^r6^r7
- +36 ;
- +37 ;where ACHSDIEN is the internal sequence number of the document
- +38 ; DA is the transaction subscript
- +39 ; rx is the action taken on the document for trans type x
- +40 ; for example, if r4 = "", we did not creat a type 4 trans
- +41 ; and we don't know why.
- +42 ; SHOULD NOT OCCUR.
- +43 ; if r5 = 0, that means a type 5 trans was created
- +44 ; a 0 ALWAYS means trans created.
- +45 ; if r3 = 17, then the trans was not created
- +46 ; for reason #17
- +47 ;
- +48 ;for test
- +49 SET SDA=DA
- +50 ;
- +51 ;
- +52 ;AFTER the export file is created, BUT NOT BEFORE, we take the info
- +53 ;in ^ACHSXPRT and record it in ^ACHSTXST for permanent storage.
- +54 ;
- +55 ;each of the routines we call expect ACHSDOCR and the standard
- +56 ;document variables, which are returned unchanged, and the
- +57 ;routines will return RET with their outcome
- +58 SET LIST=""
- FOR NUM=2:1:7
- SET ROUT="^ACHSTX"_NUM_NUM
- SET RET=""
- DO @ROUT
- SET $PIECE(LIST,U,NUM)=+RET
- +59 ;
- +60 ;SDA for test
- +61 SET ^ACHSXPRT(DOLRH,ACHSDIEN,SDA)=LIST
- KILL SDA
- +62 ;
- +63 QUIT
- +64 ;
- EXPRT ;
- +1 ;set up for exporting, as opposed to REexporting
- +2 ;
- +3 ;beginning date starts as the end date of the last export
- +4 SET P=$ORDER(^ACHSTXST(DUZ(2),1,""),-1)
- +5 IF P'=""
- SET ACHSBDT=$PIECE(^ACHSTXST(DUZ(2),1,P,0),U,3)
- +6 ;if there is no last export, set the start date to 1/1/1800
- +7 IF P=""
- SET ACHSBDT=1000101
- +8 ;
- +9 ;now get the ending date. There is no easy way to get it.
- +10 ;go through each child below the "AR" cross reference to get a
- +11 ;register number. then use that register number to see when it
- +12 ;was last closed - that's the "W" cross reference. As you get
- +13 ;each one, see if it's later than the end date you got and, if
- +14 ;it is, keep it.
- +15 ;
- +16 SET DA=9999998-DT-1
- FOR
- SET DA=$ORDER(^ACHS(9,DUZ(2),"FY",ACHSCFY,"AR",DA))
- IF DA=""!('DA)
- QUIT
- Begin DoDot:1
- +17 SET DCR=""
- FOR
- SET DCR=$ORDER(^ACHS(9,DUZ(2),"FY",ACHSCFY,"AR",DA,DCR))
- IF DCR=""!('DCR)
- QUIT
- Begin DoDot:2
- +18 SET DAT=$GET(^ACHS(9,DUZ(2),"FY",ACHSCFY,"W",DCR,0))
- +19 IF $PIECE(DAT,U,2)>ACHSEDT
- SET ACHSEDT=$PIECE(DAT,U,2)
- +20 QUIT
- End DoDot:2
- +21 QUIT
- End DoDot:1
- +22 KILL DAT,DCR
- +23 IF 'ACHSEDT
- WRITE !!,*7,*7,"DCR REGISTER ERROR YOU MUST CLOSE YOUR REGISTERS FIRST"
- DO RTRN^ACHS
- SET STOP=1
- QUIT
- +24 QUIT
- +25 ;
- INIT ;EP from ACHSTX2R
- +1 ;set up basic vars with default values and in other ways
- +2 ;get set to do this function
- +3 ;
- +4 ;S (ACHSDCR,ACHSEDT,ACHSBDT)=0,ACHSRR=""
- +5 ;
- +6 ;get the authorizing facility number. will be in one of two
- +7 ;places in the AUTTLOC global: either in the entry for this
- +8 ;facility, or in the entry for the area office facility. site
- +9 ;parm makes the difference
- +10 SET ACHSAFAC=$PIECE(^AUTTLOC(DUZ(2),0),U,10)
- +11 IF $$PARM^ACHS(2,25)="Y"
- SET ACHSAFAC=$PIECE(^ACHSF(DUZ(2),0),U,12)
- IF ACHSAFAC'=""
- SET ACHSAFAC=$PIECE($GET(^AUTTLOC(ACHSAFAC,0)),U,10)
- +12 ;if it's not set by now, tell them about it and stop
- +13 IF 'ACHSAFAC
- WRITE !!,*7,*7,"AUTHORIZING FACILITY CODE ERROR - JOB CANCELLED"
- SET STOP=1
- QUIT
- +14 ;
- +15 ;we use a couple of parms several times, including a busy loop, so
- +16 ;lets load them once and keep the values around. other parms we
- +17 ;just use once or twice
- +18 SET ACHSF209=$$PARM^ACHS(2,9)="Y"
- SET ACHSF211=$$PARM^ACHS(2,11)="Y"
- SET ACHSF212=$$PARM^ACHS(2,12)="Y"
- +19 ;
- +20 ;parm 2,9 says whether we are export statistical data or not.
- +21 ;if so, go get some object class codes
- +22 IF ACHSF209
- Begin DoDot:1
- +23 FOR ACHS="252F","254V"
- SET ACHS(ACHS)=$ORDER(^ACHS(3,DUZ(2),1,"B",ACHS,0))
- +24 ; if this is a 638 facility, get even more object class codes
- +25 IF ACHSF638="Y"
- FOR ACHS="252G","252R","254D","254L","254M"
- SET ACHS(ACHS)=$ORDER(^ACHS(3,DUZ(2),1,"B",ACHS,0))
- +26 QUIT
- End DoDot:1
- +27 ;
- +28 ;this array keeps track of how many records of each type we create.
- +29 ;init the counts to zero
- +30 FOR ACHS=2:1:7
- SET ACHSRTYP(ACHS)=0
- +31 ;
- +32 QUIT
- +33 ;