1. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 4/18/2019 5:55:12 PM Eastern Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

1.1 Files compared

# Location File Last Modified
1 MCCF_EDI_TAS_TASCore v2.0_Build_10.zip\MCCF_EDI_TAS_API_Core\src\app\fsc\837 business.js Wed Apr 3 02:27:40 2019 UTC
2 MCCF_EDI_TAS_TASCore v2.0_Build_10.zip\MCCF_EDI_TAS_API_Core\src\app\fsc\837 business.js Tue Apr 16 13:20:38 2019 UTC

1.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 4 1372
Changed 3 6
Inserted 0 0
Removed 0 0

1.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

1.4 Active regular expressions

No regular expressions were active.

1.5 Comparison detail

  1   "use stric t"
  2   const debu g = requir e('debug') ('fsc837')
  3   const {
  4       perfor mance
  5   } = requir e('perf_ho oks')
  6  
  7   const util  = require ('util')
  8  
  9   const $tas  = require ('../../.. /tas')()
  10  
  11   const logg ing = {
  12       add: a sync (item , secid) = > await $t as.command .run('logg ing', 'dat a', 'save' , item, {
  13           se cid
  14       })
  15   }
  16  
  17   const inst anceMap =  {
  18       get: a sync () =>  await $ta s.provider s.load('me tabase').g et('common :vista_ins tance_map' )
  19   }
  20  
  21   const crit eria = [{
  22           pr edicate: ( error, res ponse, bod y) => ((er ror || {}) .message | | '').incl udes('ECON NRESET'),
  23           ac tion: (err or, respon se, body)  => true
  24       },
  25       {
  26           pr edicate: ( error, res ponse, bod y) => ((er ror || {}) .message | | '').incl udes('ENOT FOUND'),
  27           ac tion: (err or, respon se, body)  => false
  28       },
  29       {
  30           pr edicate: ( error, res ponse, bod y) => ((er ror || {}) .message | | '').incl udes('ETIM EDOUT'),
  31           ac tion: () = > true
  32       },
  33       {
  34           pr edicate: ( error, res ponse, bod y) => (res ponse || { }).statusC ode === 50 2,
  35           ac tion: () = > true
  36       },
  37       {
  38           pr edicate: ( error, res ponse, bod y) => ((bo dy || {}). entry || ' ').length  === 0,
  39           ac tion: () = > false
  40       }
  41   ]
  42  
  43   /**
  44    * 
  45    * @param  {*} extrac tConfig 
  46    * @param  {*} vistaI
  47    */
  48   let instan ceHelper =  async (ex tractConfi g, vistaId ) => {
  49       let _i nstanceMap  = await i nstanceMap .get()
  50       let re gex = new  RegExp('(\ \d+).*', ' gm')
  51       let ma tchArray =  regex.exe c(vistaId)
  52       if (ma tchArray & & matchArr ay.length)  {
  53           le t _instanc e = matchA rray[1]
  54           re turn _inst anceMap[_i nstance] | | 'bad_map '
  55       } else  {
  56           re turn 'bad_ map'
  57       }
  58   }
  59  
  60   /**
  61    * 
  62    * @param  {*} extrac tConfig 
  63    * @param  {*} claimR esponseIEN
  64    * @param  {*} vistaI
  65    */
  66   let assemb leClaimURL S  = async  (extractC onfig, cla imResponse IENs, vist aId)  => {
  67       let me ssage = "S uccess"
  68       let st atusCode =  200
  69       let ur ls = []
  70       let qu ery = `ent ry[*].reso urce.{ ide ntifier :  identifier [], organi zation: or ganization  }`
  71       let ie nsArray =  $tas.helpe rs.jmespat h.search(c laimRespon seIENs, qu ery)
  72       const  USE = "837 "
  73       let in stance = a wait insta nceHelper( extractCon fig, vista Id)
  74       extrac tConfig.vi staInstanc e = instan ce
  75       extrac tConfig.vi staId = vi staId
  76       let ie nCount = 0
  77       let ie nLimit = e xtractConf ig.ienLimi t || 0
  78       if (ie nsArray &&  iensArray .length >  0) {
  79           ie nsArray.ma p(resource  => {
  80                let id =  resource. identifier [0].value
  81                let refe rence = re source.org anization. reference
  82                let loca tion = ref erence.sub str(refere nce.lastIn dexOf('/')  + 1)
  83                ienCount  = ienCoun t + 1
  84  
  85                if ((ien Count <= i enLimit) | | ( ienLim it == 0))  {
  86                    urls .push({
  87                    opti ons: {
  88                         method: 'G ET',
  89                         uri: `${ex tractConfi g.tasFHIRE ndpoint}`  + TEMPLATE _fsc_837_b undle_url( extractCon fig, USE,  id),
  90                         headers: {
  91                             vistai d: extract Config.vis taId
  92                         },
  93                         retry: {
  94                             maxCou nt: 40,
  95                             sleepT ime: 90,
  96                             criter ia
  97                         }
  98                    }
  99                })
  100           }
  101           })
  102       } else  {
  103           st atusCode =  201
  104           me ssage = "N o iens fou nd " + JSO N.stringif y(claimRes ponseIENs)
  105       }
  106       return  {
  107           st atusCode,
  108           me ssage,
  109           ur ls
  110       }
  111   }
  112  
  113  
  114   /**
  115    *
  116    * @param  user_id
  117    * @param  webClientO ptions
  118    * @return s {Promise <{statusCo de: string , message:  string, u ri: *, bun dle: any}> }
  119    */
  120   let getBun dle = asyn c function  (user_id,  webClient Options) {
  121       debug( 'business: :getBundle ')
  122       let me ssage = "S uccess"
  123       let st atusCode =  200
  124       let ur i = webCli entOptions .uri
  125       let bu ndle
  126       let {
  127           er ror,
  128           re sponse,
  129           bo dy
  130       } = aw ait $tas.w ebclient({
  131           se curityCont extNotUsed : user_id
  132       }, web ClientOpti ons)
  133  
  134       if (er ror !== nu ll || body  === null)  {
  135           if  (response  != null & & response .request)  {
  136                statusCo de = respo nse.status Code || 50 0
  137                if (resp onse.statu sCode ===  500) {
  138                    mess age = webC lientOptio ns.uri + ' body: ' +  body
  139                } else {
  140                    mess age = 'Err or from FH IR server: ' + util.i nspect(err or) + ' '  + webClien tOptions.u ri + ' ' +  body
  141                }
  142           }  else {
  143                statusCo de = 500
  144                message  = 'Error:  ' + webCli entOptions .uri + ' '  + util.in spect(erro r)
  145           }
  146       } else  if (body  !== null & & response  != null & & response .statusCod e !== 200)  {
  147           st atusCode =  response. statusCode
  148           me ssage = 'F HIR Server  returned  status cod e: ' + res ponse.stat usCode + '  ' + webCl ientOption s.uri + '  ' + body
  149       } else  {
  150           //  jws 12/10 /18 added  back JSON. parse()
  151           tr y {
  152                bundle =  JSON.pars e(body)
  153           }  catch (ex)  {
  154                statusCo de = 500
  155                message  = 'FHIR Se rver retur ned non js on (html?)  :' + webC lientOptio ns.uri + '  ' + body
  156           }
  157       }
  158  
  159       return  {
  160           st atusCode,
  161           me ssage,
  162           ur i,
  163           bu ndle
  164       }
  165   }
  166  
  167   /**
  168    *
  169    * @param  webClientO ptions
  170    * @return s {Promise <{statusCo de: string , message:  string, u ri: *, bun dle: any}> }
  171    */
  172   let setBun dle = asyn c function  (webClien tOptions)  {
  173       debug( 'business: :setBundle ')
  174       let me ssage = "S uccess"
  175       let st atusCode =  200
  176       let se curityCont ext = null
  177       let {
  178           er ror,
  179           re sponse,
  180           bo dy
  181       } = aw ait $tas.w ebclient(s ecurityCon text, webC lientOptio ns)
  182  
  183       if (er ror !== nu ll || body  === null)  {
  184           if  (response  != null & & response .request)  {
  185                statusCo de = respo nse.status Code || 50 0
  186                if (resp onse.statu sCode ===  500) {
  187                    mess age = webC lientOptio ns.uri + ' body: ' +  body
  188                    // 5 /29/2018 l og warning  and then  go head an d push the  Operation Outcome
  189                    logg ing.add(lo gItem('WAR NING', 'FH IR SERVER  RETURNED 5 00 ' + web ClientOpti ons.uri +  body))
  190                    // f all throug h
  191                } else {
  192                    mess age = 'Err or from FH IR server: ' + util.i nspect(err or) + ' '  + webClien tOptions.u ri
  193                }
  194           }  else {
  195                statusCo de = 500
  196                message  = 'Error:  ' + webCli entOptions .uri + ' '  + util.in spect(erro r)
  197           }
  198       } else  if (body  !== null & & response  != null & & response .statusCod e !== 200)  {
  199           st atusCode =  response. statusCode  || 500
  200           me ssage = 'F HIR Server  returned  status cod e: ' + res ponse.stat usCode + '  ' + webCl ientOption s.uri + '  ' + body
  201       }
  202  
  203       let bu ndle = bod y
  204  
  205       return  {
  206           st atusCode,
  207           me ssage,
  208           ur i: webClie ntOptions. uri,
  209           bu ndle
  210       }
  211   }
  212  
  213  
  214   /**
  215    *
  216    * @param  readResult s
  217    * @param  extractCon fig
  218    * @param  user_id
  219    * @return s {Promise <*>}
  220    */
  221   let sendTo Queue = as ync functi on (bundle Obj, extra ctConfig,  user_id) {
  222       debug( 'business: :sendToQue ue')
  223       if (bu ndleObj.st atusCode ! == 200) {
  224           re turn {
  225                statusCo de: 501,
  226                message:  "Skipping , record n ot written  to queue;  upstream  500 from V A_FHIR_Ser ver",
  227           }
  228       }
  229  
  230       // JWS  11/5/18 i f FHIR Ser ver return  self for  some reaso n, bundle  msg is not  defined,  entry.leng th is unde fined
  231       if (bu ndleObj.bu ndle && bu ndleObj.bu ndle.entry  && bundle Obj.bundle .entry.len gth === 0)  {
  232           re turn {
  233                statusCo de: 501,
  234                message:  "Skipping , record n ot written  to queue;  no bundle Obj.bundle .entry",
  235           }
  236       }
  237  
  238       let qu eue_respon se
  239       let pa yload = bu ndleObj.bu ndle
  240       let qu eueName =  extractCon fig.queueN ame
  241  
  242       let co unt = (bun dleObj.bun dle.meta & & bundleOb j.bundle.m eta.extens ion) ? bun dleObj.bun dle.meta.e xtension.l ength : 0
  243       for (v ar i = cou nt - 1; i  > -1; i--)  {
  244           le t claimDat a = bundle Obj.bundle .meta.exte nsion[i]
  245           if  (claimDat a.id === ' status') {
  246                let clai mType = cl aimData.va lueString
  247                if (clai mType ===  'test') {
  248                    queu eName = ex tractConfi g.testQueu eName
  249                } else { }
  250                break
  251           }
  252       }
  253  
  254       try {
  255           //  N.B. requ ires $tas. config.QUE UE_ADDRESS
  256           qu eue_respon se = await  $tas.prov iders.amqp .send(queu eName, pay load)
  257           //  if queue  response d oes not =  'true' the n somethin g else.
  258  
  259       } catc h (ex) {
  260           lo gging.add( logItem('I NFO', ex.m essage + '  ' + ex.st ack, 'djh_ failure'),  user_id)
  261           re turn {
  262                statusCo de: 500,
  263                message:  ex.messag e,
  264                exceptio n: ex
  265           }
  266       }
  267       let st atusCode =  200
  268       if (!q ueue_respo nse || que ue_respons e == false ) {
  269           st atusCode =  500
  270       }
  271  
  272       return  {
  273           st atusCode,
  274           me ssage: `am qp send()  response:  ${queue_re sponse}  $ {bundleObj .uri}`
  275       }
  276   }
  277  
  278   var FHIR_C laim_Ack_R esponse =  {
  279       "resou rceType":  "Claim",
  280       "id":  "11112222" ,
  281       "exten sion": [{
  282           "u rl": "writ eToQueueSu ccessful",
  283           "v alueString ": 200
  284       }]
  285   }
  286  
  287   /**
  288    *
  289    * @param  readResult s
  290    * @param  extractCon fig
  291    * @param  user_id
  292    * @return s {Promise <*>}
  293    */
  294   let writeB ack = asyn c function  (bundleOb j, queueOb j, extract Config, vi staId) {
  295       debug( 'business: :writeBack ')
  296       if (bu ndleObj.st atusCode ! == 200) {
  297           re turn {
  298                statusCo de: 501,
  299                message:  "Skipping , no write back; upst ream 500 f rom VA_FHI R_Server",
  300                uri: bun dleObj.uri
  301           }
  302       }
  303  
  304       if (!b undleObj.b undle) {
  305           re turn {
  306                statusCo de: 501,
  307                message:  "Skipping , no claim  bundle",
  308                uri: bun dleObj.uri
  309           }
  310       }
  311  
  312       if (qu eueObj.sta tusCode != = 200) {
  313           re turn {
  314                statusCo de: 501,
  315                message:  "Skipping , no write back; queu e failed",
  316                uri: bun dleObj.uri
  317           }
  318       }
  319  
  320       const  USE = '837 WB'
  321       let in stance = a wait insta nceHelper( extractCon fig, vista Id)
  322       extrac tConfig.vi staInstanc e = instan ce
  323       extrac tConfig.vi staId = vi staId
  324  
  325       let se tBundleObj
  326       // DJH  - Questio n for JWS  -is this p ulling out  of the bu ndle or fr om the URI ? 12/8/201 8 for some  reason th is was 
  327       // let  id = /.*_ id=(\d*)/g m.exec(bun dleObj.bun dle)
  328       let id  = /.*_id= (\d*)/gm.e xec(bundle Obj.uri)
  329       // TOD O check if  id[1] str ing is num ber
  330       // rep lace claim  ien id in  response  template w ith curren t claim ie n processi ng
  331       let UR L = `${ext ractConfig .tasFHIREn dpoint}` +  TEMPLATE_ fsc_837_wr iteback_ur l(extractC onfig, USE , id[1])
  332       let pa yload = JS ON.parse(J SON.string ify(FHIR_C laim_Ack_R esponse))
  333       payloa d.id = id[ 1]
  334       let op tions = {
  335           me thod: 'PUT ',
  336           ur i: URL,
  337           he aders: {
  338                vistaid:  extractCo nfig.vista Id
  339           },
  340           re try: {
  341                maxCount : 40,
  342                sleepTim e: 90,
  343                criteria
  344           },
  345           bo dy: payloa d,
  346           js on: true
  347       }
  348  
  349       setBun dleObj = a wait setBu ndle(optio ns)
  350       
  351       try {
  352                if (setB undleObj ! == null &&  setBundle Obj.bundle  !==null)  {
  353                    if ( setBundleO bj.bundle. issue !==  undefined)  {
  354                         let rpcSta tusData =  setBundleO bj.bundle. issue[0]
  355                         let rpcSta tus = rpcS tatusData. diagnostic s.slice(-5 ,-4)
  356                         if (rpcSta tus == '1' ) {
  357                             setBun dleObj.sta tusCode =  200
  358                         }
  359                    }
  360                }
  361  
  362           }  catch (ex)  {
  363                setBundl eObj.statu sCode = 50 0
  364           }
  365       return  setBundle Obj
  366   }
  367  
  368   /**
  369    *
  370    * @param  priority
  371    * @param  message
  372    * @return s {{type:  string, ac tion: *, d ata: *}}
  373    */
  374  
  375   let logIte m = functi on (priori ty, messag e) {
  376       return  {
  377           ty pe: "night ly_extract ",
  378           ac tion: prio rity,
  379           da ta: messag e // data  === outcom eDesc
  380       }
  381   }
  382  
  383   /***
  384    *
  385    * @param  user_id
  386    * @param  extractCon fig
  387    * @return s {Promise <*>}
  388    *
  389    * extract  is the wo rkhorse
  390    *
  391    * 1) call s VA_FHIR_ Server to  get claim  data
  392    * 2) post s claim ob jects to R abbit MQ s erver queu e 837Trans actions
  393    * 3) exec utes an ac knowledgem ent RPC in dicating c laim was p osted to q ueue
  394    */
  395   let extrac tClaims =  async func tion (user _id, extra ctConfig,  bundleUrl,  vistaId)  {
  396       debug( 'business: :extractCl aims')
  397       let su mmary = {
  398           bu ndleSucces s: 0,
  399           qu eueWriteSu ccess: 0,
  400           wr iteBackSuc cess: 0,
  401           bu ndleFailur e: 0,
  402           qu eueWriteFa ilure: 0,
  403           wr iteBackFai lure: 0,
  404           qu eueWriteSk ip: 0,
  405           wr iteBackSki p: 0,
  406           to tal: 0
  407       }
  408  
  409       let re sults = aw ait Promis e.all(
  410           bu ndleUrl.ur ls.map(asy nc webclie ntObj => {
  411                try {
  412                    summ ary.total+ +
  413                    // r ead bundle s from VA- FHIR-Serve r
  414                    let  bundleObj  = await ge tBundle(us er_id, web clientObj. options)
  415                    bund leObj.stat usCode ==  200 ? summ ary.bundle Success++  : summary. bundleFail ure++
  416  
  417                    // w rite bundl es to amqp
  418                    let  queueWrite  = await s endToQueue (bundleObj , extractC onfig, use r_id)
  419                    if ( queueWrite .statusCod e == 200)  {
  420                         summary.qu eueWriteSu ccess++
  421                    } el se if ( qu eueWrite.s tatusCode  == 501) {
  422                         summary.qu eueWriteSk ip++
  423                    } el se {
  424                         summary.qu eueWriteFa ilure++
  425                    }
  426  
  427  
  428                    // w rite back  to vista a cknowledge ment that  claim was  posted to  queue
  429                    let  writeBackR esult = aw ait writeB ack(bundle Obj, queue Write, ext ractConfig , vistaId)
  430                    if ( writeBackR esult.stat usCode ==  200) {
  431                         summary.wr iteBackSuc cess++
  432                    } el se if ( wr iteBackRes ult.status Code == 50 1) {
  433                         summary.wr iteBackSki p++
  434                    } el se {
  435                         summary.wr iteBackFai lure++
  436                    }
  437  
  438                    dele te bundleO bj.bundle
  439  
  440                    debu g(webclien tObj.optio ns.uri + '  ' + util. inspect(su mmary))
  441  
  442                    let  _result =  {
  443                         statusCode : (bundleO bj.statusC ode == 200  && queueW rite.statu sCode == 2 00 && writ eBackResul t.statusCo de == 200)  ? 200 : 5 00,
  444                         message: ( bundleObj. statusCode  == 200 &&  queueWrit e.statusCo de == 200  && writeBa ckResult.s tatusCode  == 200) ?  'Success'  : 'bundleO bj: ' + bu ndleObj.me ssage + 'q ueueWrite:  ' + queue Write.mess age + 'wri teBackResu lt: ' + wr iteBackRes ult.messag e,
  445                         bundleObj,
  446                         queueWrite ,
  447                         writeBack:  writeBack Result
  448                    }
  449  
  450                    // D JH 12/14/2 018 - when  we ran 10 00, result s was caus ing 2.5 MB  json, so  truncate
  451                    if ( _result.st atusCode ! = 200) {
  452                         return _re sult
  453                    } el se {
  454                         return
  455                    }
  456                } catch  (ex) {
  457                    retu rn {
  458                         statusCode : 500,
  459                         message: " Exception: " + ex.mes sage ? ex. message :  "no messag e extractC laims()",
  460                         exception:  ex
  461                    }
  462                }
  463  
  464           })
  465       )
  466  
  467       let st atusCode =  200
  468       let me ssage = 'S uccess'
  469       if ((s ummary.bun dleSuccess  + summary .queueWrit eSuccess +  summary.w riteBackSu ccess) / 3  != summar y.total) {
  470           st atusCode =  500
  471           me ssage = 'F ailure che cksum'
  472       }
  473  
  474       // DJH  12/14/201 8 remove u ndefined
  475       result s = result s.filter(  n => n)
  476  
  477       // JWS  1/24/19 w rite resul ts-log ent ry to a fi le incase  it's too b ig to file  to MongoD b
  478       // @JW S changed  this to be  written o nly if env  variable  is set, is  this ok?
  479       if ( p rocess.env .TAS_LOCAL _DEVELOPER  && (summa ry.bundleS uccess + s ummary.que ueWriteSuc ces + summ ary.writeB ackSucces)  / 3 != su mmary.tota l) {
  480           le t filename  = '837Bus inessServi ceResults  ' + Date.n ow() + '.t xt'
  481           le t text = J SON.string ify(summar y)
  482           le t text1 =  JSON.strin gify(resul ts)
  483           le t textresu lt = statu sCode + '  ' + messag e + ' ' +  text + ' '  + text1
  484           aw ait $tas.f s.writeFil e(filename , textresu lt)
  485           }
  486       return  {
  487           st atusCode,
  488           me ssage,
  489           su mmary,
  490           re sults
  491       }
  492   }
  493  
  494  
  495   let TEMPLA TE_fsc_837 _iens_url  = (extract Config) =>  `/${extra ctConfig.f hirResourc eBundle}?l ocation=${ extractCon fig.vistaI nstance}&u se=${extra ctConfig.u se}&extrac tTimestamp =${extract Config.ext ractTimest amp}`
  496   //https:// DNS . URL /VA-FHIR-S erver/fhir /Bundle?lo cation=eBi lling_dev& use=837ien s
  497   let TEMPLA TE_fsc_837 _bundle_ur l = (extra ctConfig,  use, id) = > `/${extr actConfig. fhirResour ceBundle}? use=${use} &location= ${extractC onfig.vist aInstance} &_id=${id} &extractTi mestamp=${ extractCon fig.extrac tTimestamp }`
  498   //https:// DNS . URL /VA-FHIR-S erver/fhir /Bundle?us e=837&loca tion=eBill ing_dev&_i d=2113327
  499   let TEMPLA TE_fsc_837 _writeback _url = (ex tractConfi g, use, id ) => `/${e xtractConf ig.fhirRes ourceClaim }/${id}?lo cation=${e xtractConf ig.vistaIn stance}&us e=${use}&e xtractTime stamp=${ex tractConfi g.extractT imestamp}`
  500   //https:// DNS . URL /VA-FHIR-S erver/fhir /Claim/211 3326?locat ion=eBilli ng_dev&use =837WB
  501  
  502  
  503   /***
  504    *
  505    * @param  user_id
  506    * @param  extractCon fig
  507    * @return s {Promise <*>}
  508    *
  509    * assembl es claim i ens and ca ll loop to  loop over  
  510    *
  511    * 1) loop s over lis t of vista  servers
  512    * 2) call s VA_FHIR_ Server to  get list o f associat ed iens
  513    * 3) extr acts claim  response  URLS
  514    * 4) call s extractC laims()
  515    *  
  516    */
  517   let extrac tFromInsta nce = asyn c function  (user_id,  extractCo nfig, vist aId, statu sLog) {
  518       debug( 'business: :extractFr omInstance ')
  519       try {
  520           // statusLog. vistaid =  vistaId,
  521           ex tractConfi g.vistaIns tance = aw ait instan ceHelper(e xtractConf ig, vistaI d),
  522                extractC onfig.vist aId = vist aId
  523  
  524           le t URL = `$ {extractCo nfig.tasFH IREndpoint }` + TEMPL ATE_fsc_83 7_iens_url (extractCo nfig)
  525           le t options  = {
  526                method:  'GET',
  527                uri: URL ,
  528                headers:  {
  529                    vist aid: vista Id
  530                },
  531                retry: {
  532                    maxC ount: 40,
  533                    slee pTime: 90,
  534                    crit eria
  535                }
  536           }
  537  
  538           //  get IENs  list
  539           le t bundleOb j = await  getBundle( user_id, o ptions)
  540           st atusLog.se tStatus("i ens", bund leObj.stat usCode, bu ndleObj.me ssage, bun dleObj.uri )
  541           if  (bundleOb j.statusCo de === 500 ) {
  542                // short  circuit
  543                throw ne w Error('g etBundle()  for IENS  returned 5 00:  ' + b undleObj.m essage)
  544  
  545           }
  546  
  547           //  convert l ist of IEN s to webcl ient URL/o ptions
  548           le t bundleUr l = await  assembleCl aimURLS(ex tractConfi g, bundleO bj.bundle,  vistaId)
  549           st atusLog.se tStatus("b undleUrls" , bundleUr l.statusCo de, bundle Url.messag e, bundleO bj.uri)
  550           if  (bundleUr l.statusCo de === 500 ) {
  551                // short  circuit
  552                throw ne w Error('a ssembleCla imURLS() r eturned 50 0: ' + bun dleUrl.mes sage)
  553  
  554           }
  555  
  556           le t claimRes ponse = aw ait extrac tClaims(us er_id, ext ractConfig , bundleUr l, vistaId )
  557           cl aimRespons e.vistaId  = vistaId
  558           st atusLog.se tValue('cl aims', cla imResponse )
  559  
  560           re turn statu sLog
  561  
  562       } catc h (ex) {
  563           de bug('Excep tion: extr actFromIns tance::' +  util.insp ect(ex))
  564           st atusLog.se tException (ex, 500,  ex.message )
  565           re turn statu sLog
  566       }
  567   }
  568  
  569  
  570   /***
  571    *
  572    * @param  user_id
  573    * @param  extractCon fig
  574    * @return s {Promise <*>}
  575    *
  576    * loops o ver vista  ids
  577    * 
  578    */
  579  
  580   module.exp orts.extra ct = async  function  (user_id,  extractCon fig, statu sLog) {
  581       // set s up time  counter fo r entire p rocess sta rt to fini sh
  582       // con sole.time( "837Busine ssProcess" )
  583       debug( 'business: :extract')
  584       status Log.extrac tTimestamp  = Date()
  585       const  runDate =  new Date()
  586  
  587       // ext ractConfig .extractTi mestamp =r unDate.toI SOString() .slice(0,1 9).replace (/-/g,"")
  588  
  589       let re sults
  590       let ti me0 = perf ormance.no w()
  591  
  592       try {
  593           //  jws 11/8/ 18 - open  connection s to Rabbi t MQ - ope n part of  $tas.provi ders.amqp. send does  not work p roperly
  594  
  595           le t channel
  596           tr y {
  597                // open  the rabbit mq connect ion and ch annel outs ide of the  promise.a ll loop
  598                await $t as.provide rs.amqp.co nnect(extr actConfig. queueAddre ss)
  599                channel  = await $t as.provide rs.amqp.en sureSendCh annel(extr actConfig. queueName)
  600                extractC onfig.test QueueName  ? await $t as.provide rs.amqp.en sureSendCh annel(extr actConfig. testQueueN ame) : nul l
  601  
  602           }  catch (ex)  {
  603                debug('a mqp::conne ct() faile d ' + util .inspect(e x))
  604           }
  605           //  loop thru  enabled v istaIds fo r user 'IB TAS,APPLIC ATION PROX Y' - enabl ed from IA M mock or  alternativ e
  606  
  607           //  IBTAS,APP LICATION P ROXY will  always be  the user t hat execut es this 83 7 Business  Process -  call to I AM to get
  608           //  list of a ll vista s ites that  have enabl ed IBTAS,A PPLICATION  PROXY use r via the  installati on of Vist A patch
  609           //  IB.2.0*62 3
  610           le t iamVista Ids = awai t $tas.com mand.run(' metabase',  'data', ' load', {
  611                names: ' vistaid,sa mAccountNa me'
  612           },  {
  613                'secid':  'IBTAS,AP PLICATION  PROXY'
  614           })
  615  
  616           le t _vistaSi tes = iamV istaIds.da ta['vistai d']
  617           //  below cod e swaps ou t DUZ valu e in vista id string  from IAM w ith the us er name, ' IBTAS,APPL ICATION PR OXY'
  618           //  special p rocessing  is perform ed by Vist A-Link whe n passing  'user name ' as oppos ed to user 's duz val ue (pointe r)
  619           le t vistaIds  = []
  620           if  (_vistaSi tes) {
  621                vistaIds  = _vistaS ites.split (',')
  622                let coun t = vistaI ds.length
  623                for (var  i = 0; i  < count; i ++) {
  624                    var  n = vistaI ds[i].inde xOf("^")
  625                    var  restofdata  = vistaId s[i].subst ring(n, 99 9)
  626                    var  newDuzName  = vistaId s[i].subst ring(0, 4)  + iamVist aIds.data. samAccount Name + res tofdata
  627                    vist aIds[i] =  newDuzName
  628                }
  629           }
  630  
  631           st atusLog.vi staIds = v istaIds
  632  
  633           le t resultPr omises = a wait vista Ids.map(as ync vistaI d => {
  634                // extra ctConfig.e xtractTime stamp = ru nDate.toIS OString(). slice(0,19 ).replace( /-/g,"") +  ' - ' + v istaId.sli ce(0,3)
  635                return a wait extra ctFromInst ance(user_ id, extrac tConfig, v istaId, st atusLog)
  636           })
  637  
  638           re sults = aw ait Promis e.all(resu ltPromises )
  639  
  640           le t statusCo de = 200
  641           le t message  = "Success "
  642           aw ait result s.every( r esult => {
  643                if (resu lt.statusC ode !== 20 0) {
  644                    stat usCode = r esult.stat usCode
  645                    mess age = resu lt.message  
  646                    retu rn false
  647                } else {
  648                    retu rn true
  649                }
  650           })
  651  
  652           re sults['sta tusCode']  = statusCo de
  653           re sults['mes sage'] = m essage
  654  
  655           st atusLog.se tValue('83 7ElapsedTi me', perfo rmance.now () - time0 )
  656  
  657           de bug('inspe ct status  log', util .inspect(s tatusLog,  true, 5))
  658  
  659           //  console.t imeEnd("83 7BusinessP rocess")
  660  
  661           tr y {
  662                await $t as.provide rs.amqp.cl oseChannel (channel.k ey)
  663           }
  664           ca tch (ex) {
  665                debug('a mqp::close () failed  ' + util.i nspect(ex) )
  666           }
  667  
  668       }
  669       catch  (ex) {
  670           if  (!results ) {
  671                statusLo g.setExcep tion(ex, 5 00, ex.mes sage)
  672           }
  673           el se {
  674                results[ 'statusCod e'] = 500
  675                results[ 'message']  = "Severe  error: "  + ex.messa ge
  676                results[ 'exception '] = ex
  677           }
  678       }
  679  
  680       result s = result s || statu sLog
  681       return   results
  682  
  683   }
  684  
  685   module.exp orts.TEMPL ATE_fsc_83 7_bundle_u rl = TEMPL ATE_fsc_83 7_bundle_u rl
  686   module.exp orts.TEMPL ATE_fsc_83 7_iens_url  = TEMPLAT E_fsc_837_ iens_url
  687   module.exp orts.TEMPL ATE_fsc_83 7_writebac k_url = TE MPLATE_fsc _837_write back_url
  688   module.exp orts.templ ateInstanc eHelper =  instanceHe lper
  689   module.exp orts.assem bleClaimUR LS = assem bleClaimUR LS