BPSOSQ2 ;BHAM ISC/FCS/DRS/DLF - form transmission packets ;06/01/2004
 ;;1.0;E CLAIMS MGMT ENGINE;**1,5,7,10**;JUN 2004;Build 27
 ;;Per VHA Directive 2004-038, this routine should not be modified.
 ; Construct packets for transmission
 Q
 ;
PACKETS ; EP - Tasked by BPSOSQA
 ;
 ; First handle insurer alseep transactions
 I $D(^BPST("AD",31)) D STATUS31^BPSOSQF
 ;
 ; Handle claims that need the packet to be built
 I $D(^BPST("AD",30)) D STATUS30
 ;
 ; If there are still any claims with status 30 (perhaps due to failed
 ;   LOCK59), queue up BPSOSQ2 to run again
 I $O(^BPST("AD",30,0)) H 60 D TASK^BPSOSQA
 Q
 ;
 ; Walk through claims at 30%, bundle, and create the claim
STATUS30 ;
 N IEN59,ERROR,TRANLIST
 S IEN59=""
 I '$$LOCK59(30) Q
 ;
 ; Loop though claims at 30%, bundle with other 30% claims, and process
 F  S IEN59=$$NEXT59(IEN59) Q:IEN59=""  D
 . ; Intialize the list
 . K TRANLIST
 . S TRANLIST(IEN59)=""
 . ;
 . ; Update the status to 40 (Building the packet)
 . D SETSTAT^BPSOSU(IEN59,40)
 . ;
 . ; If the VA implements bundling in the future, then init BUNDLE variable to be 1 here
 . N BUNDLE
 . S BUNDLE=0
 . ;
 . ; If reversal, only one claim per transmission
 . I $G(^BPST(IEN59,4)) S BUNDLE=0
 . ;
 . ; Bundling only valid for billing requests, not eligibility or reversals
 . I $P($G(^BPST(IEN59,0)),U,15)'="C" S BUNDLE=0
 . ;
 . ; If prior auth are entered, only one claim per transmission
 . I $$CHKPA() S BUNDLE=0
 . ;
 . I $G(BUNDLE) D BUNDLE
 . ;
 . ; BPSOSQG will build the claim data, create the packet, and send to HL7
 . S ERROR=$$PACKET^BPSOSQG
 . ;
 . ; If an error is returned, log the error to each transaction
 . I ERROR S IEN59="" F  S IEN59=$O(TRANLIST(IEN59)) Q:IEN59=""  D
 .. D ERROR^BPSOSU($T(+0),IEN59,$P(ERROR,U),$P(ERROR,U,2,$L(ERROR,U)))
 D UNLOCK59(30)
 Q
 ;
NEXT59(IEN59) ;EP - BPSOSQF
 N GRPLAN,BPSIEN15
N59A ;
 ; Get next transaction at 30%
 S IEN59=$O(^BPST("AD",30,IEN59))
 I IEN59="" Q IEN59  ; end of list, return ""
 ;
 ; Get the GROUP INSURANCE PLAN
 S GRPLAN=+$$GETPLN59^BPSUTIL2(IEN59)
 ;
 ; If the GROUP INSURANCE PLAN isn't asleep or if the IGNORE ASLEEP flag
 ;   is set, then return this transaction
 I '$$ISASLEEP^BPSOSQF(GRPLAN) Q IEN59
 ;
 ; If this is the prober and it is time to retry, then return the transaction
 I $$PROBER^BPSOSQF(GRPLAN)=IEN59,$$RETRY^BPSOSQF(GRPLAN) Q IEN59
 ;
 ; For anything else, we need to turn on insurer asleep
 S BPSIEN15=$O(^BPS(9002313.15,"B",+$G(GRPLAN),0))
 D SETSLEEP^BPSOSQ4(IEN59,BPSIEN15,$T(+0)_"-Insurer asleep - Waiting for Prober Transaction "_$$PROBER^BPSOSQF(+$G(GRPLAN))_" to complete")
 ;
 ; Get next transaction
 G N59A
 ;
