Produced by Araxis Merge on 4/9/2018 3:46:05 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 | TelehealthMgmtPlat_4.0.zip\Telehealth Management Platform 4.0\CRM-Prod.zip\CRM-Prod\VA.TMP.WebResources\J Script Functions\HTML | VIALogin.js | Fri Feb 23 23:11:32 2018 UTC |
| 2 | TelehealthMgmtPlat_4.0.zip\Telehealth Management Platform 4.0\CRM-Prod.zip\CRM-Prod\VA.TMP.WebResources\J Script Functions\HTML | VIALogin.js | Mon Apr 9 12:58:38 2018 UTC |
| Description | Between Files 1 and 2 |
|
|---|---|---|
| Text Blocks | Lines | |
| Unchanged | 7 | 1390 |
| Changed | 6 | 12 |
| 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 | if (typeof (MCS) == "undefined ") | |
| 2 | MCS = {}; | |
| 3 | ||
| 4 | if (typeof (MCS.VIAL ogin == "u ndefined") ) | |
| 5 | MCS.VI ALogin = { } | |
| 6 | ||
| 7 | MCS.VIALog in.KeepAli veWindowNa me = "crms soi"; | |
| 8 | MCS.VIALog in.Refresh es = 0; | |
| 9 | //MCS.VIAL ogin.Getti ngNewUserD uz; | |
| 10 | ||
| 11 | // ******* ********** ********** ********** *********P age Specif ic Functio ns | |
| 12 | MCS.VIALog in.LoginBu tton = fun ction () { | |
| 13 | var va lidSamlTok en = MCS.V IALogin.Is ValidSamlT oken(); | |
| 14 | if (va lidSamlTok en) { | |
| 15 | MC S.VIALogin .Login(); | |
| 16 | } | |
| 17 | else { | |
| 18 | MC S.VIALogin .Saml(); | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | MCS.VIALog in.IsValid SamlToken = function () { | |
| 23 | if (!M CS.VIALogi n.RunVista Integratio n()) | |
| 24 | re turn true; | |
| 25 | //To D o - add in possible check to e nsure the user who g ot the tok en origina lly is the same pers on that is now takin g action | |
| 26 | var sa mlToken = Xrm.Page.g etAttribut e("cvt_sam ltoken") ! = null ? X rm.Page.ge tAttribute ("cvt_saml token").ge tValue() : null; | |
| 27 | if (sa mlToken == null) //N o token | |
| 28 | re turn false ; | |
| 29 | ||
| 30 | var er rorTag = s amlToken.i ndexOf("<w st:Reason> "); | |
| 31 | if (er rorTag != -1) //Erro red Token | |
| 32 | re turn false ; | |
| 33 | ||
| 34 | var en dTimeIndex = samlTok en.indexOf ("NotOnOrA fter"); | |
| 35 | if (en dTimeIndex != -1) { | |
| 36 | va r endTimeS tring = sa mlToken.su bstring(en dTimeIndex + "NotOnO rAfter".le ngth + 2, endTimeInd ex + "NotO nOrAfter". length + 2 +20); | |
| 37 | va r end = ne w Date(end TimeString ).getTime( ); | |
| 38 | ||
| 39 | // Note: VA c omputer cl ocks are c ontrolled by IT, so it should be safe to assume th at clocks are close enough to accurate t hat this i s a safe w ay to chec k | |
| 40 | if (new Date ().getTime () + 1000 * 30 > end ) //Inacti ve token, or token w ill be ina ctive in 3 0 seconds, so consid er it expi red | |
| 41 | return f alse; | |
| 42 | el se //Valid token tha t doesnt e xpire for at least 3 0 seconds from now | |
| 43 | return t rue; | |
| 44 | } | |
| 45 | else / /Invalid T oken - all valid tok ens must c ontain the NotOnOrAf ter token | |
| 46 | re turn false ; | |
| 47 | }; | |
| 48 | ||
| 49 | MCS.VIALog in.IsValid UserDuz = function ( ) { | |
| 50 | if (!M CS.VIALogi n.RunVista Integratio n()) | |
| 51 | re turn true; | |
| 52 | ||
| 53 | //To D o - Check for the du z field(s) | |
| 54 | var si de = MCS.V IALogin.Du zSide(); | |
| 55 | var du zMissing = false; | |
| 56 | if (si de == "bot h" || side == "pat") { | |
| 57 | du zMissing = Xrm.Page. getAttribu te("cvt_pa tuserduz") .getValue( ) == null; | |
| 58 | } | |
| 59 | if (si de == "bot h" || side == "pro") { | |
| 60 | du zMissing = duzMissin g ? true : Xrm.Page. getAttribu te("cvt_pr ouserduz") .getValue( ) == null; | |
| 61 | } | |
| 62 | ||
| 63 | return !duzMissi ng; | |
| 64 | ||
| 65 | //if ( duzMissing ) | |
| 66 | // return fal se; | |
| 67 | ||
| 68 | ////To Do - add in possibl e check to ensure th e user who got the t oken origi nally is t he same pe rson that is now tak ing action | |
| 69 | //var samlToken = Xrm.Page .getAttrib ute("cvt_s amltoken") != null ? Xrm.Page. getAttribu te("cvt_sa mltoken"). getValue() : null; | |
| 70 | //if ( samlToken == null) / /No token | |
| 71 | // return fal se; | |
| 72 | ||
| 73 | //var errorTag = samlToken .indexOf(" <wst:Reaso n>"); | |
| 74 | //if ( errorTag ! = -1) //Er rored Toke n | |
| 75 | // return fal se; | |
| 76 | ||
| 77 | //var notBeforeT imeIndex = samlToken .indexOf(" NotBefore" ); | |
| 78 | //if ( notBeforeT imeIndex ! = -1) { | |
| 79 | // var notBef oreString = samlToke n.substrin g(notBefor eTimeIndex + "NotBef ore".lengt h + 2, not BeforeTime Index + "N otBefore". length + 2 + 20); | |
| 80 | // var notBef ore = new Date(notBe foreString ).getTime( ); | |
| 81 | ||
| 82 | // //Note: VA computer clocks are controlle d by IT, s o it shoul d be safe to assume that clock s are clos e enough t o accurate that this is a safe way to ch eck | |
| 83 | // if (new Da te().getTi me() + 100 0 * 30 > n otBefore + 1000 * 60 * 60 * 4) //Inactiv e Duz, or Duz (which lasts 4 h ours from issue inst ant, aka n otBefore) will be in active in 30 seconds , so consi der it exp ired | |
| 84 | // return false; | |
| 85 | // else { | |
| 86 | // var em ailAddress = ""; | |
| 87 | // CrmRes tKit.Retri eve('Syste mUser', Xr m.Page.con text.getUs erId(), [' DomainName ','Interna lEMailAddr ess'], fal se) | |
| 88 | // .fail( function ( err) { | |
| 89 | // al ert("Inval id Vista L ogin (User Duz) - tr y logging in again. Details: " + MCS.cv t_Common.R estError(e rr)); | |
| 90 | // }).don e(function (data) { | |
| 91 | // if (data != null && da ta.d != nu ll) { | |
| 92 | // emailAdd ress = dat a.d.Domain Name; | |
| 93 | // if (emai lAddress.i ndexOf("@v a.gov") == -1) | |
| 94 | // emai lAddress = data.d.In ternalEMai lAddress; | |
| 95 | // } | |
| 96 | // }); | |
| 97 | // if (em ailAddress != "" && samlToken. toLowerCas e().indexO f(emailAdd ress.toLow erCase()) != -1) //V alid token that is a ssigned to you and i s good for at least 30 seconds from now | |
| 98 | // re turn true; | |
| 99 | // else | |
| 100 | // re turn false ; //this i s not your token | |
| 101 | // } | |
| 102 | //} | |
| 103 | //else //Invalid Token - a ll valid t okens must contain t he NotOnOr After toke n | |
| 104 | // return fal se; | |
| 105 | }; | |
| 106 | ||
| 107 | MCS.VIALog in.Saml = function ( ) { | |
| 108 | //MCS. VIALogin.I sValidSaml Token(); | |
| 109 | var ru nVista = M CS.VIALogi n.RunVista Integratio n(); | |
| 110 | if (ru nVista) | |
| 111 | MC S.VIALogin .GetSamlTo ken(); | |
| 112 | }; | |
| 113 | ||
| 114 | MCS.VIALog in.DuzSide = functio n () { | |
| 115 | var ty peCode = X rm.Page.co ntext.getQ ueryString Parameters ().etc; | |
| 116 | ||
| 117 | var ru nProSide = true; | |
| 118 | var ru nPatSide = true; | |
| 119 | if (ty peCode == 4214) { | |
| 120 | ru nPatSide = Xrm.Page. getAttribu te("cvt_ty pe").getVa lue() == f alse; | |
| 121 | ru nProSide = Xrm.Page. getAttribu te("cvt_te lehealthmo dality").g etValue() == false; | |
| 122 | } | |
| 123 | if (ru nPatSide & & runProSi de) | |
| 124 | re turn "both "; | |
| 125 | else i f (runPatS ide) | |
| 126 | re turn "pat" ; | |
| 127 | else i f (runProS ide) | |
| 128 | re turn "pro" ; | |
| 129 | else | |
| 130 | re turn null; | |
| 131 | } | |
| 132 | ||
| 133 | MCS.VIALog in.Login = function () { | |
| 134 | var ru nVista = M CS.VIALogi n.RunVista Integratio n(); | |
| 135 | if (!r unVista) | |
| 136 | re turn; | |
| 137 | Xrm.Pa ge.ui.tabs .get('serv ice').sect ions.get(' VistaLogin ').setVisi ble(true); | |
| 138 | if (Xr m.Page.get Attribute( "cvt_samlt oken").get Value() == null) { | |
| 139 | re turn; | |
| 140 | } | |
| 141 | var si de = MCS.V IALogin.Du zSide(); | |
| 142 | ||
| 143 | if (MC S.VIALogin .GetSettin g("VIA Log in Endpoin t") != "") | |
| 144 | MC S.VIALogin .LoginToVi aBah(side) ; | |
| 145 | else | |
| 146 | MC S.VIALogin .ViaLoginV imt(side); | |
| 147 | }; | |
| 148 | ||
| 149 | MCS.VIALog in.RunVist aIntegrati on = funct ion () { | |
| 150 | var ty peCode = X rm.Page.co ntext.getQ ueryString Parameters ().etc; | |
| 151 | //if b lock resou rce and th eres no re lated appo intment | |
| 152 | if (ty peCode == 4201 && Xr m.Page.get Attribute( "cvt_servi ceactivity id").getVa lue() == n ull) | |
| 153 | re turn false ; | |
| 154 | //if a ppointment and no ts a is set | |
| 155 | if (ty peCode == 4214 && (X rm.Page.ge tAttribute ("mcs_rela tedtsa") = = null || Xrm.Page.g etAttribut e("mcs_rel atedtsa"). getValue() == null)) | |
| 156 | re turn false ; | |
| 157 | //if a ppt and cl inic based Group | |
| 158 | if (ty peCode == 4214 && (! Xrm.Page.g etAttribut e("cvt_typ e").getVal ue() && Xr m.Page.get Attribute( "mcs_group appointmen t").getVal ue())) | |
| 159 | re turn false ; | |
| 160 | var st ateCode = Xrm.Page.g etAttribut e('stateco de').getVa lue(); | |
| 161 | //if n ot active | |
| 162 | if (st ateCode != 3 && Xrm. Page.ui.ge tFormType( ) != 1) | |
| 163 | re turn false ; | |
| 164 | //If v ista integ ration swi tch is tur ned off | |
| 165 | if (!M CS.VIALogi n.CheckVis taSwitches ()) | |
| 166 | re turn false ; | |
| 167 | return true; | |
| 168 | }; | |
| 169 | ||
| 170 | // ******* ********** ********** ********** ********** *STS Retri eval Funct ions****** ********** ********** ********** ********** ****** | |
| 171 | //Retrieve s the SSOi SAML Toke n either t hrough Kee p Alive or through D irect IAM STS depend ing on whi ch URLs ar e availabl e | |
| 172 | MCS.VIALog in.GetSaml Token = fu nction () { | |
| 173 | var re freshUrl = MCS.VIALo gin.GetKee pAliveUrl( ); | |
| 174 | var ke epAliveLog inUrl = MC S.VIALogin .GetKeepAl iveLoginUr l(); | |
| 175 | var di rectIamUrl = MCS.VIA Login.GetS tsUrl(); | |
| 176 | ||
| 177 | if (re freshUrl ! = "" && ke epAliveLog inUrl != " ") | |
| 178 | MC S.VIALogin .RefreshTo ken(); | |
| 179 | else i f (directI amUrl != " ") | |
| 180 | MC S.VIALogin .CallIamSt s(directIa mUrl); | |
| 181 | else { | |
| 182 | al ert("No PI V Authenti cation has been set up"); | |
| 183 | va r fake = ' <?xml vers ion="1.0" encoding=" UTF- 8"?>< soapenv:E nvelope xm lns: wsa = "http://w ww.w3.org/ 2005/08/ad dressing" xmlns: xsi = "http:/ /www.w3.or g/2001/XML Schema-ins tance" xml ns: xsd = "http://ww w.w3.org/2 001/XMLSch ema" xmlns : Soapenv = "http:// schemas.xm lsoap.org/ soap/envel ope/" xmln s: wst = " http://sch emas.xmlso ap.org/ws/ 2005/02/tr ust" > <so apenv:Head er><ns1:Se curity soa penv:mustU nderstand= "0" xmlns: ns1="http: //docs.oas is-open.or g/wss/2004 /01/oasis- 200401-wss -wssecurit y-secext-1 .0.xsd"><n s2:Timesta mp xmlns:n s2="http:/ /docs.oasi s-open.org /wss/2004/ 01/oasis-2 00401-wss- wssecurity -utility-1 .0.xsd"><n s2:Created >2017-11-2 7T19:37:26 Z</ns2:Cre ated ></ns 2: Timesta mp ></ns1: Security ></soapenv : Header > <soapenv: Body><wst: RequestSec urityToken Response>< wst:Reques tType>http ://schemas .xmlsoap.o rg/ws/2005 /02/trust/ Issue</wst :RequestTy pe > <wst: TokenType> http://doc s.oasis-op en.org/wss /oasis-wss -saml-toke n-profile- 1.1#SAMLV2 .0</wst:To kenType > <wst:Statu s><wst:Cod e>http://d ocs.oasis- open.org/w s-sx/ws-tr ust/200512 /status/In valid</wst :Code > <w st:Reason> BACK_END_C ONNECTION_ FAILED: Ba ck End Aut h Provider Connectio n Failed.< /wst:Reaso n ></wst: Status ></ wst: Reque stSecurity TokenRespo nse ></soa penv: Body ></soapen v: Envelop e >'; | |
| 184 | Xr m.Page.get Attribute( "cvt_samlt oken").set Value(fake ); | |
| 185 | Xr m.Page.get Attribute( "cvt_samlt oken").fir eOnChange( ); | |
| 186 | } | |
| 187 | }; | |
| 188 | ||
| 189 | //Retrieve s the Toke n from IAM directly | |
| 190 | MCS.VIALog in.CallIam Sts = func tion (iamU rl) { | |
| 191 | var po ststring = "<soapenv :Envelope xmlns:soap env=\"http ://schemas .xmlsoap.o rg/soap/en velope/\" xmlns:ns=\ "http://do cs.oasis-o pen.org/ws -sx/ws-tru st/200512\ ">" | |
| 192 | + "<soapenv: Header/>" | |
| 193 | + "<soapenv: Body>" | |
| 194 | + "<ns:Reque stSecurity Token>" | |
| 195 | + "<ns:Base> " | |
| 196 | + "<wss:TLS xmlns:wss= \"http://d ocs.oasis- open.org/w ss/2004/01 /oasis-200 401-wss-ws security-s ecext-1.0. xsd\"/>" | |
| 197 | + "</ns:Base >" | |
| 198 | + "<wsp:Appl iesTo xmln s:wsp=\"ht tp://schem as.xmlsoap .org/ws/20 04/09/poli cy\">" | |
| 199 | + "<wsa:Endp ointRefere nce xmlns: wsa=\"http ://schemas .xmlsoap.o rg/ws/2004 /08/addres sing\">" | |
| 200 | + "<wsa:Ad dress>http s:// DNS /TMP</wsa: Address>" | |
| 201 | + "</wsa:End pointRefer ence>" | |
| 202 | + "</wsp:App liesTo>" | |
| 203 | + "<ns:Issue r>" | |
| 204 | + "<wsa:Ad dress xmln s:wsa=\"ht tp://schem as.xmlsoap .org/ws/20 04/08/addr essing\">h ttps:// DNS /Issuer/sm token/SAML 2</wsa:Add ress>" | |
| 205 | + "</ns:Issu er>" | |
| 206 | + "<ns:Reque stType>htt p://schema s.xmlsoap. org/ws/200 5/02/trust /Validate< /ns:Reques tType>" | |
| 207 | + "</ns:Requ estSecurit yToken>" | |
| 208 | + "</soapenv :Body>" | |
| 209 | + "</soapenv :Envelope> " | |
| 210 | ; | |
| 211 | url = iamUrl == null ? MCS .VIALogin. GetStsUrl( ) : iamUrl ; | |
| 212 | //$.su pport.cors = true; | |
| 213 | $.get( url).done( function ( ) { | |
| 214 | $. ajax({ | |
| 215 | url: url , | |
| 216 | type: 'P OST', | |
| 217 | crossDom ain: true, | |
| 218 | data: po ststring, | |
| 219 | contentT ype: 'text /plain', | |
| 220 | dataType : 'text', | |
| 221 | success: function (result) { | |
| 222 | Xrm. Page.getAt tribute("c vt_samltok en").setVa lue(result ); | |
| 223 | Xrm. Page.getAt tribute("c vt_samltok en").fireO nChange(); | |
| 224 | }, | |
| 225 | error: f unction (j qXHR, tran Status, er rorThrown) { | |
| 226 | aler t("Unable to Get SAM L token to log into Vista\n" + | |
| 227 | 'Status: ' + jqXHR.s tatus + ' ' + jqXHR. statusText + '. ' + | |
| 228 | 'Response: ' + jqXHR .responseT ext | |
| 229 | ); | |
| 230 | } | |
| 231 | }) ; | |
| 232 | }).fai l(function (err) { | |
| 233 | al ert("Failu re to Get SAML token to log in to Vista\n " + | |
| 234 | 'Status: ' + err.s tatus + ' ' + err.st atusText + '. ' + | |
| 235 | 'Respons e: ' + err .responseT ext | |
| 236 | ); | |
| 237 | }); | |
| 238 | ||
| 239 | }; | |
| 240 | ||
| 241 | //Function calls the refresh e ndpoint an d sets the resulting SAML toke n onto the form if t he call is successfu l, otherwi se keeps c alling its elf every 5 seconds | |
| 242 | MCS.VIALog in.Refresh Token = fu nction () { | |
| 243 | MCS.VI ALogin.Ref reshes++; | |
| 244 | var ur l = MCS.VI ALogin.Get KeepAliveU rl(); | |
| 245 | var to ken = ""; | |
| 246 | $.ajax ({ | |
| 247 | ur l: url, | |
| 248 | su ccess: fun ction (res ult) { | |
| 249 | if (resu lt != null ) | |
| 250 | toke n = result .SAMLToken ; | |
| 251 | if (toke n != null && token ! = "") { | |
| 252 | Xrm. Page.getAt tribute("c vt_samltok en").setVa lue(token) ; | |
| 253 | Xrm. Page.getAt tribute("c vt_samltok en").fireO nChange(); | |
| 254 | } | |
| 255 | else if (MCS.VIALo gin.Refres hes == 1) | |
| 256 | aler t("Please login with your PIN in the new window to sign into Vista."); | |
| 257 | }, | |
| 258 | er ror: funct ion (reque st, status , error) { | |
| 259 | alert("T oken Refre sh call fa iled: " + request.re sponseText + "; info : " + requ est.status Text); | |
| 260 | }, | |
| 261 | co mplete: fu nction () { | |
| 262 | if (Xrm. Page.getAt tribute("c vt_samltok en").getVa lue() == n ull && MCS .VIALogin. Refreshes < 4) { | |
| 263 | setT imeout(MCS .VIALogin. RefreshTok en, 15000) ; | |
| 264 | MCS. VIALogin.K eepSession Alive(); | |
| 265 | } | |
| 266 | } | |
| 267 | ||
| 268 | }); | |
| 269 | }; | |
| 270 | ||
| 271 | //Funtion to open th e Keep Ali ve page (i f its alre ady open, then it wi ll just fo rce focus to it) | |
| 272 | MCS.VIALog in.KeepSes sionAlive = function () { | |
| 273 | var ur l = MCS.VI ALogin.Get KeepAliveL oginUrl(); | |
| 274 | ssoiWi ndow = win dow.open(u rl, | |
| 275 | MC S.VIALogin .KeepAlive WindowName , | |
| 276 | 'h eight=500, width=865 , location =yes, resi zable=yes, scrollbar s=yes, sta tus=yes, t itlebar=ye s, top=100 , left=100 ', | |
| 277 | tr ue | |
| 278 | ); | |
| 279 | ssoiWi ndow.focus (); | |
| 280 | return ; | |
| 281 | }; | |
| 282 | ||
| 283 | // ******* ********** ********** ********** *****VIA L ogin Funct ions****** ********** ********** ********** ********** * | |
| 284 | ////////// ////////// ///iHub Vi aLogin | |
| 285 | //main met hod to log into VIA using BAH' s VIA Logi n Web Part (iHub) | |
| 286 | MCS.VIALog in.LoginTo ViaBah = f unction (s ide) { | |
| 287 | var ur l = MCS.VI ALogin.Via LoginUrl() ; | |
| 288 | var to ken = Xrm. Page.getAt tribute("c vt_samltok en").getVa lue(); | |
| 289 | if (to ken == nul l || token == "") { | |
| 290 | al ert("No VI A Login co mpleted be cause SAML token not found. " ); | |
| 291 | re turn; | |
| 292 | } | |
| 293 | ||
| 294 | if (si de == "bot h") { | |
| 295 | va r patFacil ityNumber = MCS.VIAL ogin.GetFa cilityNumb er("pat"); | |
| 296 | va r proFacil ityNumber = MCS.VIAL ogin.GetFa cilityNumb er("pro"); | |
| 297 | va r patMessa ge = MCS.V IALogin.Se tupViaMess age(patFac ilityNumbe r, token); | |
| 298 | va r patDuz = MCS.VIALo gin.CallBa hLogin(pat Message); | |
| 299 | Xr m.Page.get Attribute( "cvt_patus erduz").se tValue(pat Duz); | |
| 300 | ||
| 301 | if (patFacil ityNumber != proFaci lityNumber ) { | |
| 302 | var proM essage = M CS.VIALogi n.SetupVia Message(pr oFacilityN umber, tok en); | |
| 303 | var proD uz = MCS.V IALogin.Ca llBahLogin (proMessag e); | |
| 304 | if (proD uz != "") { | |
| 305 | Xrm. Page.getAt tribute("c vt_prouser duz").setV alue(proDu z); | |
| 306 | MCS. VIALogin.T riggerGetC onsults(); | |
| 307 | } | |
| 308 | else | |
| 309 | aler t("No VIA Login comp leted for pro side") ; | |
| 310 | } | |
| 311 | el se { | |
| 312 | if (patD uz != "") { | |
| 313 | //Bo th sides a re the sam e, so use the same l ogin (duz) for pat a nd pro sid e | |
| 314 | Xrm. Page.getAt tribute("c vt_prouser duz").setV alue(patDu z); | |
| 315 | MCS. VIALogin.T riggerGetC onsults(); | |
| 316 | } | |
| 317 | else | |
| 318 | aler t("No VIA Login comp leted for pat side") ; | |
| 319 | } | |
| 320 | } | |
| 321 | else { | |
| 322 | va r facility = MCS.VIA Login.GetF acilityNum ber(side); | |
| 323 | va r message = MCS.VIAL ogin.Setup ViaMessage (facility, token); | |
| 324 | va r duz = MC S.VIALogin .CallBahLo gin(messag e); | |
| 325 | if (duz != " ") { | |
| 326 | Xrm.Page .getAttrib ute("cvt_" + side + "userduz") .setValue( duz); | |
| 327 | MCS.VIAL ogin.Trigg erGetConsu lts(); | |
| 328 | } | |
| 329 | el se | |
| 330 | alert("N o VIA Logi n complete d for " + side + "si de"); | |
| 331 | } | |
| 332 | }; | |
| 333 | ||
| 334 | MCS.VIALog in.Trigger GetConsult s = functi on () { | |
| 335 | var ty pecode = X rm.Page.co ntext.getQ ueryString Parameters ().etc; | |
| 336 | if (ty pecode == 4214) | |
| 337 | Xr m.Page.get Attribute( "cvt_runge tconsults" ).fireOnCh ange(); | |
| 338 | }; | |
| 339 | ||
| 340 | //Helper m ethod tp P repare the VIA Login Message | |
| 341 | MCS.VIALog in.SetupVi aMessage = function (facilityN umber, tok en) { | |
| 342 | var vi aMessage = {}; | |
| 343 | viaMes sage.Acces sCode = "d onotuse"; | |
| 344 | viaMes sage.Verif yCode = "d onotuse"; | |
| 345 | viaMes sage.SiteI d = facili tyNumber; | |
| 346 | viaMes sage.SamlT oken = tok en; | |
| 347 | return viaMessag e; | |
| 348 | }; | |
| 349 | ||
| 350 | //Helper m ethod call ed by VIA Login whic h performs the ajax call and r eturns the resulting Duz (if e xists) | |
| 351 | MCS.VIALog in.CallBah Login = fu nction (me ssage, url ) { | |
| 352 | var du z = ""; | |
| 353 | $.ajax ({ | |
| 354 | as ync: false , | |
| 355 | ty pe: 'POST' , | |
| 356 | ur l: url, | |
| 357 | be foreSend: function ( request) { | |
| 358 | request. setRequest Header("CR MSSOiSessi onSaml", w indow.btoa (message.S amlToken)) | |
| 359 | }, | |
| 360 | da taType: 'j son', | |
| 361 | co ntentType: 'applicat ion/json', | |
| 362 | da ta: JSON.s tringify(m essage), | |
| 363 | su ccess: fun ction (dat a, textSta tus, jqXHR ) { | |
| 364 | if (data == null | | data.Dat a == null || data.Da ta[0] == n ull || dat a.Data[0]. Duz == nul l) { | |
| 365 | if ( data == nu ll) | |
| 366 | alert("No data retur ned"); | |
| 367 | else if (data. Data == nu ll || data .Data[0] = = null) | |
| 368 | alert("Emp ty Data" + data.Erro rMessage); | |
| 369 | else if (data. Data[0].Fa ult != nul l) | |
| 370 | alert("Fai led to log in: " + da ta.Data[0] .Fault.Mes sage) | |
| 371 | } | |
| 372 | else { | |
| 373 | if ( data.Data[ 0].Duz != null) | |
| 374 | duz = data .Data[0].D uz; | |
| 375 | } | |
| 376 | ||
| 377 | }, | |
| 378 | er ror: funct ion (jqXHR , textStat us, errorT hrown) { | |
| 379 | alert(te xtStatus + ". Error : " + erro rThrown); | |
| 380 | return " "; | |
| 381 | } | |
| 382 | }); | |
| 383 | return duz; | |
| 384 | }; | |
| 385 | ||
| 386 | ////////// ////////// /EC ViaLog in | |
| 387 | //main met hod to log into VIA using VIMT EC (throu gh Actions /CWF/LOB) | |
| 388 | MCS.VIALog in.ViaLogi nVimt = fu nction (si de, access , verify) { | |
| 389 | var sa mlToken = Xrm.Page.g etAttribut e("cvt_sam ltoken").g etValue(); | |
| 390 | if (si de == "bot h") { | |
| 391 | va r patStati onNumber = MCS.VIALo gin.GetFac ilityNumbe r("pat"); | |
| 392 | va r proStati onNumber = MCS.VIALo gin.GetFac ilityNumbe r("pro"); | |
| 393 | if (patStati onNumber ! = proStati onNumber) { | |
| 394 | MCS.VIAL ogin.Login WithAction (samlToken , patStati onNumber, "pat", acc ess, verif y); | |
| 395 | MCS.VIAL ogin.Login WithAction (samlToken , proStati onNumber, "pro", acc ess, verif y); | |
| 396 | } | |
| 397 | el se { | |
| 398 | MCS.VIAL ogin.Login WithAction (samlToken , proStati onNumber, side, acce ss, verify ); | |
| 399 | } | |
| 400 | } | |
| 401 | else { | |
| 402 | va r stationN umber = MC S.VIALogin .GetFacili tyNumber(s ide); | |
| 403 | MC S.VIALogin .LoginWith Action(sam lToken, st ationNumbe r, side, a ccess, ver ify); | |
| 404 | } | |
| 405 | }; | |
| 406 | ||
| 407 | //Calls th e action a nd sets th e resultin g DUZ onto the page or else ca lls the Lo gin throug h Access-V erify code s | |
| 408 | MCS.VIALog in.LoginWi thAction = function (samlToken , stationN umber, sid e, access, verify) { | |
| 409 | var re questName = "cvt_Via LoginActio n"; | |
| 410 | ||
| 411 | var re questParam s = | |
| 412 | [{ | |
| 413 | Key: "St ationNumbe r", | |
| 414 | Type: MC S.Scripts. Process.Da taType.Str ing, | |
| 415 | Value: s tationNumb er | |
| 416 | }, | |
| 417 | { | |
| 418 | Key: "Sa mlToken", | |
| 419 | Type: MC S.Scripts. Process.Da taType.Str ing, | |
| 420 | Value: s amlToken | |
| 421 | }, | |
| 422 | { | |
| 423 | Key: "Ac cessCode", | |
| 424 | Type: MC S.Scripts. Process.Da taType.Str ing, | |
| 425 | Value: t ypeof(acce ss) === "u ndefined" ? "" : acc ess | |
| 426 | }, | |
| 427 | { | |
| 428 | Key: "Ve rifyCode", | |
| 429 | Type: MC S.Scripts. Process.Da taType.Str ing, | |
| 430 | Value: t ypeof(veri fy) === "u ndefined" ? "" : ver ify | |
| 431 | }] ; | |
| 432 | ||
| 433 | MCS.Sc ripts.Proc ess.Execut eAction(re questName, requestPa rams) | |
| 434 | .d one(functi on (respon se) { | |
| 435 | // Succe ss | |
| 436 | var user Duz = resp onse.UserD uz; | |
| 437 | var succ ess = resp onse.Succe ssfulLogin ; | |
| 438 | var erro rMessage = response. ErrorMessa ge; | |
| 439 | //alert( "Duz: " + userDuz + "\nError: " + errorM essage); | |
| 440 | ||
| 441 | if (succ ess) { | |
| 442 | if ( side == "b oth") { | |
| 443 | Xrm.Page.g etAttribut e("cvt_pro userduz"). setValue(u serDuz); | |
| 444 | Xrm.Page.g etAttribut e("cvt_pat userduz"). setValue(u serDuz); | |
| 445 | } | |
| 446 | else | |
| 447 | Xrm.Page.g etAttribut e("cvt_" + side + "u serduz").s etValue(us erDuz); | |
| 448 | //if (MCS.VIAL ogin.Getti ngNewUserD uz) | |
| 449 | //// { | |
| 450 | // MCS.VIAL ogin.Getti ngNewUserD uz = false ; | |
| 451 | // //SaveSA (); | |
| 452 | //// } | |
| 453 | //el se | |
| 454 | MCS.VIALog in.Trigger GetConsult s(); | |
| 455 | } | |
| 456 | else { | |
| 457 | var useAVCodes = confirm ("Failed t o log in w ith PIV, a ttempting Access Ver ify Codes for " + si de + " sid e. Error Details: " + errorMe ssage); | |
| 458 | if ( useAVCodes ) | |
| 459 | MCS.VIALog in.LoginWi thAccessVe rify(side, samlToken , stationN umber); | |
| 460 | //el se { | |
| 461 | // if (MCS. VIALogin.G ettingNewU serDuz) { | |
| 462 | // MCS. VIALogin.G ettingNewU serDuz = f alse; | |
| 463 | // aler t("Canceli ng Save"); | |
| 464 | // } | |
| 465 | //} | |
| 466 | } | |
| 467 | }) | |
| 468 | .f ail(functi on (err) { | |
| 469 | alert("L ogin Actio n Failed: " + err.re sponseText ); | |
| 470 | //if (MC S.VIALogin .GettingNe wUserDuz) | |
| 471 | // MC S.VIALogin .GettingNe wUserDuz = false; | |
| 472 | }) ; | |
| 473 | }; | |
| 474 | ||
| 475 | //Helper t o re-call LoginVIMT using acce ssVerify e ntered by user promp t - user c an leave b lank or hi t cancel t o end loop | |
| 476 | MCS.VIALog in.LoginWi thAccessVe rify = fun ction (sid e, samlTok en, statio nNumber) { | |
| 477 | //var cancelLogi n = false; | |
| 478 | var fa cilityStri ng = side == "both" ? "the" : "the " + s ide; | |
| 479 | var ac cessCode = prompt("P lease ente r your acc ess code f or " + fac ilityStrin g + " faci lity (" + stationNum ber + ")." , ""); | |
| 480 | var ve rifyCode; | |
| 481 | if (ac cessCode ! = null && accessCode != "") { | |
| 482 | ve rifyCode = prompt("P lease ente r your ver ify code f or " + fac ilityStrin g + " faci lity (" + stationNum ber + ")." , ""); | |
| 483 | if (verifyCo de != null && verify Code != "" ) | |
| 484 | MCS.VIAL ogin.Login WithAction (samlToken , stationN umber, sid e, accessC ode, verif yCode); | |
| 485 | // else | |
| 486 | // cancel Login = tr ue; | |
| 487 | } | |
| 488 | //else | |
| 489 | // cancelLogi n = true; | |
| 490 | //if ( cancelLogi n) | |
| 491 | // MCS.VIALog in.Getting NewUserDuz = true; | |
| 492 | }; | |
| 493 | ||
| 494 | // ******* ********** *******Hel per method s to retri eve Integr ation Sett ings (URLS ) ******** ********** ********** ********* | |
| 495 | //Helper M ethod to g et SAML To ken URL | |
| 496 | MCS.VIALog in.GetStsU rl = funct ion () { | |
| 497 | var defaul tUrl = ""; // "https: // URL : PORT /STS/Reque stSecurity Token"; | |
| 498 | var ur l = MCS.VI ALogin.Get Setting("I AM SAML To ken Endpoi nt"); | |
| 499 | return url != "" ? url : d efaultUrl; | |
| 500 | }; | |
| 501 | ||
| 502 | //Helper m ethod to g et the Kee p Alive Lo gin Page | |
| 503 | MCS.VIALog in.GetKeep AliveLogin Url = func tion () { | |
| 504 | var defaul tUrl = ""; //"https:/ / URL /CRMSSOi/q a/default. aspx"; | |
| 505 | var ur l = MCS.VI ALogin.Get Setting("K eep Alive Login Endp oint"); | |
| 506 | return url != "" ? url : d efaultUrl; | |
| 507 | }; | |
| 508 | ||
| 509 | //Helper M ethod to g et the url to refres h your tok en (assumi ng you hav e already called the login pag e) | |
| 510 | MCS.VIALog in.GetKeep AliveUrl = function () { | |
| 511 | var defaul tUrl = ""; // "https: // URL /CRMSSOi/q a/refresht okensessio n.aspx"; | |
| 512 | var ur l = MCS.VI ALogin.Get Setting("R efresh SAM L Token En dpoint"); | |
| 513 | return url != "" ? url : d efaultUrl; | |
| 514 | }; | |
| 515 | ||
| 516 | //Helper M ethod to g et BAH VIA Login iHu b Endpoint URL | |
| 517 | MCS.VIALog in.ViaLogi nUrl = fun ction () { | |
| 518 | var ur l = MCS.VI ALogin.Get Setting("V IA Login E ndpoint"); | |
| 519 | var defaul tUrl = ""; //"https:/ / URL /WebParts/ DEV/api/VI A/LoginVIA /2.1/json" ; | |
| 520 | return url != "" ? url : d efaultUrl; | |
| 521 | }; | |
| 522 | ||
| 523 | //Helper m ethod to g et any int egration s etting wit h the pass ed in name | |
| 524 | MCS.VIALog in.GetSett ing = func tion (name ) { | |
| 525 | var va lue = ""; | |
| 526 | var fi lter = "mc s_name eq '" + name + "'"; | |
| 527 | calls = CrmRestK it.ByQuery ("mcs_inte grationset ting", ['m cs_value'] , filter, false); | |
| 528 | calls. fail(funct ion (err) { | |
| 529 | re turn value ; | |
| 530 | }).don e(function (data) { | |
| 531 | if (data && data.d && data.d.res ults != nu ll && data .d.results .length != 0) { | |
| 532 | value = data.d.res ults[0].mc s_value | |
| 533 | } | |
| 534 | }) ; | |
| 535 | return value; | |
| 536 | }; | |
| 537 | ||
| 538 | //Helper m ethod to g et the TSA id whethe r the curr ent record is an app t or a blo ck resourc e | |
| 539 | MCS.VIALog in.GetTsaI d = functi on () { | |
| 540 | var ts aObj = Xrm .Page.getA ttribute(" mcs_relate dtsa"); | |
| 541 | if (ts aObj != nu ll) | |
| 542 | re turn tsaOb j.getValue ()[0].id; | |
| 543 | var ts aId; | |
| 544 | var sa = Xrm.Pag e.getAttri bute("cvt_ serviceact ivityid"). getValue() [0].id; | |
| 545 | CrmRes tKit.Retri eve('Servi ceAppointm ent', sa, ['mcs_rela tedtsa'], false) | |
| 546 | .f ail(functi on (err) { | |
| 547 | alert("f ailed TSA check, Una ble to per form VIA l ogin: " + MCS.cvt_Co mmon.RestE rror(err)) ; | |
| 548 | }) | |
| 549 | .d one(functi on (data) { | |
| 550 | if (data != null & & data.d ! = null) { | |
| 551 | tsaI d = data.d .mcs_relat edtsa.Id; | |
| 552 | } | |
| 553 | }) ; | |
| 554 | return tsaId; | |
| 555 | }; | |
| 556 | ||
| 557 | //Helper m ethod to g et the sta tion numbe r of the f acility | |
| 558 | MCS.VIALog in.GetFaci lityNumber = functio n (side) { | |
| 559 | var ts aId = MCS. VIALogin.G etTsaId(); | |
| 560 | var pa tFacId = n ull; | |
| 561 | var pr oFacId = n ull; | |
| 562 | var is InterFacil ity = fals e; | |
| 563 | CrmRes tKit.Retri eve('mcs_s ervices', tsaId, ['c vt_Patient Facility', 'cvt_Prov iderFacili ty', 'cvt_ ServiceSco pe'], fals e) | |
| 564 | .f ail(functi on (err) { | |
| 565 | alert("f ailed TSA check, Una ble to per form VIA l ogin: " + MCS.cvt_Co mmon.RestE rror(err)) ; | |
| 566 | }) | |
| 567 | .d one(functi on (data) { | |
| 568 | if (data != null & & data.d ! = null) { | |
| 569 | if ( data.d.cvt _PatientFa cility != null) | |
| 570 | patFacId = data.d.cv t_PatientF acility.Id ; | |
| 571 | if ( data.d.cvt _ProviderF acility != null) | |
| 572 | proFacId = data.d.cv t_Provider Facility.I d; | |
| 573 | if ( data.d.cvt _ServiceSc ope != nul l) | |
| 574 | isInterFac ility = da ta.d.cvt_S erviceScop e.Value == 917290000 ; | |
| 575 | } | |
| 576 | }) ; | |
| 577 | var id = side == "pat" ? p atFacId : proFacId; | |
| 578 | var fa cilityNumb er; | |
| 579 | CrmRes tKit.Retri eve('mcs_f acility', id, ['mcs_ StationNum ber'], fal se) | |
| 580 | .f ail(functi on (err) { | |
| 581 | alert("F ailed to g et TSA, Un able to Pe rform VIA Login: " + MCS.cvt_C ommon.Rest Error(err) ); | |
| 582 | }) .done(func tion (data ) { | |
| 583 | if (data != null & & data.d ! = null) | |
| 584 | faci lityNumber = data.d. mcs_Statio nNumber; | |
| 585 | else | |
| 586 | aler t("Failed to get TSA station n umber, Una ble to Per form VIA L ogin"); | |
| 587 | }) ; | |
| 588 | return facilityN umber; | |
| 589 | }; | |
| 590 | ||
| 591 | MCS.VIALog in.CheckVi staSwitche s = functi on () { | |
| 592 | var Vi staSwitche sConfig = true; | |
| 593 | var ba seSwitchCo nfig = tru e; | |
| 594 | var hm Config = t rue; | |
| 595 | var if cConfig = true; | |
| 596 | var si ngleNonHmC onfig = tr ue; | |
| 597 | var fi lter = "mc s_name eq 'Active Se ttings'"; | |
| 598 | calls = CrmRestK it.ByQuery ("mcs_sett ing", ['cv t_UseVista Integratio n', 'cvt_U seVVSHomeM obile', 'c vt_UseVVSI nterfacili ty', 'cvt_ UseVVSSing leEncounte rNonHomeMo bile'], fi lter, fals e); | |
| 599 | calls. fail(funct ion (err) { | |
| 600 | re turn Vista SwitchesCo nfig; | |
| 601 | }).don e(function (data) { | |
| 602 | if (data && data.d && data.d.res ults != nu ll && data .d.results .length != 0) { | |
| 603 | var reco rd = data. d.results[ 0]; | |
| 604 | baseSwit chConfig = record.cv t_UseVista Integratio n != null ? record.c vt_UseVist aIntegrati on : true; | |
| 605 | hmConfig = record. cvt_UseVVS HomeMobile != null ? record.cv t_UseVVSHo meMobile : true; | |
| 606 | ifcConfi g = record .cvt_UseVV SInterfaci lity != nu ll ? recor d.cvt_UseV VSInterfac ility : tr ue; | |
| 607 | singleNo nHmConfig = record.c vt_UseVVSS ingleEncou nterNonHom eMobile != null ? re cord.cvt_U seVVSSingl eEncounter NonHomeMob ile : true ; | |
| 608 | } | |
| 609 | }); | |
| 610 | //Note that this is a trip le equal, not a doub le, so a n ull value is conside red accept able to co ntinue, on ly a false will mean "don't sh ow Get Con sults" | |
| 611 | if (ba seSwitchCo nfig === f alse) | |
| 612 | re turn false ; | |
| 613 | var ap ptTypeChec k = MCS.VI ALogin.App ointmentTy peSwitchCh eck(hmConf ig, ifcCon fig, singl eNonHmConf ig); | |
| 614 | return apptTypeC heck; | |
| 615 | }; | |
| 616 | ||
| 617 | MCS.VIALog in.Appoint mentTypeSw itchCheck = function (hmConfig , ifcConfi g, singleN onHmConfig ) { | |
| 618 | var Xr m = parent .Xrm; | |
| 619 | var ts aId = MCS. VIALogin.G etTsaId(); | |
| 620 | var pa tFacId = n ull; | |
| 621 | var pr oFacId = n ull; | |
| 622 | var su bSpecialty = null; | |
| 623 | var sp ecialty = null; | |
| 624 | var is InterFacil ity = fals e; | |
| 625 | CrmRes tKit.Retri eve('mcs_s ervices', tsaId, ['c vt_Patient Facility', 'cvt_Prov iderFacili ty', 'cvt_ ServiceSco pe', 'cvt_ servicetyp e', 'cvt_s ervicesubt ype', 'cvt _relatedpr ovidersite id', 'cvt_ relatedpat ientsiteid '], false) | |
| 626 | .f ail(functi on (err) { | |
| 627 | alert("f ailed TSA check, def aulting to display C onsults" + MCS.cvt_C ommon.Rest Error(err) ); | |
| 628 | }) | |
| 629 | .d one(functi on (data) { | |
| 630 | if (data != null & & data.d ! = null) { | |
| 631 | if ( data.d.cvt _PatientFa cility != null) | |
| 632 | patFacId = data.d.cv t_PatientF acility.Id ; | |
| 633 | if ( data.d.cvt _ProviderF acility != null) | |
| 634 | proFacId = data.d.cv t_Provider Facility.I d; | |
| 635 | if ( data.d.cvt _ServiceSc ope != nul l) | |
| 636 | isInterFac ility = da ta.d.cvt_S erviceScop e.Value == 917290000 ; | |
| 637 | if ( data.d.cvt _servicety pe != null ) | |
| 638 | specialty = data.d.c vt_service type.Id; | |
| 639 | if ( data.d.cvt _servicesu btype != n ull) | |
| 640 | subSpecial ty = data. d.cvt_serv icesubtype .Id; | |
| 641 | if ( data.d.cvt _relatedpr ovidersite id != null ) | |
| 642 | TsaProvide rSiteId = data.d.cvt _relatedpr ovidersite id.Id; //T his is key to run ea ch time TS A is set b ecause the Provider Site does not come t hrough unt il after T SA js has run, but t his functi on runs be fore TSA j s is compl ete, so pu lling in T SAProvider SiteId wil l set prov iderSiteId when its not otherw ise popula ted | |
| 643 | if ( data.d.cvt _relatedpr ovidersite id != null ) | |
| 644 | TsaPatient SiteId = d ata.d.cvt_ relatedpat ientsiteid .Id; | |
| 645 | } | |
| 646 | }) ; | |
| 647 | ||
| 648 | var ts aObj = Xrm .Page.getA ttribute(" mcs_relate dtsa"); | |
| 649 | if (ts aObj != nu ll) { | |
| 650 | ||
| 651 | va r isHomeMo bile = Xrm .Page.getA ttribute(" cvt_type") .getValue( ); | |
| 652 | if (isHomeMo bile) | |
| 653 | return h mConfig; | |
| 654 | va r isSingle NonHm = Xr m.Page.get Attribute( "cvt_teleh ealthmodal ity").getV alue(); | |
| 655 | if (isSingle NonHm) | |
| 656 | return s ingleNonHm Config; | |
| 657 | } | |
| 658 | ||
| 659 | var su bSpecialty Switch = n ull; | |
| 660 | if (su bSpecialty != null) { | |
| 661 | // Check SubS pecialty S witch | |
| 662 | Cr mRestKit.R etrieve('m cs_service subtype', subSpecial ty, ['cvt_ UseVVS'], false) | |
| 663 | .fail(fu nction (er r) { | |
| 664 | aler t("failed sub-specia lty type c heck, look ing for sp ecialty sw itch: " + MCS.cvt_Co mmon.RestE rror(err)) ; | |
| 665 | }).done( function ( data) { | |
| 666 | subS pecialtySw itch = dat a.d.cvt_Us eVVS; | |
| 667 | }); | |
| 668 | } | |
| 669 | //vari ous "===" is so that if the va lue is nul l, then we evaluate the next c ondition i nstead of considerin g it false | |
| 670 | if (su bSpecialty Switch === false) | |
| 671 | re turn false ; | |
| 672 | var sp ecialtySwi tch = true ; | |
| 673 | if (su bSpecialty Switch == null) { | |
| 674 | Cr mRestKit.R etrieve('m cs_service type', spe cialty, [' cvt_UseVVS '], false) | |
| 675 | .fail(fu nction (er r) { | |
| 676 | aler t("failed specialty type check , defaulti ng to disp lay Consul ts" + MCS. cvt_Common .RestError (err)); | |
| 677 | }) | |
| 678 | .done(fu nction (da ta) { | |
| 679 | spec ialtySwitc h = data.d .cvt_UseVV S; | |
| 680 | }); | |
| 681 | } | |
| 682 | if (sp ecialtySwi tch === fa lse) | |
| 683 | re turn false ; | |
| 684 | ||
| 685 | if (is InterFacil ity) | |
| 686 | re turn ifcCo nfig; | |
| 687 | ||
| 688 | var fa cilitySwit ch = true; | |
| 689 | ||
| 690 | if (pa tFacId != null && pr oFacId != null && pa tFacId == proFacId) { | |
| 691 | Cr mRestKit.R etrieve('m cs_facilit y', patFac Id, ['cvt_ UseVistaIn trafacilit y'], false ) | |
| 692 | .fail(fu nction (er r) { | |
| 693 | aler t("failed Intrafacil ity check, defaultin g to displ ay Consult s" + MCS.c vt_Common. RestError( err)); | |
| 694 | }) | |
| 695 | .done(fu nction (da ta) { | |
| 696 | if ( data != nu ll && data .d != null ) | |
| 697 | facilitySw itch = dat a.d.cvt_Us eVistaIntr afacility != null ? data.d.cvt _UseVistaI ntrafacili ty : true; | |
| 698 | }); | |
| 699 | } | |
| 700 | return facilityS witch === false ? fa lse : true ; | |
| 701 | }; |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.