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.
# | 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 |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 4 | 1372 |
Changed | 3 | 6 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
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 |
No regular expressions were active.
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 d | |
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 s | |
64 | * @param {*} vistaI d | |
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 |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.