BUNDLE ; This code is for bundling claims.  The VA is not doing bundling, but this 
 ; code is being left in place in case we do bundling in the future.  If so, the
 ; code will need to be rewritten to look at the correct fields.
 ;
 Q    ;  no bundling for now
 ;
 ; Code below is original IHS code, which is based on NCPCP version 3x.
 ; Going forward, the Transmission Header, Patient, and Insurance segments
 ; would need to be the same for all bundled claims.  So, we would need:
 ;   Same Pharmacy Plan (which we get the BIN, PCN, Software Cert ID)
 ;   Same Pharmacy NPI (same division for all Rx's)
 ;   Same DOS for all Rx's
 ;   Same Patient
 ;   Same Insurance/Cardholder
 ;   Make sure the transaction is a billing request (not reversal/eligibility)
 N RA0,RA1 S RA0=^BPST(IEN59,0),RA1=^(1)
 N IEN59 S IEN59="" ; preserve the top-level index!
 F  S IEN59=$$NEXT59(IEN59,30) Q:'IEN59  D
 . N RB0,RB1 S RB0=^BPST(IEN59,0),RB1=^(1)
 . ; Only bundle when you have the same:
 . ; Patient, Visit, Division, Division Source, Insurer, Pharmacy
 . I $P(RA0,U,6,7)'=$P(RB0,U,6,7) Q
 . I $P(RA1,U,4,7)'=$P(RB1,U,4,7) Q
 . I $P(RB0,U,2)'=30 Q  ; might have been canceled, or maybe 31'd
 . D SETSTAT^BPSOSU(IEN59,40)
 . S TRANLIST(IEN59)=""
 . Q
 ;
BUNDLEX ;
 Q
 ;
 ;
LOCK59(STATUS) ;EP - BPSOSQF
 L +^BPST("AD",STATUS):60
 Q $T
 ;
UNLOCK59(STATUS) ;EP - BPSOSQF
 L -^BPST("AD",STATUS)
 Q
 ;
 ; IHS code, slightly modified for VA.  We will need to look
 ;  at this if we start bundling claims.
 ; Since the prior auth type and number are in the claim segment,
 ;  which is at the transmission level, this check may not longer 
 ;  be valid.  This code was originally for NCPCP version 3x and
 ;  may no longer be valid for NCPCP version D0.
 ; If this is valid, it would seem that the same logic would
 ;  need to be added to the BUNDLE procedure above so we don't add a 
 ;  BPS Transaction to the bundle if it has a prior auth type or number.
CHKPA() ;
 N PATYP,PANUM,PACLM
 S PACLM=0
 ;
 S PATYP=$P($G(^BPST(IEN59,1)),U,15)    ;prior auth type code
 S PANUM=$P($G(^BPST(IEN59,1)),U,9)     ;prior auth number
 I ($G(PATYP)'="")!($G(PANUM)'="") S PACLM=1
 ;
 Q PACLM
 
--- Routine Detail   --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HBPSOSQ2   4946     printed  Sep 23, 2025@19:28:04                                                                                                                                                                                                     Page 2
BPSOSQ2   ;BHAM ISC/FCS/DRS/DLF - form transmission packets ;06/01/2004
 +1       ;;1.0;E CLAIMS MGMT ENGINE;**1,5,7,10**;JUN 2004;Build 27
 +2       ;;Per VHA Directive 2004-038, this routine should not be modified.
 +3       ; Construct packets for transmission
 +4        QUIT 
 +5       ;
PACKETS   ; EP - Tasked by BPSOSQA
 +1       ;
 +2       ; First handle insurer alseep transactions
 +3        IF $DATA(^BPST("AD",31))
               DO STATUS31^BPSOSQF
 +4       ;
 +5       ; Handle claims that need the packet to be built
 +6        IF $DATA(^BPST("AD",30))
               DO STATUS30
 +7       ;
 +8       ; If there are still any claims with status 30 (perhaps due to failed
 +9       ;   LOCK59), queue up BPSOSQ2 to run again
 +10       IF $ORDER(^BPST("AD",30,0))
               HANG 60
               DO TASK^BPSOSQA
 +11       QUIT 
 +12      ;
 +13      ; Walk through claims at 30%, bundle, and create the claim
STATUS30  ;
 +1        NEW IEN59,ERROR,TRANLIST
 +2        SET IEN59=""
 +3        IF '$$LOCK59(30)
               QUIT 
 +4       ;
 +5       ; Loop though claims at 30%, bundle with other 30% claims, and process
 +6        FOR 
               SET IEN59=$$NEXT59(IEN59)
               if IEN59=""
                   QUIT 
               Begin DoDot:1
 +7       ; Intialize the list
 +8                KILL TRANLIST
 +9                SET TRANLIST(IEN59)=""
 +10      ;
 +11      ; Update the status to 40 (Building the packet)
 +12               DO SETSTAT^BPSOSU(IEN59,40)
 +13      ;
 +14      ; If the VA implements bundling in the future, then init BUNDLE variable to be 1 here
 +15               NEW BUNDLE
 +16               SET BUNDLE=0
 +17      ;
 +18      ; If reversal, only one claim per transmission
 +19               IF $GET(^BPST(IEN59,4))
                       SET BUNDLE=0
 +20      ;
 +21      ; Bundling only valid for billing requests, not eligibility or reversals
 +22               IF $PIECE($GET(^BPST(IEN59,0)),U,15)'="C"
                       SET BUNDLE=0
 +23      ;
 +24      ; If prior auth are entered, only one claim per transmission
 +25               IF $$CHKPA()
                       SET BUNDLE=0
 +26      ;
 +27               IF $GET(BUNDLE)
                       DO BUNDLE
 +28      ;
 +29      ; BPSOSQG will build the claim data, create the packet, and send to HL7
 +30               SET ERROR=$$PACKET^BPSOSQG
 +31      ;
 +32      ; If an error is returned, log the error to each transaction
 +33               IF ERROR
                       SET IEN59=""
                       FOR 
                           SET IEN59=$ORDER(TRANLIST(IEN59))
                           if IEN59=""
                               QUIT 
                           Begin DoDot:2
 +34                           DO ERROR^BPSOSU($TEXT(+0),IEN59,$PIECE(ERROR,U),$PIECE(ERROR,U,2,$LENGTH(ERROR,U)))
                           End DoDot:2
               End DoDot:1
 +35       DO UNLOCK59(30)
 +36       QUIT 
 +37      ;
NEXT59(IEN59) ;EP - BPSOSQF
 +1        NEW GRPLAN,BPSIEN15
N59A      ;
 +1       ; Get next transaction at 30%
 +2        SET IEN59=$ORDER(^BPST("AD",30,IEN59))
 +3       ; end of list, return ""
           IF IEN59=""
               QUIT IEN59
 +4       ;
 +5       ; Get the GROUP INSURANCE PLAN
 +6        SET GRPLAN=+$$GETPLN59^BPSUTIL2(IEN59)
 +7       ;
 +8       ; If the GROUP INSURANCE PLAN isn't asleep or if the IGNORE ASLEEP flag
 +9       ;   is set, then return this transaction
 +10       IF '$$ISASLEEP^BPSOSQF(GRPLAN)
               QUIT IEN59
 +11      ;
 +12      ; If this is the prober and it is time to retry, then return the transaction
 +13       IF $$PROBER^BPSOSQF(GRPLAN)=IEN59
               IF $$RETRY^BPSOSQF(GRPLAN)
                   QUIT IEN59
 +14      ;
 +15      ; For anything else, we need to turn on insurer asleep
 +16       SET BPSIEN15=$ORDER(^BPS(9002313.15,"B",+$GET(GRPLAN),0))
 +17       DO SETSLEEP^BPSOSQ4(IEN59,BPSIEN15,$TEXT(+0)_"-Insurer asleep - Waiting for Prober Transaction "_$$PROBER^BPSOSQF(+$GET(GRPLAN))_" to complete")
 +18      ;
 +19      ; Get next transaction
 +20       GOTO N59A
 +21      ;
BUNDLE    ; This code is for bundling claims.  The VA is not doing bundling, but this 
 +1       ; code is being left in place in case we do bundling in the future.  If so, the
 +2       ; code will need to be rewritten to look at the correct fields.
 +3       ;
 +4       ;  no bundling for now
           QUIT 
 +5       ;
 +6       ; Code below is original IHS code, which is based on NCPCP version 3x.
 +7       ; Going forward, the Transmission Header, Patient, and Insurance segments
 +8       ; would need to be the same for all bundled claims.  So, we would need:
 +9       ;   Same Pharmacy Plan (which we get the BIN, PCN, Software Cert ID)
 +10      ;   Same Pharmacy NPI (same division for all Rx's)
 +11      ;   Same DOS for all Rx's
 +12      ;   Same Patient
 +13      ;   Same Insurance/Cardholder
 +14      ;   Make sure the transaction is a billing request (not reversal/eligibility)
 +15       NEW RA0,RA1
           SET RA0=^BPST(IEN59,0)
           SET RA1=^(1)
 +16      ; preserve the top-level index!
           NEW IEN59
           SET IEN59=""
 +17       FOR 
               SET IEN59=$$NEXT59(IEN59,30)
               if 'IEN59
                   QUIT 
               Begin DoDot:1
 +18               NEW RB0,RB1
                   SET RB0=^BPST(IEN59,0)
                   SET RB1=^(1)
 +19      ; Only bundle when you have the same:
 +20      ; Patient, Visit, Division, Division Source, Insurer, Pharmacy
 +21               IF $PIECE(RA0,U,6,7)'=$PIECE(RB0,U,6,7)
                       QUIT 
 +22               IF $PIECE(RA1,U,4,7)'=$PIECE(RB1,U,4,7)
                       QUIT 
 +23      ; might have been canceled, or maybe 31'd
                   IF $PIECE(RB0,U,2)'=30
                       QUIT 
 +24               DO SETSTAT^BPSOSU(IEN59,40)
 +25               SET TRANLIST(IEN59)=""
 +26               QUIT 
               End DoDot:1
 +27      ;
BUNDLEX   ;
 +1        QUIT 
 +2       ;
 +3       ;
LOCK59(STATUS) ;EP - BPSOSQF
 +1        LOCK +^BPST("AD",STATUS):60
 +2        QUIT $TEST
 +3       ;
UNLOCK59(STATUS) ;EP - BPSOSQF
 +1        LOCK -^BPST("AD",STATUS)
 +2        QUIT 
 +3       ;
 +4       ; IHS code, slightly modified for VA.  We will need to look
 +5       ;  at this if we start bundling claims.
 +6       ; Since the prior auth type and number are in the claim segment,
 +7       ;  which is at the transmission level, this check may not longer 
 +8       ;  be valid.  This code was originally for NCPCP version 3x and
 +9       ;  may no longer be valid for NCPCP version D0.
 +10      ; If this is valid, it would seem that the same logic would
 +11      ;  need to be added to the BUNDLE procedure above so we don't add a 
 +12      ;  BPS Transaction to the bundle if it has a prior auth type or number.
CHKPA()   ;
 +1        NEW PATYP,PANUM,PACLM
 +2        SET PACLM=0
 +3       ;
 +4       ;prior auth type code
           SET PATYP=$PIECE($GET(^BPST(IEN59,1)),U,15)
 +5       ;prior auth number
           SET PANUM=$PIECE($GET(^BPST(IEN59,1)),U,9)
 +6        IF ($GET(PATYP)'="")!($GET(PANUM)'="")
               SET PACLM=1
 +7       ;
 +8        QUIT PACLM