ABSPOSP2 ; IHS/FCS/DRS - EOB to Payments Batch ; [ 09/12/2002 10:17 AM ]
;;1.0;PHARMACY POINT OF SALE;**3**;JUN 21, 2001;Build 38
; Payments & Adjustments - ScreenMan front-end to create batch
; with parameters to assemble what should match the EOB.
I DUZ(0)="@" W "Going to the TEST entry point..." H 2 G TEST
Q
;
MAIN ;EP - option ABSP EOB TO BATCH
Q:$$MUSTILC^ABSPOSB
N X D
. N LOCKREF S LOCKREF="^ABSP(9002313.99,1,""EOB-SCREEN"")"
. L +@LOCKREF:0 I '$T D S X="" Q
. . W "Someone else is using the EOB program.",!
. S X=$$MYSCREEN
. I X S X=$G(^ABSP(9002313.99,1,"EOB-SCREEN"))
. E S X=""
. L -@LOCKREF
I X="" W "Nothing done",! H 2 Q ; didn't get <F1>E
N PARAMS M PARAMS=^ABSP(9002313.99,1,"EOB-SCREEN")
;
N ROU S ROU=$T(+0)
;
; Build ^TMP($J,ROU,1,pt9002313.02,pt9002313.03)=""
;
W !,"Please wait... searching our records of POS payments...",!
D SEARCH
;
; Build ^TMP($J,ROU,2,PATNAME,DATERECD,RXI,RXR,pt9002313.02,position)
; = amount paid^pt9002313.03
; This is to mimic the order of the EOB.
; We may need to do different sort orders for different insurers.
;
W !,"Now sorting the payment records...",!
D SORT
;
W "Creating a payments batch...",!
N BATCH S BATCH=$$NEWBATCH^ABSPOSP(1)
I 'BATCH W "Can't create a batch - Stopping",! Q
W "The batch is payment batch #",BATCH,!
N PATNAME,DATERECD,RXI,RXR,CLAIM,POSITN,DATA,AMT,RESP
S PATNAME=""
F S PATNAME=$O(^TMP($J,ROU,2,PATNAME)) Q:PATNAME="" D
. S DATERECD=""
. F S DATERECD=$O(^TMP($J,ROU,2,PATNAME,DATERECD)) Q:DATERECD="" D
. . S RXI=""
. . F S RXI=$O(^TMP($J,ROU,2,PATNAME,DATERECD,RXI)) Q:RXI="" D
. . . S RXR=""
. . . F S RXR=$O(^TMP($J,ROU,2,PATNAME,DATERECD,RXI,RXR)) Q:RXR="" D
. . . . S CLAIM=""
. . . . F S CLAIM=$O(^TMP($J,ROU,2,PATNAME,DATERECD,RXI,RXR,CLAIM)) Q:CLAIM="" D
. . . . . S POSITN=""
. . . . . F S POSITN=$O(^TMP($J,ROU,2,PATNAME,DATERECD,RXI,RXR,CLAIM,POSITN)) Q:POSITN="" D
. . . . . . S DATA=^TMP($J,ROU,2,PATNAME,DATERECD,RXI,RXR,CLAIM,POSITN)
. . . . . . D ONEPMT
I $P(PARAMS,U,5) D ; control total
. ; Note: do it here at the end - because individual transactions
. ; each added to total (in ABSPOSP). But if '$P(PARAMS,U,5),
. ; then user must not have entered a control total - so just take
. ; the total of transactions as ABSPOSP tallied them.
. D SETAMT^ABSPOSP(BATCH,$P(PARAMS,U,5),.04)
W "Done",!!
W "Note: the batch is still open; it is not automatically posted.",!
W "You are responsible for making sure that you really want",!
W "to post the batch and that the control total is correct.",!
D PRESSANY^ABSPOSU5()
Q
ONEPMT ;
N PCNDFN S PCNDFN=$P(^ABSPC(CLAIM,0),U,3)
N AMT S AMT=$P(DATA,U)
N DEPDATE S DEPDATE=$P(PARAMS,U,4)
N INSDFN S INSDFN=$P(PARAMS,U)
I 'PCNDFN D Q ; no PCNDFN?! Put it into unallocated cash
. W "Unallocated Cash $",$J(AMT,0,2)," for ",PATNAME,!
. W ?10,"See Claim ID ",$P(^ABSPC(CLAIM,0),U),!
. S ^ABSTMP(BATCH,"UC")=$G(^ABSTMP(BATCH,"UC"))+AMT
. ; and you want to put an entry in ^ABSBUC()
D PAYMENT^ABSPOSP(PCNDFN,BATCH,AMT,INSDFN,DEPDATE)
Q
SORT K ^TMP($J,ROU,2)
N PATNAME,DATERECD,RXI,RXR,CLAIM,RESP
S CLAIM=0
F S CLAIM=$O(^TMP($J,ROU,1,CLAIM)) Q:'CLAIM D
. I $$ISREVERS^ABSPOSU(CLAIM) Q ; reversal - elsewhere
. S RESP=0
. F S RESP=$O(^TMP($J,ROU,1,CLAIM,RESP)) Q:'RESP D SORT1
Q
SORT1 ;
I $$RESP500^ABSPOSQ4(RESP,"I")'="A" Q ; header not accepted
S PATNAME=$P(^ABSPC(CLAIM,1),U)
S DATERECD=$P(^ABSPR(RESP,0),U,2)
S DATERECD=$P(DATERECD,".")
N POSITN S POSITN=0
F S POSITN=$O(^ABSPR(RESP,1000,POSITN)) Q:'POSITN D
. I $$RESP1000^ABSPOSQ4(RESP,POSITN,"I")'="P" Q ; only if Payable
. ; RXI, RXR as fetched here:
. ; * They should already be in the EOB's format
. ; * The RXR does not necessarily correspond to the index into
. ; the multiple in ^PSRX(+RXI,1,...)
. S RXI=$P(^ABSPC(CLAIM,400,POSITN,400),U,2)
. S RXR=$P(^ABSPC(CLAIM,400,POSITN,400),U,3)
. N X S X=^ABSPR(RESP,1000,POSITN,500)
. N AMT S AMT("PATIENT")=$P(X,U,5)
. S AMT("INGR")=$P(X,U,6),AMT("DISPFEE")=$P(X,U,7)
. S AMT("TAX")=$P(X,U,8),AMT("TOT")=$P(X,U,9),AMT("COPAY")=$P(X,U,18)
. S AMT("INCENT")=$P(X,U,21)
. ; convert signed overpunch numeric mess
. N X S X="" F S X=$O(AMT(X)) Q:X="" I AMT(X)]"",AMT(X)'?1N.N D
. . S AMT(X)=$$DFF2EXT^ABSPECFM(AMT(X))
. ; Assemble data value
. ; we have lots of AMT(*) available; let's go with total amt. for now
. N DATA S DATA=AMT("TOT")_U_RESP
. ; Store it!
. ; But not if the claim was reversed in this same time frame
. I $$SUCCREV D Q
. . ;W "TEMP - ",CLAIM," was successfully reversed by ",$$SUCCREV,!
. S ^TMP($J,ROU,2,PATNAME,DATERECD,RXI,RXR,CLAIM,POSITN)=DATA
Q
SUCCREV() ; was the CLAIM,POSITN in 9002313.02 successfully reversed, ever?
; return pointer to 9002313.02 reversal claim if it was
N CLAIMID S CLAIMID=$P(^ABSPC(CLAIM,0),U)
N REVID S REVID=CLAIMID_"R"_POSITN
N REVCLAIM S REVCLAIM=0
N RETVAL S RETVAL=0 ; assume No
; In most cases, this For loop body never runs,
; because reversals are relatively uncommon.
; And when it does run, instances of multiple responses should
; never really happen, but if they do, just take latest response.
; Conceivable only if the reversal was attempted when the
; host was down?
F S REVCLAIM=$O(^ABSPC("B",REVID,REVCLAIM)) Q:'REVCLAIM D
. ; In oddball case of multiple responses to this claim, take latest
. N REVRESP S REVRESP=$O(^ABSPR("B",REVCLAIM,""),-1)
. I 'REVRESP Q ; got no response? oh well
. ; accepted reversal? you tell by whether header was accepted.
. I $$RESP500^ABSPOSQ4(REVRESP,"I")="A" S RETVAL=REVCLAIM
Q RETVAL
SEARCH K ^TMP($J,ROU,1)
N INSURER S INSURER=$P(PARAMS,U)
N START S START=$P(PARAMS,U,2)
N END S END=$P(PARAMS,U,3)
I $P(END,".",2)="" S $P(END,".",2)="99999999" ; default to entire day
N DATE S DATE=START
F D S DATE=$O(^ABSPR("AE",DATE)) Q:DATE>END
. N RESP S RESP=0
. F S RESP=$O(^ABSPR("AE",DATE,RESP)) Q:'RESP D
. . N CLAIM S CLAIM=$P(^ABSPR(RESP,0),U) Q:'CLAIM
. . I $P(^ABSPC(CLAIM,0),U,2)'=INSURER Q
. . ;
. . ; Yes - the response is from this insurer for this date.
. . ;
. . S ^TMP($J,ROU,1,CLAIM,RESP)=""
Q
MYSCREEN() ; returns 1 if <F1>E (or the equivalent) was used
; if the user quits out (<F1>Q or the equivalent), returns 0
N DDSFILE,DR,DDSPAGE,DDSPARM
N DDSCHANG,DDSSAVE,DIMSG,DTOUT
N DA
S DDSFILE=9002313.99,DA=1
S DR="[ABSP EOB TO BATCH]"
AA S DDSPARM="CS"
D ^DDS
Q:'$Q
I $G(DDSSAVE) Q 1
E Q 0
TEST ;
W "Just GOTO MAIN",! H 1
G MAIN
W "Outputs:",!
D ZWRITE^ABSPOS("DDSCHANG","DDSSAVE","DIMSG","DTOUT")
N X S X=$G(^ABSP(9002313.99,1,"EOB-SCREEN"))
W "9002313.99,EOB-SCREEN node=",X,!
Q
ABSPOSP2 ; IHS/FCS/DRS - EOB to Payments Batch ; [ 09/12/2002 10:17 AM ]
+1 ;;1.0;PHARMACY POINT OF SALE;**3**;JUN 21, 2001;Build 38
+2 ; Payments & Adjustments - ScreenMan front-end to create batch
+3 ; with parameters to assemble what should match the EOB.
+4 IF DUZ(0)="@"
WRITE "Going to the TEST entry point..."
HANG 2
GOTO TEST
+5 QUIT
+6 ;
MAIN ;EP - option ABSP EOB TO BATCH
+1 IF $$MUSTILC^ABSPOSB
QUIT
+2 NEW X
Begin DoDot:1
+3 NEW LOCKREF
SET LOCKREF="^ABSP(9002313.99,1,""EOB-SCREEN"")"
+4 LOCK +@LOCKREF:0
IF '$TEST
Begin DoDot:2
+5 WRITE "Someone else is using the EOB program.",!
End DoDot:2
SET X=""
QUIT
+6 SET X=$$MYSCREEN
+7 IF X
SET X=$GET(^ABSP(9002313.99,1,"EOB-SCREEN"))
+8 IF '$TEST
SET X=""
+9 LOCK -@LOCKREF
End DoDot:1
+10 ; didn't get <F1>E
IF X=""
WRITE "Nothing done",!
HANG 2
QUIT
+11 NEW PARAMS
MERGE PARAMS=^ABSP(9002313.99,1,"EOB-SCREEN")
+12 ;
+13 NEW ROU
SET ROU=$TEXT(+0)
+14 ;
+15 ; Build ^TMP($J,ROU,1,pt9002313.02,pt9002313.03)=""
+16 ;
+17 WRITE !,"Please wait... searching our records of POS payments...",!
+18 DO SEARCH
+19 ;
+20 ; Build ^TMP($J,ROU,2,PATNAME,DATERECD,RXI,RXR,pt9002313.02,position)
+21 ; = amount paid^pt9002313.03
+22 ; This is to mimic the order of the EOB.
+23 ; We may need to do different sort orders for different insurers.
+24 ;
+25 WRITE !,"Now sorting the payment records...",!
+26 DO SORT
+27 ;
+28 WRITE "Creating a payments batch...",!
+29 NEW BATCH
SET BATCH=$$NEWBATCH^ABSPOSP(1)
+30 IF 'BATCH
WRITE "Can't create a batch - Stopping",!
QUIT
+31 WRITE "The batch is payment batch #",BATCH,!
+32 NEW PATNAME,DATERECD,RXI,RXR,CLAIM,POSITN,DATA,AMT,RESP
+33 SET PATNAME=""
+34 FOR
SET PATNAME=$ORDER(^TMP($JOB,ROU,2,PATNAME))
IF PATNAME=""
QUIT
Begin DoDot:1
+35 SET DATERECD=""
+36 FOR
SET DATERECD=$ORDER(^TMP($JOB,ROU,2,PATNAME,DATERECD))
IF DATERECD=""
QUIT
Begin DoDot:2
+37 SET RXI=""
+38 FOR
SET RXI=$ORDER(^TMP($JOB,ROU,2,PATNAME,DATERECD,RXI))
IF RXI=""
QUIT
Begin DoDot:3
+39 SET RXR=""
+40 FOR
SET RXR=$ORDER(^TMP($JOB,ROU,2,PATNAME,DATERECD,RXI,RXR))
IF RXR=""
QUIT
Begin DoDot:4
+41 SET CLAIM=""
+42 FOR
SET CLAIM=$ORDER(^TMP($JOB,ROU,2,PATNAME,DATERECD,RXI,RXR,CLAIM))
IF CLAIM=""
QUIT
Begin DoDot:5
+43 SET POSITN=""
+44 FOR
SET POSITN=$ORDER(^TMP($JOB,ROU,2,PATNAME,DATERECD,RXI,RXR,CLAIM,POSITN))
IF POSITN=""
QUIT
Begin DoDot:6
+45 SET DATA=^TMP($JOB,ROU,2,PATNAME,DATERECD,RXI,RXR,CLAIM,POSITN)
+46 DO ONEPMT
End DoDot:6
End DoDot:5
End DoDot:4
End DoDot:3
End DoDot:2
End DoDot:1
+47 ; control total
IF $PIECE(PARAMS,U,5)
Begin DoDot:1
+48 ; Note: do it here at the end - because individual transactions
+49 ; each added to total (in ABSPOSP). But if '$P(PARAMS,U,5),
+50 ; then user must not have entered a control total - so just take
+51 ; the total of transactions as ABSPOSP tallied them.
+52 DO SETAMT^ABSPOSP(BATCH,$PIECE(PARAMS,U,5),.04)
End DoDot:1
+53 WRITE "Done",!!
+54 WRITE "Note: the batch is still open; it is not automatically posted.",!
+55 WRITE "You are responsible for making sure that you really want",!
+56 WRITE "to post the batch and that the control total is correct.",!
+57 DO PRESSANY^ABSPOSU5()
+58 QUIT
ONEPMT ;
+1 NEW PCNDFN
SET PCNDFN=$PIECE(^ABSPC(CLAIM,0),U,3)
+2 NEW AMT
SET AMT=$PIECE(DATA,U)
+3 NEW DEPDATE
SET DEPDATE=$PIECE(PARAMS,U,4)
+4 NEW INSDFN
SET INSDFN=$PIECE(PARAMS,U)
+5 ; no PCNDFN?! Put it into unallocated cash
IF 'PCNDFN
Begin DoDot:1
+6 WRITE "Unallocated Cash $",$JUSTIFY(AMT,0,2)," for ",PATNAME,!
+7 WRITE ?10,"See Claim ID ",$PIECE(^ABSPC(CLAIM,0),U),!
+8 SET ^ABSTMP(BATCH,"UC")=$GET(^ABSTMP(BATCH,"UC"))+AMT
+9 ; and you want to put an entry in ^ABSBUC()
End DoDot:1
QUIT
+10 DO PAYMENT^ABSPOSP(PCNDFN,BATCH,AMT,INSDFN,DEPDATE)
+11 QUIT
SORT KILL ^TMP($JOB,ROU,2)
+1 NEW PATNAME,DATERECD,RXI,RXR,CLAIM,RESP
+2 SET CLAIM=0
+3 FOR
SET CLAIM=$ORDER(^TMP($JOB,ROU,1,CLAIM))
IF 'CLAIM
QUIT
Begin DoDot:1
+4 ; reversal - elsewhere
IF $$ISREVERS^ABSPOSU(CLAIM)
QUIT
+5 SET RESP=0
+6 FOR
SET RESP=$ORDER(^TMP($JOB,ROU,1,CLAIM,RESP))
IF 'RESP
QUIT
DO SORT1
End DoDot:1
+7 QUIT
SORT1 ;
+1 ; header not accepted
IF $$RESP500^ABSPOSQ4(RESP,"I")'="A"
QUIT
+2 SET PATNAME=$PIECE(^ABSPC(CLAIM,1),U)
+3 SET DATERECD=$PIECE(^ABSPR(RESP,0),U,2)
+4 SET DATERECD=$PIECE(DATERECD,".")
+5 NEW POSITN
SET POSITN=0
+6 FOR
SET POSITN=$ORDER(^ABSPR(RESP,1000,POSITN))
IF 'POSITN
QUIT
Begin DoDot:1
+7 ; only if Payable
IF $$RESP1000^ABSPOSQ4(RESP,POSITN,"I")'="P"
QUIT
+8 ; RXI, RXR as fetched here:
+9 ; * They should already be in the EOB's format
+10 ; * The RXR does not necessarily correspond to the index into
+11 ; the multiple in ^PSRX(+RXI,1,...)
+12 SET RXI=$PIECE(^ABSPC(CLAIM,400,POSITN,400),U,2)
+13 SET RXR=$PIECE(^ABSPC(CLAIM,400,POSITN,400),U,3)
+14 NEW X
SET X=^ABSPR(RESP,1000,POSITN,500)
+15 NEW AMT
SET AMT("PATIENT")=$PIECE(X,U,5)
+16 SET AMT("INGR")=$PIECE(X,U,6)
SET AMT("DISPFEE")=$PIECE(X,U,7)
+17 SET AMT("TAX")=$PIECE(X,U,8)
SET AMT("TOT")=$PIECE(X,U,9)
SET AMT("COPAY")=$PIECE(X,U,18)
+18 SET AMT("INCENT")=$PIECE(X,U,21)
+19 ; convert signed overpunch numeric mess
+20 NEW X
SET X=""
FOR
SET X=$ORDER(AMT(X))
IF X=""
QUIT
IF AMT(X)]""
IF AMT(X)'?1N.N
Begin DoDot:2
+21 SET AMT(X)=$$DFF2EXT^ABSPECFM(AMT(X))
End DoDot:2
+22 ; Assemble data value
+23 ; we have lots of AMT(*) available; let's go with total amt. for now
+24 NEW DATA
SET DATA=AMT("TOT")_U_RESP
+25 ; Store it!
+26 ; But not if the claim was reversed in this same time frame
+27 IF $$SUCCREV
Begin DoDot:2
+28 ;W "TEMP - ",CLAIM," was successfully reversed by ",$$SUCCREV,!
End DoDot:2
QUIT
+29 SET ^TMP($JOB,ROU,2,PATNAME,DATERECD,RXI,RXR,CLAIM,POSITN)=DATA
End DoDot:1
+30 QUIT
SUCCREV() ; was the CLAIM,POSITN in 9002313.02 successfully reversed, ever?
+1 ; return pointer to 9002313.02 reversal claim if it was
+2 NEW CLAIMID
SET CLAIMID=$PIECE(^ABSPC(CLAIM,0),U)
+3 NEW REVID
SET REVID=CLAIMID_"R"_POSITN
+4 NEW REVCLAIM
SET REVCLAIM=0
+5 ; assume No
NEW RETVAL
SET RETVAL=0
+6 ; In most cases, this For loop body never runs,
+7 ; because reversals are relatively uncommon.
+8 ; And when it does run, instances of multiple responses should
+9 ; never really happen, but if they do, just take latest response.
+10 ; Conceivable only if the reversal was attempted when the
+11 ; host was down?
+12 FOR
SET REVCLAIM=$ORDER(^ABSPC("B",REVID,REVCLAIM))
IF 'REVCLAIM
QUIT
Begin DoDot:1
+13 ; In oddball case of multiple responses to this claim, take latest
+14 NEW REVRESP
SET REVRESP=$ORDER(^ABSPR("B",REVCLAIM,""),-1)
+15 ; got no response? oh well
IF 'REVRESP
QUIT
+16 ; accepted reversal? you tell by whether header was accepted.
+17 IF $$RESP500^ABSPOSQ4(REVRESP,"I")="A"
SET RETVAL=REVCLAIM
End DoDot:1
+18 QUIT RETVAL
SEARCH KILL ^TMP($JOB,ROU,1)
+1 NEW INSURER
SET INSURER=$PIECE(PARAMS,U)
+2 NEW START
SET START=$PIECE(PARAMS,U,2)
+3 NEW END
SET END=$PIECE(PARAMS,U,3)
+4 ; default to entire day
IF $PIECE(END,".",2)=""
SET $PIECE(END,".",2)="99999999"
+5 NEW DATE
SET DATE=START
+6 FOR
Begin DoDot:1
+7 NEW RESP
SET RESP=0
+8 FOR
SET RESP=$ORDER(^ABSPR("AE",DATE,RESP))
IF 'RESP
QUIT
Begin DoDot:2
+9 NEW CLAIM
SET CLAIM=$PIECE(^ABSPR(RESP,0),U)
IF 'CLAIM
QUIT
+10 IF $PIECE(^ABSPC(CLAIM,0),U,2)'=INSURER
QUIT
+11 ;
+12 ; Yes - the response is from this insurer for this date.
+13 ;
+14 SET ^TMP($JOB,ROU,1,CLAIM,RESP)=""
End DoDot:2
End DoDot:1
SET DATE=$ORDER(^ABSPR("AE",DATE))
IF DATE>END
QUIT
+15 QUIT
MYSCREEN() ; returns 1 if <F1>E (or the equivalent) was used
+1 ; if the user quits out (<F1>Q or the equivalent), returns 0
+2 NEW DDSFILE,DR,DDSPAGE,DDSPARM
+3 NEW DDSCHANG,DDSSAVE,DIMSG,DTOUT
+4 NEW DA
+5 SET DDSFILE=9002313.99
SET DA=1
+6 SET DR="[ABSP EOB TO BATCH]"
AA SET DDSPARM="CS"
+1 DO ^DDS
+2 IF '$QUIT
QUIT
+3 IF $GET(DDSSAVE)
QUIT 1
+4 IF '$TEST
QUIT 0
TEST ;
+1 WRITE "Just GOTO MAIN",!
HANG 1
+2 GOTO MAIN
+3 WRITE "Outputs:",!
+4 DO ZWRITE^ABSPOS("DDSCHANG","DDSSAVE","DIMSG","DTOUT")
+5 NEW X
SET X=$GET(^ABSP(9002313.99,1,"EOB-SCREEN"))
+6 WRITE "9002313.99,EOB-SCREEN node=",X,!
+7 QUIT