IBCE277	;ALB/TMP - 277 EDI CLAIM STATUS MESSAGE PROCESSING ;15-JUL-98
	;;2.0;INTEGRATED BILLING;**137,155,368**;21-MAR-94;Build 21
	;;Per VHA Directive 2004-038, this routine should not be modified.
	Q
	; MESSAGE HEADER DATA STRING =
	;   type of message^msg queue^msg #^bill #^REF NUM/Batch #^date/time
	;
HDR(ENTITY,ENTVAL,IBTYPE,IBD)	;Process header data
	; INPUT:
	;   ENTITY = "BATCH" or "CLAIM" for batch/claim level messages respectively
	;   ENTVAL = claim #
	;   IBTYPE = the type of status msg this piece of the message represents
	;             (837REC1, 837REJ1)
	;   ^TMP("IBMSGH",$J,0) = header message text
	;
	; OUTPUT:
	;   IBD array returned with processed data
	;      "DATE" = Date/Time of status (Fileman format)
	;      "MRA" =  1 if MRA, 0 if not         "X12" = 1 if X12, 0 if not
	;      "BATCH" = Batch ien for batch level calls
	;      "SOURCE" = Source of message code^source name, if known
	;
	;   ^TMP("IBMSG",$J,"BATCH",batch #,0)=MESSAGE HEADER DATA STRING
	;                                      if batch level message
	;                                  ,"D",0,1)=header record raw data
	;                                  ,line #)=batch status message lines
	;
	;   ^TMP("IBMSG",$J,"CLAIM",claim #,0)=MESSAGE HEADER DATA STRING
	;                                      if claim level message
	;                                  ,"D",0,1)=header record raw data
	;                                  ,line #)=claim status message lines
	;
	N DATA,IBD0,L,PC,X,Y
	S IBD0=$G(^TMP("IBMSGH",$J,0)) Q:IBD0=""
	S Y=0,L=1
	; Convert claim date/time
	S X=$$DATE($P(IBD0,U,3))_"@"_$E($P(IBD0,U,4)_"0000",1,4) I X S %DT="XTS" D ^%DT
	; populate IBD array
	S IBD("DATE")=$S(Y>0:Y,1:""),IBD("MRA")=$P(IBD0,U,5),IBD("X12")=($P(IBD0,U,2)="X")
	S IBD("SOURCE")=$P(IBD0,U,12,13),IBD("BATCH")=$P(IBD0,U,14)
	I +$TR($P(IBD0,U,6,9),U) F PC=6:1:9 D
	.I $P(IBD0,U,PC)'="" S DATA=$P("# Claims Submitted^# Claims Rejected^Total Charges Submitted^Total Charges Rejected",U,PC-5)_": "_$S(PC<8:+$P(IBD0,U,PC),1:$FNUMBER($P(IBD0,U,PC)/100,"",2))_"  "
	.I $L($G(^TMP("IBMSG-H",$J,ENTITY,ENTVAL,L)))+$L(DATA)>70 S L=L+1 ; if data doesn't fit into current line, go to the next line
	.S ^TMP("IBMSG-H",$J,ENTITY,ENTVAL,L)=$G(^TMP("IBMSG-H",$J,ENTITY,ENTVAL,L))_DATA ; file this piece of data
	.Q
	; file batch ref. number
	S:IBD("BATCH")'="" L=L+1,^TMP("IBMSG-H",$J,ENTITY,ENTVAL,L)="Batch Reference Number: "_IBD("BATCH")
	I $TR($P(IBD0,U,10,13),U)'="" D
	.S L=L+1
	.; generate and file Payer Name / Payer Id line
	.S DATA="Payer Name: "_$S($P(IBD0,U,10)'="":$P(IBD0,U,10),1:"N/A")_"  Payer ID: "_$S($P(IBD0,U,11)'="":$P(IBD0,U,11),1:"N/A")
	.S ^TMP("IBMSG-H",$J,ENTITY,ENTVAL,L)=DATA
	.I $P(IBD0,U,12)'=""!($P(IBD0,U,13)'="") D
	..; generate and file Message Source line
	..S DATA="Source: "_$S($P(IBD0,U,12)="Y":"Sent by payer",$P(IBD0,U,13)'="":"Sent by non-payer ("_$P(IBD0,U,13)_")",1:"UNKNOWN")
	..S L=L+1,^TMP("IBMSG-H",$J,ENTITY,ENTVAL,L)=DATA
	..Q
	.Q
	S ^TMP("IBMSG",$J,ENTITY,ENTVAL,0)=IBTYPE_U_$G(IBD("MSG#"))_U_$G(IBD("SUBJ"))_U_$$GETBILL(ENTVAL)_U_U_IBD("DATE")_U_IBD("SOURCE")
	; file raw data
	S ^TMP("IBMSG",$J,ENTITY,ENTVAL,"D",0,1)="##RAW DATA: "_IBD0
	Q
	;
9(IBD)	; Process Message Header record
	; INPUT:
	;   IBD must be passed by reference = entire message line
	; OUTPUT:
	;   IBD array returned with processed data
	;      "CLAIM" = claim #
	;      "LINE" = last line # populated in the message
	;
	;   ^TMP("IBMSG",$J,"CLAIM",claim #,line#)= message data lines
	;                                  ,"D",9,msg seq #)= raw data
	N ENTITY,ERR,FLD,IBCLM,IBIFN,L
	D STRTREC Q:IBCLM=""  ; if no claim/batch number, bail out
	; make sure that we have data to file
	S ERR=$P(IBD,U,4) Q:ERR=""
	; file error along with corresponding field number (if available)
	S L=L+1,FLD=$P(IBD,U,5),^TMP("IBMSG",$J,ENTITY,IBCLM,L)="Error"_$S(FLD'="":" in field "_FLD,1:"")_":"
	S L=L+1,^TMP("IBMSG",$J,ENTITY,IBCLM,L)=ERR
	D ENDREC(9)
	Q
	;
10(IBD)	; Process message data
	; INPUT:
	;   IBD must be passed by reference = entire message line
	; OUTPUT:
	;   IBD array returned with processed data
	;      "CLAIM" = claim #
	;      "LINE" = last line # populated in the message
	;
	;   ^TMP("IBMSG",$J,"CLAIM",claim #,line#)= message data lines
	;                                  ,"D",10,msg seq #)= raw data
	;   ^TMP("IBCONF",$J,claim #")="" for invalid claims within the batch
	;
	N CODE,DATA,ENTITY,IBCLM,IBIFN,IBTYPE,L,Z
	D STRTREC Q:IBCLM=""  ; if no claim number, bail out
	S:$P(IBD,U,3)="R" ^TMP("IBCONF",$J,IBIFN)=""
	S IBTYPE=$S($P(IBD,U,3)="R":"837REJ1",1:"837REC1")
	;Process header data if not already done
	I '$D(^TMP("IBMSG",$J,ENTITY,IBCLM,0)) D HDR(ENTITY,IBCLM,IBTYPE,.IBD)
	I IBTYPE="837REJ1",$P($G(^TMP("IBMSG",$J,ENTITY,IBCLM,0)),U,1)'="837REJ1" D HDR(ENTITY,IBCLM,IBTYPE,.IBD)
	S CODE=$P(IBD,U,4) I CODE'="",$TR($P(IBD,U,5,6),U)'="" D
	.S Z=CODE_$P(IBD,U,5) I Z'=$G(IBD("SCODE")) D
	..; determine type of status code and file it
	..S L=L+1,DATA=$S(CODE="W":"Warning",CODE="E":"Error",1:"Informational")_" "
	..I $P(IBD,U,5)'="" S ^TMP("IBMSG",$J,ENTITY,IBCLM,L)=DATA_"Code: "_$P(IBD,U,5)
	..I $P(IBD,U,6)'="" S:$P(IBD,U,5)'="" L=L+1 S ^TMP("IBMSG",$J,ENTITY,IBCLM,L)=DATA_"Message:",L=L+1
	..S IBD("SCODE")=Z
	..Q
	.; file status message
	.I $P(IBD,U,6)'="" S ^TMP("IBMSG",$J,ENTITY,IBCLM,L)=$P(IBD,U,6),L=L+1,^TMP("IBMSG",$J,ENTITY,IBCLM,L)=" "
	.Q
	D ENDREC(10)
	Q
	;
13(IBD)	; Process claim data
	; Claim must have been referenced by a previous '10' level
	; INPUT:
	;   IBD must be passed by reference = entire message line
	;
	; OUTPUT:
	;      IBD("LINE") = The last line # populated in the message
	;
	;     ^TMP("IBMSG",$J,"CLAIM",claim #,line#)=claim data lines
	;                                    ,"D",13,msg seq #)=raw data
	;
	N CTYPE,ENTITY,IBCLM,IBIFN,L,Z1,Z2
	D STRTREC
	; quit if no claim number or no previous 'line 10' record
	Q:$S(IBCLM="":1,1:'$D(^TMP("IBMSG",$J,"CLAIM",IBCLM)))
	; file clearinghouse trace number
	I $P(IBD,U,3)'="" S L=L+1,^TMP("IBMSG",$J,ENTITY,IBCLM,L)="Clearinghouse Trace Number: "_$P(IBD,U,3)
	; file payer status date
	I $P(IBD,U,4)'="" S L=L+1,^TMP("IBMSG",$J,ENTITY,IBCLM,L)="         Payer Status Date: "_$$DATE($P(IBD,U,4))
	; file payer claim number
	I $P(IBD,U,5)'="" S L=L+1,^TMP("IBMSG",$J,ENTITY,IBCLM,L)="        Payer Claim Number: "_$P(IBD,U,5)
	; file split claim indicator
	I +$P(IBD,U,6)'=0 S L=L+1,^TMP("IBMSG",$J,ENTITY,IBCLM,L)="               Split Claim: "_$S(+$P(IBD,U,6)=1:"No",1:"Yes ("_+$P(IBD,U,6)_" parts)")
	; file claim type if it either doesn't match value in VistA or if it's a dental claim
	S Z1=$P(IBD,U,7),Z2=$$FT^IBCEF(IBIFN),CTYPE=$S(Z1="P"&(Z2'=2):"Professional",Z1="I"&(Z2'=3):"Institutional",Z1="D":"Dental",1:"")
	S:CTYPE'="" L=L+1,^TMP("IBMSG",$J,ENTITY,IBCLM,L)="                Claim Type: "_CTYPE
	D ENDREC(13)
	Q
	;
15(IBD)	; Process subscriber/patient data
	; Claim must have been referenced by a previous '10' level
	; INPUT:
	;   IBD must be passed by reference = entire message line
	;
	; OUTPUT:
	;      IBD("LINE") = The last line # populated in the message
	;
	;     ^TMP("IBMSG",$J,"CLAIM",claim #,line#)=formatted service dates
	;                                    ,"D",15,msg seq #)=
	;                                         subscr/patient raw data
	;
	N ENTITY,DATA,IBCLM,IBIFN,IBNM,IBNUM,IBDFN,L
	D STRTREC
	; quit if no claim number or no previous 'line 10' record
	Q:$S(IBCLM="":1,1:'$D(^TMP("IBMSG",$J,"CLAIM",IBCLM)))
	S IBDFN=+$P(^DGCR(399,IBIFN,0),U,2)
	S IBNM=$S($P(IBD,U,3)'="":$P(IBD,U,3)_","_$P(IBD,U,4)_$S($P(IBD,U,5)'="":" "_$P(IBD,U,5),1:""),1:$P($G(^DPT(IBDFN,0)),U))
	S IBNUM=$S($P(IBD,U,6)'="":$P(IBD,U,6),1:$P($G(^DPT(IBDFN,0)),U,9))
	S L=L+1,^TMP("IBMSG",$J,ENTITY,IBCLM,L)="Patient: "_IBNM_"   "_IBNUM
	I $P(IBD,U,11) D
	.S DATA=$$DATE($P(IBD,U,11)),L=L+1
	.S ^TMP("IBMSG",$J,ENTITY,IBCLM,L)="Service Dates: "_DATA_" - "_$S($P(IBD,U,12):$$DATE($P(IBD,U,12)),1:DATA)
	.Q
	D ENDREC(15)
	Q
	;
STRTREC	; start processing of the record
	;           
	; OUTPUT:
	;   sets the following variables
	;   IBCLM = claim #
	;   ENTITY = "CLAIM" (all 277STAT messages are on claim level)
	;   L = last populated line number
	;
	S IBCLM=$$GETCLM($P(IBD,U,2)),ENTITY="CLAIM",L=+$G(IBD("LINE"))
	S IBIFN=+$O(^DGCR(399,"B",IBCLM,0))
	Q
	;
ENDREC(TYPE)	; finish processing of the record
	; INPUT:
	;   TYPE = record type (line type)
	;   
	; OUTPUT:
	;   IBD("LINE") = is updated with last populated line number
	;
	;make sure all variables are set properly
	Q:$G(ENTITY)=""
	Q:$G(IBCLM)=""
	Q:$G(TYPE)=""
	; file raw data
	S ^TMP("IBMSG",$J,ENTITY,IBCLM,"D",TYPE,$O(^TMP("IBMSG",$J,ENTITY,IBCLM,"D",TYPE,""),-1)+1)="##RAW DATA: "_IBD
	; update line count
	S IBD("LINE")=$G(IBD("LINE"))+L
	Q
	;
GETBILL(CLAIM)	; Extract transmission #
	N TRANS
	S TRANS=$$LAST364^IBCEF4(IBIFN)
	; if status of the last transmission is "X" or "P", keep searching backwards through file 364 until record
	; with different status is found
	I TRANS F  Q:"XP"'[$P(^IBA(364,TRANS,0),U,3)  S TRANS=$O(^IBA(364,"B",IBIFN,TRANS),-1) Q:TRANS=""  ;
	Q +TRANS
	;
DATE(DT)	; Convert YYMMDD Date into MM/DD/YY or YYYYMMDD into MM/DD/YYYY
	N D,Y
	S D=DT,Y=""
	I $L(DT)=8 S D=$E(DT,3,8),Y=$E(DT,1,2)
	Q ($E(D,3,4)_"/"_$E(D,5,6)_"/"_Y_$E(D,1,2))
	;
GETCLM(X)	; Extract the claim # without site id from the data in X
	N IBCLM
	S IBCLM=$P(X,"-",2) I IBCLM="",X'="" S IBCLM=$E(X,$S($L(X)>7:4,1:1),$L(X))
	Q IBCLM
	;
