72. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 9/9/2019 5:42:10 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.

72.1 Files compared

# Location File Last Modified
1 Webvram-v4.zip\20190725-webvram-source.zip\Sources\WebVRAM.VistA.Service\Services SyncService.cs Tue Jul 23 23:11:38 2019 UTC
2 Webvram-v4.zip\20190725-webvram-source.zip\Sources\WebVRAM.VistA.Service\Services SyncService.cs Fri Sep 6 20:51:21 2019 UTC

72.2 Comparison summary

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

72.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

72.4 Active regular expressions

No regular expressions were active.

72.5 Comparison detail

  1   using Syst em;
  2   using Syst em.Collect ions.Gener ic;
  3   using Syst em.Linq;
  4   using Syst em.Securit y.Claims;
  5   using Syst em.Threadi ng.Tasks;
  6   using Micr osoft.Exte nsions.Log ging;
  7   using Vist a.RPC;
  8   using Vist a.RPC.Exce ptions;
  9   using Vist a.RPC.Proc edures.DDR ;
  10   using Vist a.RPC.Proc edures.ORW U;
  11   using Vist a.RPC.Proc edures.XU;
  12   using Vist a.RPC.Proc edures.XUS ;
  13   using Vist a.RPC.Util ities;
  14   using WebV RAM.Vista. Models;
  15   using WebV RAM.Vista. Service.Ex ceptions;
  16   using WebV RAM.Vista. Service.Mo dels;
  17   using WebV RAM.Web.ng .Models;
  18  
  19   namespace  WebVRAM.Vi sta.Servic es
  20   {
  21       /// <s ummary>
  22       /// Th is VistA s ervice is  the core o f WebVRAM;  it provid es the syn chronizati on logic a nd rules
  23       /// </ summary>
  24       public  class Syn cService :  BaseServi ce<SyncSer vice>
  25       {
  26           pr ivate Vist aUserServi ce _vistaU serService ;
  27  
  28           pu blic SyncS ervice(ILo gger<SyncS ervice> lo gger, Vist aConfig vi staConfig,
  29                ClaimsPr incipal cl aimsPrinci pal, Vista UserServic e vistaUse rService)  : base(log ger, vista Config, cl aimsPrinci pal)
  30           {
  31                _vistaUs erService  = vistaUse rService;
  32           }
  33  
  34           pr ivate stat ic readonl y string A V_PUSH_SEC URITY_KEY  = "WEBG AV  PUSH";
  35  
  36           // / <summary >
  37           // / Gets a s et of Vist A security  keys that  are NOT a llowed to  be copied  during syn chronizati on
  38           // / </summar y>
  39           // / <returns >a set of  forbidden  security k eys</retur ns>
  40           pr ivate Hash Set<string > GetForbi ddenKeys()
  41           {
  42                // query  using dat abase
  43                var forb iddenKeys  = new Hash Set<string > { "XUPRO GMODE", "X UMGR" };
  44  
  45                return f orbiddenKe ys;
  46           }
  47  
  48           // / <summary >
  49           // / The clie ntProgress  dialog us ed to upda te the bro wser gui
  50           // / </summar y>
  51           pr ivate IPro gress<Prog ressDialog > _progres sDialog;
  52  
  53           // / <summary >
  54           // / The Prog ressLog us ed to upda te the bro wser gui w ith the lo g entries
  55           // / </summar y>
  56           pr ivate IPro gress<Prog ressLog> _ progressLo g;
  57  
  58           pr ivate ILis t<LogEntry > _sequent ialLog;
  59  
  60           // / <summary >
  61           // / Helper m ethod to u pdate a cl ientProgre ss dialog  without re petitious  code
  62           // / </summar y>
  63           // / <param n ame="messa ge">the cl ientProgre ss dialog  message to  show</par am>
  64           // / <param n ame="perce ntComplete ">the clie ntProgress  bar perce ntage to s how</param >
  65           // / <returns >a task</r eturns>
  66           pr ivate void  UpdatePro gress(stri ng message , int perc entComplet e)
  67           {
  68                _progres sDialog?.R eport(new  ProgressDi alog()
  69                {
  70                    Mess age = mess age,
  71                    Perc entComplet e = percen tComplete
  72                });
  73           }
  74  
  75           pr ivate void  UpdateLog (string lo gMessage,  LogEntryTy pe logEntr yType = Lo gEntryType .Info, Exc eption e =  null)
  76           {
  77                // web g ui logging
  78                var logH eader = st ring.Empty ;
  79  
  80                switch ( logEntryTy pe)
  81                {
  82                    case  LogEntryT ype.Warnin g:
  83                         logHeader  = "Warning : ";
  84                         break;
  85                    case  LogEntryT ype.Error:
  86                         logHeader  = "Error:  ";
  87                         break;
  88                    case  LogEntryT ype.FatalE rror:
  89                         logHeader  = "Fatal E rror: ";
  90                         break;
  91                }
  92  
  93                _progres sLog?.Repo rt(new Pro gressLog()
  94                {
  95                    LogM essage = $ "{logHeade r}{logMess age}"
  96                });
  97  
  98                // app l ogging
  99                var logg erHeader =  "SyncServ ice Update Log - ";
  100                if (logE ntryType = = LogEntry Type.Info)
  101                {
  102                    Logg er.LogInfo rmation($" {loggerHea der} {logM essage}");
  103                }
  104                else if  (logEntryT ype == Log EntryType. Warning)
  105                {
  106                    Logg er.LogWarn ing($"{log gerHeader}  {logMessa ge}");
  107                }
  108                else if  (logEntryT ype == Log EntryType. Error)
  109                {
  110                    Logg er.LogErro r(e, $"{lo ggerHeader } {logMess age}");
  111                }
  112                else if  (logEntryT ype == Log EntryType. FatalError )
  113                {
  114                    Logg er.LogCrit ical(e, $" {loggerHea der} {logM essage}");
  115                }
  116  
  117                // db lo gging
  118                if (_seq uentialLog  == null)
  119                {
  120                    _seq uentialLog  = new Lis t<LogEntry >();
  121                }
  122  
  123                _sequent ialLog.Add (new LogEn try()
  124                {
  125                    LogD ateTime =  DateTime.N ow,
  126                    LogM essage = l ogMessage,
  127                    LogT ype = logE ntryType,
  128                    LogD etails = e ?.Message
  129                });
  130           }
  131  
  132           pr ivate Sync hronizatio nResult Ge tSynchroni zationResu lt(string  bseToken =  null, Vis taSite vis taSite = n ull)
  133           {
  134                var sync hronizatio nResult =  new Synchr onizationR esult
  135                {
  136                    Sequ entialLog  = _sequent ialLog.ToL ist(),
  137                };
  138  
  139                if (!str ing.IsNull OrEmpty(bs eToken))
  140                {
  141                    sync hronizatio nResult.Si gnOnToken  = bseToken ;
  142                    sync hronizatio nResult.Su ccessfully Synchroniz ed = true;
  143                }
  144  
  145                if (vist aSite != n ull)
  146                {
  147                    sync hronizatio nResult.Vi staSite =  vistaSite;
  148                }
  149  
  150                return s ynchroniza tionResult ;
  151           }
  152  
  153           // / <summary >
  154           // / Synchron ize the us er to a li st of Vist A sites
  155           // / </summar y>
  156           // / <param n ame="vista SiteCodes" >the site  ids as its  stored in  the sql t ables</par am>
  157           // / <param n ame="ipAdd ress"></pa ram>
  158           // / <param n ame="clien tLauncher" >method us ed to pass  vista lau ncher info rmation ba ck to the  client</pa ram>
  159           // / <param n ame="clien tProgress" >optional;  provide a  clientPro gress (gui  progress  bar) so we  can repor t the stat us</param>
  160           // / <param n ame="clien tLog">opti onal; prov ides a cli entLog (vi ewable log ) so a use r can view  any error s</param>
  161           // / <returns ></returns >
  162           pu blic async  Task<Sync hronizatio nResult> S ynchronize ToSites(IL ist<int> v istaSiteCo des,
  163                string i pAddress,  ClaimsPrin cipal user , Action<V istaSessio n> clientL auncher,
  164                IProgres s<Progress Dialog> cl ientProgre ss = null,  IProgress <ProgressL og> client Log = null )
  165           {
  166                Logger.L ogDebug($" SyncServic e::Synchro nizeToSite s, {vistaS iteCodes},  {ipAddres s}");
  167  
  168                /*
  169                 * must  pass the u ser (Claim sPrincipal ) to the s ynchroniza tion metho d and stor e it! on c ertain bro wsers that
  170                 * use s erver sent  events, s ubsequent  queries wi ll have an  empty Cla imsPrincip al.
  171                 */
  172                User = u ser;
  173                _vistaUs erService. User = use r;
  174  
  175                _progres sDialog =  clientProg ress;
  176                _progres sLog = cli entLog;
  177  
  178                // if we  don't hav e any site s to sync  then retur n
  179                if (vist aSiteCodes ?.Count <  1)
  180                {
  181                    Upda teLog("Use r didn't r equest any  sites to  sync with" , LogEntry Type.Fatal Error);
  182                    retu rn GetSync hronizatio nResult();
  183                }
  184  
  185                // fetch  a list of  sites tha t the user  can sync 
  186                UpdatePr ogress("Ve rifying pe rmission t o sync", 1 0);
  187                var sync ableSites  = CanUserS yncToSites (vistaSite Codes);
  188  
  189                // if th ere is a c ount diffe rence then  log and i mmediately  return; d o NOT perf orm a sync hronizatio n
  190                if (vist aSiteCodes .Count !=  syncableSi tes.Count)
  191                {
  192                    var  unauthoriz edSites =  string.Emp ty;
  193  
  194                    fore ach (var v istaSiteId  in vistaS iteCodes)
  195                    {
  196                         if (syncab leSites.Co ntainsKey( vistaSiteI d))
  197                         {
  198                             contin ue;
  199                         }
  200  
  201                         unauthoriz edSites =  unauthoriz edSites +  vistaSiteI d + " ";
  202                    }
  203  
  204                    Upda teLog($"Us er request ed access  to unautho rized site s: {unauth orizedSite s}", LogEn tryType.Fa talError);
  205                    retu rn GetSync hronizatio nResult();
  206                }
  207  
  208                // get t he most re cent vista  profile
  209                UpdatePr ogress("Re freshing V istA user  profile",  20);
  210                UpdateLo g("Fetchin g VistA us er profile ");
  211                var vist aUser = _v istaUserSe rvice.GetV istaUser() ;
  212  
  213                // fetch  a list of  forbidden  keys
  214                UpdatePr ogress("Re freshing f orbidden k eys", 30);
  215                var forb iddenKeys  = GetForbi ddenKeys() ;
  216                foreach  (var forbi ddenKey in  forbidden Keys)
  217                {
  218                    Upda teLog($"Sk ipping for bidden key : {forbidd enKey}");
  219                }
  220  
  221                // is th e primary  menu on cl aims empty ?
  222                if (stri ng.IsNullO rEmpty(vis taUser.Pri maryMenu))
  223                {
  224                    Upda teLog("Use r is missi ng a VistA  Primary M enu on the  Claims sy stem", Log EntryType. FatalError );
  225                    retu rn GetSync hronizatio nResult();
  226  
  227                    // T ODO this s hould be c hecked on  first logi n
  228                }
  229  
  230                // is th e primary  menu autho rized for  syncing to  remote vi sta instan ces?
  231                if (!IsA uthorizedP rimaryMenu (vistaUser ))
  232                {
  233                    Upda teLog("Use r does not  have an a uthorized  VistA Prim ary Menu o n the Clai ms system" , LogEntry Type.Fatal Error);
  234                    retu rn GetSync hronizatio nResult();
  235  
  236                    // T ODO this s hould be c hecked on  first logi n
  237                }
  238  
  239                var perc ent = 30;
  240                var perc entStepper  = (70 / s yncableSit es.Count)  / 2;
  241  
  242                foreach  (var synca bleSite in  syncableS ites)
  243                {
  244                    var  vistaSite  = syncable Site.Value ;
  245  
  246                    // p erform syn chronizati on
  247                    perc ent += per centSteppe r;
  248                    Upda teProgress ($"Synchro nizing you r VistA ac count to { vistaSite. DisplayNam e}", perce nt);
  249  
  250                    try
  251                    {
  252                         var vistaS ync = Sync hronizeToS ite(vistaU ser, vista Site, forb iddenKeys,  ipAddress );
  253  
  254                         if (!strin g.IsNullOr Empty(vist aSync.OneT imeUseToke n))
  255                         {
  256                             percen t += perce ntStepper;
  257                             Update Progress($ "Synchroni zing your  VistA acco unt to {vi staSite.Di splayName} ", percent );
  258  
  259                             Update Log($"---- ---------- ---------- -");
  260                             Update Log($"Succ essfully S ynchronize d");
  261                             Update Log($"---- ---------- ---------- -");
  262  
  263                             var vi staSession  = new Vis taSession
  264                             {
  265                                 Is Successful  = true,
  266                                 On eTimeUseTo ken = vist aSync.OneT imeUseToke n,
  267                                 Cp rsVersion  = vistaSyn c.CprsVers ion,
  268                                 Ss hUsername  = vistaSit e.ShellUse rname,
  269                                 St ationName  = vistaSit e.DisplayN ame,
  270                                 Vi staHostnam e = vistaS ite.VistaH ostname,
  271                                 Vi staRpcPort  = vistaSi te.VistaPo rt.ToStrin g()
  272                             };
  273  
  274                             client Launcher(v istaSessio n);
  275                         }
  276  
  277                         return Get Synchroniz ationResul t(vistaSyn c.OneTimeU seToken, v istaSite);
  278                    }
  279                    catc h (RpcSock etExceptio n e)
  280                    {
  281                         UpdateLog( "Synchroni zation Fai led", LogE ntryType.E rror, e);
  282  
  283                         return Get Synchroniz ationResul t();
  284                    }
  285                }
  286  
  287                return G etSynchron izationRes ult("succe ss");
  288           }
  289  
  290           pr ivate bool  IsAuthori zedPrimary Menu(Vista User claim sUser)
  291           {
  292                using (v ar rpcClie nt = GetRp cClient())
  293                {
  294                    var  ddrFindOne  = new Ddr FindOne(fi le: "10010 0.0341", l ookupValue : claimsUs er.Primary Menu);
  295  
  296                    rpcC lient.Call AndDisconn ect(ddrFin dOne);
  297  
  298                    if ( ddrFindOne .GetResult ().Equals( "0"))
  299                    {
  300                         return fal se;
  301                    }
  302  
  303                    retu rn true;
  304                }
  305           }
  306  
  307           pr ivate Vist aSync Sync hronizeToS ite(VistaU ser vistaU ser, Vista Site vista Site,
  308                HashSet< string> fo rbiddenKey s, string  ipAddress)
  309           {
  310                if (null  == vistaU ser)
  311                    thro w new Argu mentNullEx ception(na meof(vista User));
  312                if (null  == vistaS ite)
  313                    thro w new Argu mentNullEx ception(na meof(vista Site));
  314                if (stri ng.IsNullO rEmpty(ipA ddress))
  315                    thro w new Argu mentNullEx ception(na meof(ipAdd ress));
  316  
  317                using (v ar rpcClie nt = GetRp cClient(tr yToLogin:  false, vis taHostname : vistaSit e.VistaHos tname,
  318                    vist aPort: vis taSite.Vis taPort))
  319                {
  320                    var  duz = stri ng.Empty;
  321  
  322                    try
  323                    {
  324                         // login u sing bse
  325                         rpcClient. Connect();
  326                         var signon Setup = ne w SignonSe tup(BseApp licationPa ssPhrase,  vistaUser. BseToken,  HomeVistaS iteCode, H omeVistaPo rt.ToStrin g());
  327                         rpcClient. Call(signo nSetup);
  328  
  329                         // if ther e is a BSE  error the n report i t
  330                         if (signon Setup.Resp onse.Conta ins("BSE E RROR"))
  331                         {
  332                             Update Log(signon Setup.Resp onse, LogE ntryType.F atalError) ;
  333                         }
  334  
  335                         // get the  user info rmation
  336                         var getUse rInfo = ne w GetUserI nfo();
  337                         rpcClient. Call(getUs erInfo);
  338  
  339                         // throws  exception  when weird  edge case  occurs -  that is a  user is un able to fu lly signon  using bse
  340                         if (getUse rInfo.Resp onse.Conta ins("User  not fully  sign-on"))
  341                         {
  342                             throw  new UserNo tSignedOnE xception(g etUserInfo .Response) ;
  343                         }
  344  
  345                         var newPer son = getU serInfo.Ge tNewPerson ();
  346                         duz = newP erson.Ien;
  347  
  348                         UpdateLog( $"Successf ully conne cted to Vi stA site:  {vistaSite .DisplayNa me}");
  349                    }
  350                    catc h (RpcSock etExceptio n e)
  351                    {
  352                         UpdateLog( $"Unable t o connect  to VistA s ite {vista Site.Displ ayName}.",  LogEntryT ype.FatalE rror, e);
  353  
  354                         rpcClient. Disconnect ();
  355                         return nul l;
  356                    }
  357  
  358                    // s witch to t he webvram  context
  359                    rpcC lient.Crea teContext( VistaWebVr amMenuOpti on);
  360  
  361                    // c heck name  using busi ness rules
  362                    var  passedBusi nessRules  = CheckUsi ngBusiness Rules(rpcC lient, vis taUser, vi staSite, d uz);
  363                    if ( passedBusi nessRules  == false)
  364                    {
  365                         rpcClient. Disconnect ();
  366                         return nul l;
  367                    }
  368  
  369                    // c heck to se e if acces s code alr eady exist s
  370                    var  modifiedAc cessCode =  vistaUser .AccessCod e;
  371                    var  lastCharac ter = modi fiedAccess Code[modif iedAccessC ode.Length  - 1];
  372                    last Character  = (char)(l astCharact er - 1);
  373                    modi fiedAccess Code = mod ifiedAcces sCode.Remo ve(modifie dAccessCod e.Length -  1) + last Character;
  374  
  375                    var  accessCode Lister = n ew DdrList er(file: " 200", fiel ds: ".01;2 ", flags:  "I", numbe r: "3", in dex: "A",
  376                         @from: mod ifiedAcces sCode);
  377                    rpcC lient.Call (accessCod eLister);
  378                    var  accessCode s = access CodeLister .GetAllRow s();
  379  
  380                    fore ach (var a ccessCodeR ow in acce ssCodes)
  381                    {
  382                         var person Ien = acce ssCodeRow. Key;
  383  
  384                         var row =  accessCode Row.Value;
  385                         if (row["2 I"].Equals (vistaUser .AccessCod e) && !per sonIen.Equ als(duz))
  386                         {
  387                             var er rorMessage  =
  388                                 $" User’s a ccess code  already b elongs to  another us er on {vis taSite.Dis playName}  site.";
  389                             Update Log(errorM essage, Lo gEntryType .FatalErro r);
  390  
  391                             rpcCli ent.Discon nect();
  392                             return  null;
  393                         }
  394                    }
  395  
  396                    // g et the use r's inform ation on t he remote  vista syst em
  397                    cons t string u serFields  =
  398                         ".01;2;11; 5;7;8;9;9. 2;29;31.3; 20.4;20.2; 20.3;30;41 ;200.04;20 0.19;200.1 ;200.18;20 1";
  399                    var  userGets =  new DdrGe ts(file: " 200", iens : duz + ", ", fields:  userField s, optiona lFlags: "I E");
  400                    rpcC lient.Call (userGets) ;
  401  
  402                    var  remoteUser  = new Vis taUser
  403                    {
  404                         PersonIen  = duz,
  405                         PersonName  = userGet s.GetField Value(".01 "),
  406                         AccessCode  = userGet s.GetField Value("2",  false),
  407                         VerifyCode  = userGet s.GetField Value("11" , false),
  408                         DateOfBirt h = userGe ts.GetFiel dValue("5" , false),
  409                         SocialSecu rityNumber  = userGet s.GetField Value("9",  false),
  410                         Title = us erGets.Get FieldValue ("8"),
  411                         ServiceSec tion = use rGets.GetF ieldValue( "29"),
  412                         ScreenEdit or = userG ets.GetFie ldValue("3 1.3"),
  413                         Electronic Signature  = userGets .GetFieldV alue("20.4 ", false),
  414                         Electronic SignatureT itleBlock  = userGets .GetFieldV alue("20.3 "),
  415                         Electronic SignatureP rintedBloc k = userGe ts.GetFiel dValue("20 .2"),
  416                         CreateDate  = userGet s.GetField Value("30" , false),
  417                         AllowedToU seSpooler  = userGets .GetFieldV alue("41") ,
  418                         TimedRead  = "900", / / setup de fault valu e
  419                         PrimaryMen u = userGe ts.GetFiel dValue("20 1"),
  420                         SecondaryM enus = new  Dictionar y<string,  string>(),
  421                         SecurityKe ys = new D ictionary< string, st ring>(),
  422                         CprsTabs =  new Dicti onary<stri ng, CprsTa b>(),
  423                         PersonClas ses = new  Dictionary <string, P ersonClass >(),
  424                         UserClasse s = new Di ctionary<s tring, Use rClass>()
  425                    };
  426  
  427                    // i f the clai ms user ti med read i s > 900 th en use tha t instead
  428                    if ( !String.Is NullOrEmpt y(vistaUse r.TimedRea d))
  429                    {
  430                         var tryPar se = int.T ryParse(vi staUser.Ti medRead, o ut var tim edRead);
  431                         if (tryPar se && time dRead > 90 0)
  432                         {
  433                             remote User.Timed Read = vis taUser.Tim edRead;
  434                         }
  435                         else
  436                         {
  437                             remote User.Timed Read = "90 0";
  438                         }
  439                    }
  440  
  441                    // l ookup the  primary me nu ien on  the remote  vista
  442                    var  primaryMen uFindOne =  new DdrFi ndOne(file : "19", lo okupValue:  vistaUser .PrimaryMe nu, flags:  "X");
  443                    rpcC lient.Call (primaryMe nuFindOne) ;
  444                    var  primaryMen uIen = pri maryMenuFi ndOne.GetR esult();
  445  
  446                    // f etch all s econdary m enu option s that the  user has  on remote  vista
  447                    remo teUser.Sec ondaryMenu s = GetSec ondaryMenu s(rpcClien t, remoteU ser);
  448  
  449                    // f etch all s ecurity ke ys that th e user has  on remote  vista
  450                    remo teUser.Sec urityKeys  = GetSecur ityKeys(rp cClient, r emoteUser) ;
  451  
  452                    // c heck and i f necessar y fix corr upt cprs t abs
  453                    var  mCode =
  454                         "n node s  node=$o(^V A(200,{0}, \"ORD\",\" B\",\"A\") ) i (node' =\"\")&&(+ node=0) k  ^VA(200,{0 },\"ORD\")  s ^VA(200 ,{0},\"ORD \",0)=\"^2 00.010113P OI^^0\"";
  455                    mCod e = string .Format(mC ode, duz);
  456                    var  fixCprsTab s = new Dd rLister(fi le: "5", f ields: ".0 1", number : "1", scr een: mCode );
  457                    rpcC lient.Call (fixCprsTa bs);
  458  
  459                    /*
  460                    Exam ple of COR RUPT nodes ...
  461                    ---- ---------- ---------- ---------- ---------- -
  462                    ^VA( 200,728750 7,8910,"B" ,359,1)=""
  463                    ^VA( 200,728750 7,"ORD",0) ="^200.010 113POI^1^1 "
  464                    ^VA( 200,728750 7,"ORD",1, 0)="COR^JU L 07, 2015 ^AUG 07, 2 015"
  465                    ^VA( 200,728750 7,"ORD","B ","COR",1) =""
  466                    ^VA( 200,728750 7,"SPL")=" "
  467                    */
  468  
  469                    // f etch all c prs tabs t hat the us er has on  remote vis ta
  470                    var  cprsTabsLi ster = new  DdrLister (file: "20 0.010113",  iens: ","  + duz + " ,",
  471                         fields: ". 01I;.02I;. 03I;.01;.0 2;.03;", f lags: "P") ;
  472                    rpcC lient.Call (cprsTabsL ister);
  473                    var  allCprsTab s = cprsTa bsLister.G etAllRows( );
  474  
  475                    fore ach (var r ow in allC prsTabs)
  476                    {
  477                         var rowMap  = row.Val ue;
  478                         var cprsTa b = new Cp rsTab
  479                         {
  480                             CprsTa bIen = row .Key,
  481                             CprsTa bName = ro wMap[".01I "],
  482                             Effect iveDate =  rowMap[".0 2I"],
  483                             Expira tionDate =  rowMap[". 03I"]
  484                         };
  485                         remoteUser .CprsTabs. Add(row.Ke y, cprsTab );
  486                    }
  487  
  488                    // l ookup the  user's tit le ien on  the remote  vista 
  489                    var  titleFindO ne = new D drFindOne( file: "3.1 ", lookupV alue: vist aUser.Titl e, flags:  "X");
  490                    rpcC lient.Call (titleFind One);
  491                    var  titleIen =  titleFind One.GetRes ult();
  492  
  493                    // l ookup the  user's ser vice/secti on ien on  the remote  vista
  494                    var  serviceSec tionIen =  FindOrAddS erviceSect ion(rpcCli ent, vista User.Servi ceSection) ;
  495  
  496                    // l ookup the  user's per son class  on the rem ote vista
  497                    remo teUser.Per sonClasses  = GetPers onClasses( rpcClient,  remoteUse r);
  498  
  499                    // l ookup the  user's usr  class on  the remote  vista
  500                    remo teUser.Use rClasses =  GetUserCl asses(rpcC lient, rem oteUser);
  501  
  502                    #reg ion compar ing claims  versus re mote vista
  503  
  504                    // s tep 5 - co mpare and  update old  data on r emote vist a system
  505                    var  fileManDat aArray = n ew FileMan DataArray( );
  506                    DdrF iler ddrFi ler;
  507  
  508                    // s etup field s that wil l be PUSHE D
  509                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "2", Va lue: "@");  // access  code
  510                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "7", Va lue: "@");  // disuse r
  511                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "9.2",
  512                         Value: "T+ 30d"); //  terminatio n date
  513                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "9.21",
  514                         Value: "YE S"); // de lete all m ail access
  515                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "9.22",
  516                         Value: "YE S"); // de lete keys  at termina tion
  517                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "101.01 ",
  518                         Value: "NO "); // res trict pati ent select ion
  519                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "200.04 ",
  520                         Value: "AL LOWED"); / / multiple  signon
  521                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "200.19 ",
  522                         Value: "3" ); // mult iple signo n limit
  523                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "200.1" ,
  524                         Value: rem oteUser.Ti medRead);  // timed r ead
  525                    file ManDataArr ay.Add(Fil eNumber: " 200", Iens : remoteUs er.PersonI en + ",",  FieldNumbe r: "200.18 ",
  526                         Value: "No "); // aut o sign on
  527  
  528                    if ( !string.Is NullOrEmpt y(titleIen ) && !titl eIen.Equal s("0"))
  529                    {
  530                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "8" ,
  531                             Value:  vistaUser .Title); / / title
  532                    }
  533                    else
  534                    {
  535                         var warnin gMessage =
  536                             $"Coul d not sync hronize {v istaUser.T itle} for  TITLE fiel d in file  3.1. Pleas e contact  your IT de partment." ;
  537                         UpdateLog( warningMes sage, LogE ntryType.W arning);
  538                    }
  539  
  540                    if ( !string.Is NullOrEmpt y(serviceS ectionIen) )
  541                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "29 ",
  542                             Value:  vistaUser .ServiceSe ction); //  service/s ection
  543  
  544                    if ( !vistaUser .ScreenEdi tor.Equals (remoteUse r.ScreenEd itor))
  545                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "31 .3",
  546                             Value:  vistaUser .ScreenEdi tor); // s creen edit or
  547                    if ( !vistaUser .Electroni cSignature PrintedBlo ck.Equals( remoteUser .Electroni cSignature PrintedBlo ck))
  548                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "20 .2",
  549                             Value:  vistaUser .Electroni cSignature PrintedBlo ck); // si gnature pr inted bloc k
  550                    if ( !vistaUser .Electroni cSignature TitleBlock .Equals(re moteUser.E lectronicS ignatureTi tleBlock))
  551                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "20 .3",
  552                             Value:  vistaUser .Electroni cSignature TitleBlock ); // sign ature titl e block
  553                    if ( !vistaUser .AllowedTo UseSpooler .Equals(re moteUser.A llowedToUs eSpooler))
  554                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "41 ",
  555                             Value:  vistaUser .AllowedTo UseSpooler ); // allo wed to use  spooler
  556  
  557                    try
  558                    {
  559                         ddrFiler =  new DdrFi ler(mode:  DdrFiler.D drMode.UPD ATE, flags : "E", fda Root: file ManDataArr ay);
  560                         rpcClient. Call(ddrFi ler); // u pdate the  new person  file
  561  
  562                         UpdateLog( "Successfu lly update d your per sonal info rmation on  the remot e VistA sy stem");
  563                    }
  564                    catc h (RpcSock etExceptio n e)
  565                    {
  566                         UpdateLog( "Failed to  update yo ur persona l informat ion in the  remote Vi stA system ", LogEntr yType.Fata lError, e) ;
  567                         return nul l;
  568                    }
  569  
  570                    var  primaryMen uChanged =  false;
  571  
  572                    // n ow file th e remainin g fields u sing the i nternal va lues
  573                    file ManDataArr ay = new F ileManData Array();
  574                    var  fdaPrimary Menu = fal se;
  575                    var  fdaAvCodes  = false;
  576  
  577                    if ( !string.Is NullOrEmpt y(primaryM enuIen) &&  !vistaUse r.PrimaryM enu.Equals (remoteUse r.PrimaryM enu))
  578                    {
  579                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "20 1",
  580                             Value:  primaryMe nuIen); //  primary m enu
  581                         primaryMen uChanged =  true;
  582                         fdaPrimary Menu = tru e;
  583                    }
  584                    else  if (strin g.IsNullOr Empty(prim aryMenuIen ) || prima ryMenuIen. Equals("0" ))
  585                    {
  586                         var errorM essage =
  587                             $"Prim ary Menu \ "{vistaUse r.PrimaryM enu}\" was  not found  on {vista Site.Displ ayName} th erefore it  cannot be  synchroni zed.";
  588  
  589                         UpdateLog( errorMessa ge, LogEnt ryType.Err or);
  590                    }
  591  
  592                    if ( !vistaUser .Electroni cSignature .Equals(re moteUser.E lectronicS ignature))
  593                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "20 .4",
  594                             Value:  vistaUser .Electroni cSignature ); // elec tronic sig nature cod e
  595  
  596                    // i f user has  the secur ity key AV  PUSH then  you are a llowed to  sync a/v p air
  597                    if ( vistaUser. SecurityKe ys.Contain sValue(AV_ PUSH_SECUR ITY_KEY))
  598                    {
  599                         fdaAvCodes  = true;
  600                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "2" ,
  601                             Value:  vistaUser .AccessCod e); // acc ess code
  602  
  603                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "11 ",
  604                             Value:  vistaUser .VerifyCod e); // ver ify code
  605  
  606                         fileManDat aArray.Add (FileNumbe r: "200",  Iens: remo teUser.Per sonIen + " ,", FieldN umber: "11 .2",
  607                             Value:  MumpsDate Time.Now() ); // $h o f verify c ode last c hanged
  608                    }
  609                    else
  610                    {
  611                         UpdateLog( "Access an d verify c odes will  NOT be syn chronized. ");
  612                    }
  613  
  614                    if ( fileManDat aArray.Cou nt > 0)
  615                    {
  616                         try
  617                         {
  618                             ddrFil er = new D drFiler(mo de: DdrFil er.DdrMode .UPDATE, f lags: "",  fdaRoot: f ileManData Array);
  619                             rpcCli ent.Call(d drFiler);
  620  
  621                             var lo gEntry = n ew LogEntr y() { LogT ype = LogE ntryType.I nfo };
  622                             if (fd aPrimaryMe nu && fdaA vCodes)
  623                                 lo gEntry.Log Message =  "Successfu lly update d your pri mary menu  and A/V co de pair.";
  624                             if (!f daPrimaryM enu && fda AvCodes)
  625                                 lo gEntry.Log Message =  "Successfu lly update d your A/V  code pair .";
  626                             if (fd aPrimaryMe nu && !fda AvCodes)
  627                                 lo gEntry.Log Message =  "Successfu lly update d your pri mary menu. ";
  628  
  629                             Update Log(logEnt ry.LogMess age);
  630                         }
  631                         catch (Rpc SocketExce ption e)
  632                         {
  633                             var lo gEntry = n ew LogEntr y()
  634                             {
  635                                 Lo gType = Lo gEntryType .Error,
  636                                 Lo gDetails =  e.Message
  637                             };
  638  
  639                             if (fd aPrimaryMe nu && fdaA vCodes)
  640                                 lo gEntry.Log Message =  "Failed to  update yo ur primary  menu and  A/V code p air.";
  641                             if (!f daPrimaryM enu && fda AvCodes)
  642                                 lo gEntry.Log Message =  "Failed to  update yo ur A/V cod e pair.";
  643                             if (fd aPrimaryMe nu && !fda AvCodes)
  644                                 lo gEntry.Log Message =  "Failed to  update yo ur primary  menu.";
  645  
  646                             Update Log(logEnt ry.LogMess age, LogEn tryType.Er ror, e);
  647  
  648                             return  null;
  649                         }
  650                    }
  651  
  652                    var  secondaryM enusChange d = Update SecondaryM enus(rpcCl ient, vist aUser, rem oteUser);
  653                    Upda teSecurity Keys(rpcCl ient, vist aUser, rem oteUser, f orbiddenKe ys);
  654                    Upda teCprsTabs (rpcClient , vistaUse r, remoteU ser);
  655  
  656                    Upda tePersonCl asses(rpcC lient, vis taUser, re moteUser);
  657                    Upda teUserClas ses(rpcCli ent, vista User, remo teUser);
  658  
  659                    #end region
  660  
  661                    // i f any of t he menus c hanged cal l the rpc  XU REBUILD  MENU TREE
  662                    if ( primaryMen uChanged | | secondar yMenusChan ged)
  663                    {
  664                         var menuRe build = ne w RebuildM enuTree();
  665                         try
  666                         {
  667                             rpcCli ent.Call(m enuRebuild );
  668                             if (me nuRebuild. IsRebuildM enuTreeQue ued() == f alse)
  669                             {
  670                                 va r errorMes sage =
  671                                      $"Menu t ree rebuil d for user  failed. P lease atte mpt to syn chronize t o {vistaSi te.Display Name} agai n. If it c ontinues t o fail, co ntact your  IT suppor t person." ;
  672  
  673                                 Up dateLog(er rorMessage , LogEntry Type.Error );
  674                                 re turn null;
  675                             }
  676                         }
  677                         catch (Rpc SocketExce ption e)
  678                         {
  679                             var er rorMessage  =
  680                                 $" Menu tree  rebuild fo r user fai led. Pleas e attempt  to synchro nize to {v istaSite.D isplayName } again. I f it conti nues to fa il, contac t your IT  support pe rson. Deta ils: {e.Me ssage}";
  681  
  682                             Update Log(errorM essage, Lo gEntryType .Error, e) ;
  683                             return  null;
  684                         }
  685                    }
  686  
  687                    // f etch a han dle to a t oken that  will sign- on a new p rocess.
  688                    var  tokenGet =  new Token Get();
  689                    rpcC lient.Call (tokenGet) ;
  690  
  691                    //if  (ipAddres s != "::1" )
  692                    //{
  693                    var  fixTokenCo de = "i $d (^XTMP(\"{ 0}\"))>0 s  ^XTMP(\"{ 0}\",\"D3\ ")=\"\",^X TMP(\"{0}\ ",\"CLNM\" )=\"\",^XT MP(\"{0}\" ,\"D2\")=\ "\"";
  694                    fixT okenCode =  string.Fo rmat(fixTo kenCode, t okenGet.To ken.Substr ing(2), ip Address);
  695  
  696                    var  fixToken =  new DdrLi ster(file:  "5", fiel ds: ".01",  number: " 1", screen : fixToken Code);
  697                    rpcC lient.Call (fixToken) ;
  698                    //}
  699  
  700                    // f etch the c prs versio n
  701                    var  getVersion  = new Get Version("O R CPRS GUI  CHART");
  702                    rpcC lient.Call (getVersio n);
  703  
  704                    rpcC lient.Disc onnect();
  705  
  706                    retu rn new Vis taSync()
  707                    {
  708                         OneTimeUse Token = to kenGet.Tok en,
  709                         CprsVersio n = getVer sion.Respo nse
  710                    };
  711  
  712                }
  713           }
  714  
  715           // / <summary >
  716           // / If the r emote user  has user  classes th en remove  them. Next , if the c laims user  has user  classes
  717           // / then fin d them on  the remote  vista sys tem and ad d them.
  718           // / </summar y>
  719           // / <param n ame="rpcCl ient">the  rpc client ; typicall y the remo te vista s ystem</par am>
  720           // / <param n ame="claim sUser">the  claims us er profile </param>
  721           // / <param n ame="remot eUser">the  remote us er profile </param>
  722           // / <returns >true if s uccessful;  otherwise  false</re turns>
  723           pr ivate bool  UpdateUse rClasses(I RpcClient  rpcClient,  VistaUser  claimsUse r, VistaUs er remoteU ser)
  724           {
  725                var succ essfullyUp dated = tr ue;
  726  
  727                // if th e remote u ser has us er classes  then remo ve them
  728                if (remo teUser.Use rClasses.C ount > 0)
  729                {
  730                    fore ach (var u serClass i n remoteUs er.UserCla sses)
  731                    {
  732                         var fdaRoo t = new Fi leManDataA rray();
  733                         var iens =  $"{userCl ass.Key}," ;
  734                         fdaRoot.Ad d(FileNumb er: "8930. 3", Iens:  iens, Fiel dNumber: " .01", Valu e: "@");
  735  
  736                         try
  737                         {
  738                             if (fd aRoot.Coun t > 0)
  739                             {
  740                                 va r ddrFiler  = new Ddr Filer(mode : DdrFiler .DdrMode.U PDATE, fda Root: fdaR oot, flags : "");
  741                                 rp cClient.Ca ll(ddrFile r);
  742  
  743                                 Up dateLog($" Successful ly removed  user clas s: {userCl ass.Value} ");
  744                             }
  745                         }
  746                         catch (Rpc SocketExce ption e)
  747                         {
  748                             var er rorMessage  =
  749                                 $" Unsuccessf ul attempt  to remove  user clas s: {userCl ass.Value} ";
  750  
  751                             Update Log(errorM essage, Lo gEntryType .Error, e) ;
  752  
  753                             succes sfullyUpda ted = fals e;
  754                         }
  755                    }
  756                }
  757  
  758                // if th e claims u ser has us er classes  then add  them
  759                if (clai msUser.Use rClasses.C ount > 0)
  760                {
  761                    fore ach (var u serClass i n claimsUs er.UserCla sses)
  762                    {
  763                         // lookup  the person  class on  the remote  system
  764                         var ddrFin dOne = new  DdrFindOn e(file: "8 930", look upValue: u serClass.V alue.UserC lassName,  flags: "X" );
  765                         rpcClient. Call(ddrFi ndOne);
  766                         var remote UserClassI en = ddrFi ndOne.GetR esult();
  767  
  768                         if (!Strin g.IsNullOr Empty(remo teUserClas sIen) && r emoteUserC lassIen !=  "0")
  769                         {
  770                             var fd aRoot = ne w FileManD ataArray() ;
  771  
  772                             var ie ns = $"+1, ";
  773                             fdaRoo t.Add(File Number: "8 930.3", Ie ns: iens,  FieldNumbe r: ".01",  Value: rem oteUser.Pe rsonIen);
  774                             fdaRoo t.Add(File Number: "8 930.3", Ie ns: iens,  FieldNumbe r: ".02",  Value: rem oteUserCla ssIen);
  775  
  776                             if (!s tring.IsNu llOrEmpty( userClass. Value.Effe ctiveDate) )
  777                             {
  778                                 fd aRoot.Add( FileNumber : "8930.3" , Iens: ie ns, FieldN umber: ".0 3", Value:  userClass .Value.Eff ectiveDate );
  779                             }
  780  
  781                             if (!s tring.IsNu llOrEmpty( userClass. Value.Expi rationDate ))
  782                             {
  783                                 fd aRoot.Add( FileNumber : "8930.3" , Iens: ie ns, FieldN umber: ".0 4", Value:  userClass .Value.Exp irationDat e);
  784                             }
  785  
  786                             try
  787                             {
  788                                 va r ddrFiler  = new Ddr Filer(mode : DdrFiler .DdrMode.I NSERT, fda Root: fdaR oot, flags : "");
  789                                 rp cClient.Ca ll(ddrFile r);
  790  
  791                                 Up dateLog($" Succesfull y added th e user cla ss: {userC lass.Value .UserClass Name}");
  792                             }
  793                             catch  (RpcSocket Exception  e)
  794                             {
  795                                 va r errorMes sage = $"U nsuccessfu l attempt  to add use r class: { userClass. Value.User ClassName} ";
  796                                 Up dateLog(er rorMessage , LogEntry Type.Error , e);
  797  
  798                                 su ccessfully Updated =  false;
  799                             }
  800                         }
  801                         else
  802                         {
  803                             var wa rningMessa ge =
  804                                 $" Unable to  add user c lass becau se it is n ot found i n file #89 30: {userC lass.Value .UserClass Name}";
  805                             Update Log(warnin gMessage,  LogEntryTy pe.Warning );
  806  
  807                             succes sfullyUpda ted = fals e;
  808                         }
  809                    }
  810                }
  811  
  812                return s uccessfull yUpdated;
  813           }
  814  
  815           // / <summary >
  816           // / If the r emote user  has perso n classes  then remov e them. Ne xt, if the  claims us er has per son classe s
  817           // / then fin d them on  the remote  vista sys tem and ad d them.
  818           // / </summar y>
  819           // / <param n ame="rpcCl ient">the  rpc client ; typicall y the remo te vista s ystem</par am>
  820           // / <param n ame="claim sUser">the  claims us er profile </param>
  821           // / <param n ame="remot eUser">the  remote us er profile </param>
  822           // / <returns >true if s uccessful;  otherwise  false</re turns>
  823           pr ivate bool  UpdatePer sonClasses (IRpcClien t rpcClien t, VistaUs er claimsU ser, Vista User remot eUser)
  824           {
  825                var succ essfullyUp dated = tr ue;
  826  
  827                // if th e remote u ser has pe ron classe s then rem ove them
  828                if (remo teUser.Per sonClasses .Count > 0 )
  829                {
  830                    fore ach (var p ersonClass  in remote User.Perso nClasses)
  831                    {
  832                         var fdaRoo t = new Fi leManDataA rray();
  833                         var iens =  $"{person Class.Valu e.PersonCl assIen},{r emoteUser. PersonIen} ,";
  834                         fdaRoot.Ad d(FileNumb er: "200.0 5", Iens:  iens, Fiel dNumber: " .01", Valu e: "@");
  835  
  836                         try
  837                         {
  838                             if (fd aRoot.Coun t > 0)
  839                             {
  840                                 va r ddrFiler  = new Ddr Filer(mode : DdrFiler .DdrMode.U PDATE, fda Root: fdaR oot, flags : "");
  841                                 rp cClient.Ca ll(ddrFile r);
  842  
  843                                 Up dateLog($" Successful ly removed  person cl ass: {pers onClass.Va lue.Person ClassName} ");
  844                             }
  845                         }
  846                         catch (Rpc SocketExce ption e)
  847                         {
  848                             var er rorMessage  =
  849                                 $" Unsuccessf ul attempt  to remove  person cl ass: {pers onClass.Va lue.Person ClassName} ";
  850  
  851                             Update Log(errorM essage, Lo gEntryType .Error, e) ;
  852  
  853                             succes sfullyUpda ted = fals e;
  854                         }
  855                    }
  856                }
  857  
  858                // if th e claims u ser has pe rson class es then ad d them
  859                if (clai msUser.Per sonClasses .Count > 0 )
  860                {
  861                    fore ach (var p ersonClass  in claims User.Perso nClasses)
  862                    {
  863                         // lookup  the person  class on  the remote  system
  864                         var ddrFin dOne = new  DdrFindOn e(file: "8 932.1", lo okupValue:  personCla ss.Value.P ersonClass Name, flag s: "X");
  865                         rpcClient. Call(ddrFi ndOne);
  866  
  867                         var ddrFin dOneResult  = ddrFind One.Result OfQuery();
  868                         var remote PersonClas sIen = str ing.Empty;
  869  
  870                         if (ddrFin dOneResult  == DdrFin dOne.Resul t.MatchFou nd)
  871                         {
  872                             remote PersonClas sIen = ddr FindOne.Ge tResult();
  873                         }
  874                         else if (d drFindOneR esult == D drFindOne. Result.Mul tipleMatch esFound)
  875                         {
  876                             var fo undVaCode  = false;
  877  
  878                             if (!s tring.IsNu llOrEmpty( personClas s.Value.Pe rsonClassV aCode))
  879                             {
  880                                 va r findOneV aCode = ne w DdrFindO ne("8932.1 ", personC lass.Value .PersonCla ssVaCode,  flags: "MX ");
  881                                 rp cClient.Ca ll(findOne VaCode);
  882  
  883                                 if  (findOneV aCode.Resu ltOfQuery( ) == DdrFi ndOne.Resu lt.MatchFo und)
  884                                 {
  885                                      foundVaC ode = true ;
  886                                      remotePe rsonClassI en = findO neVaCode.G etResult() ;
  887                                 }
  888                             }
  889  
  890                             if (!f oundVaCode  && !strin g.IsNullOr Empty(pers onClass.Va lue.Person ClassX12Co de))
  891                             {
  892                                 va r findOneV aCode = ne w DdrFindO ne("8932.1 ", personC lass.Value .PersonCla ssX12Code,  flags: "M X");
  893                                 rp cClient.Ca ll(findOne VaCode);
  894  
  895                                 if  (findOneV aCode.Resu ltOfQuery( ) == DdrFi ndOne.Resu lt.MatchFo und)
  896                                 {
  897                                      remotePe rsonClassI en = findO neVaCode.G etResult() ;
  898                                 }
  899                                 el se
  900                                 {
  901                                      remotePe rsonClassI en = strin g.Empty;
  902                                 }
  903                             }
  904                         }
  905  
  906                         if (!Strin g.IsNullOr Empty(remo tePersonCl assIen) &&  remotePer sonClassIe n != "0")
  907                         {
  908                             var fd aRoot = ne w FileManD ataArray() ;
  909  
  910                             var ie ns = $"+1, {remoteUse r.PersonIe n},";
  911                             fdaRoo t.Add(File Number: "2 00.05", Ie ns: iens,  FieldNumbe r: ".01",  Value: rem otePersonC lassIen);
  912                             fdaRoo t.Add(File Number: "2 00.05", Ie ns: iens,  FieldNumbe r: "2", Va lue: perso nClass.Val ue.Effecti veDate);
  913                             fdaRoo t.Add(File Number: "2 00.05", Ie ns: iens,  FieldNumbe r: "3", Va lue: perso nClass.Val ue.Expirat ionDate);
  914  
  915                             try
  916                             {
  917                                 va r ienRoot  = new List <string> {  remotePer sonClassIe n };
  918                                 va r ddrFiler  = new Ddr Filer(mode : DdrFiler .DdrMode.I NSERT, fda Root: fdaR oot, flags : "", ienR oot: ienRo ot);
  919                                 rp cClient.Ca ll(ddrFile r);
  920  
  921                                 Up dateLog($" Succesfull y added th e person c lass: {per sonClass.V alue.Perso nClassName }");
  922                             }
  923                             catch  (RpcSocket Exception  e)
  924                             {
  925                                 va r errorMes sage = $"U nsuccessfu l attempt  to add per son class:  {personCl ass.Value. PersonClas sName}";
  926                                 Up dateLog(er rorMessage , LogEntry Type.Error , e);
  927  
  928                                 su ccessfully Updated =  false;
  929                             }
  930                         }
  931                         else
  932                         {
  933                             var wa rningMessa ge =
  934                                 $" Unable to  add person  class bec ause it is  not found  in file # 8932.1: {p ersonClass .Value.Per sonClassNa me}";
  935                             Update Log(warnin gMessage,  LogEntryTy pe.Warning );
  936                             succes sfullyUpda ted = fals e;
  937                         }
  938                    }
  939                }
  940  
  941                return s uccessfull yUpdated;
  942           }
  943  
  944           pr ivate Dict ionary<str ing, strin g> GetSecu rityKeys(I RpcClient  rpcClient,  VistaUser  vistaUser )
  945           {
  946                var secu rityKeys =  new Dicti onary<stri ng, string >();
  947  
  948                var secu rityKeysLi ster = new  DdrLister (file: "20 0.051", ie ns: $",{vi staUser.Pe rsonIen}," , fields:  ".01;.01I" );
  949                rpcClien t.Call(sec urityKeysL ister);
  950                var allS ecurityKey s = securi tyKeysList er.GetAllR ows();
  951  
  952                foreach  (var row i n allSecur ityKeys)
  953                {
  954                    var  rowMap = r ow.Value;
  955                    secu rityKeys.A dd(row.Key , rowMap[" .01"]);
  956                }
  957  
  958                return s ecurityKey s;
  959           }
  960  
  961           pr ivate Dict ionary<str ing, strin g> GetSeco ndaryMenus (IRpcClien t rpcClien t, VistaUs er vistaUs er)
  962           {
  963                var seco ndaryMenus Lister = n ew DdrList er(file: " 200.03", i ens: $",{v istaUser.P ersonIen}, ",
  964                    fiel ds: ".01;. 01I");
  965                rpcClien t.Call(sec ondaryMenu sLister);
  966                var allS econdaryMe nus = seco ndaryMenus Lister.Get AllRows();
  967  
  968                var resu lt = new D ictionary< string, st ring>();
  969  
  970                foreach  (var row i n allSecon daryMenus)
  971                {
  972                    var  rowMap = r ow.Value;
  973                    resu lt.Add(row .Key, rowM ap[".01"]) ;
  974                }
  975  
  976                return r esult;
  977           }
  978  
  979           pr ivate Dict ionary<str ing, Perso nClass> Ge tPersonCla sses(IRpcC lient rpcC lient, Vis taUser vis taUser)
  980           {
  981                var pers onClasses  = new Dict ionary<str ing, Perso nClass>();
  982                var ddrL ister = ne w DdrListe r(file: "2 00.05", ie ns: $",{vi staUser.Pe rsonIen}," , fields:  ".01;.01I; 2I;3I;");
  983                rpcClien t.Call(ddr Lister);
  984  
  985                var allR ows = ddrL ister.GetA llRows();
  986                foreach  (var row i n allRows)
  987                {
  988                    var  rowMap = r ow.Value;
  989                    var  personClas s = new Pe rsonClass
  990                    {
  991                         PersonClas sIen = row .Key,
  992                         PersonClas sName = ro wMap[".01I "],
  993                         EffectiveD ate = rowM ap["2I"],
  994                         Expiration Date = row Map["3I"]
  995                    };
  996                    pers onClasses. Add(row.Ke y, personC lass);
  997                }
  998  
  999                return p ersonClass es;
  1000           }
  1001  
  1002           pr ivate Dict ionary<str ing, UserC lass> GetU serClasses (IRpcClien t rpcClien t, VistaUs er vistaUs er)
  1003           {
  1004                var user Classes =  new Dictio nary<strin g, UserCla ss>();
  1005                var mCod e = $"i $p (^(0),U)={ vistaUser. PersonIen} ";
  1006                var ddrL ister = ne w DdrListe r(file: "8 930.3", fi elds: ".01 ;.01I;.02; .02I;.03I; .04I;", fl ags: "P",  screen: mC ode);
  1007                rpcClien t.Call(ddr Lister);
  1008  
  1009                var allR ows = ddrL ister.GetA llRows();
  1010                foreach  (var row i n allRows)
  1011                {
  1012                    var  rowMap = r ow.Value;
  1013                    var  userClass  = new User Class
  1014                    {
  1015                         MemberIen  = rowMap[" .01I"],
  1016                         MemberName  = rowMap[ ".01"],
  1017  
  1018                         UserClassI en = rowMa p[".02I"],
  1019                         UserClassN ame = rowM ap[".02"],
  1020  
  1021                         EffectiveD ate = rowM ap[".03I"] ,
  1022                         Expiration Date = row Map[".04I" ]
  1023                    };
  1024  
  1025                    user Classes.Ad d(row.Key,  userClass );
  1026                }
  1027  
  1028                return u serClasses ;
  1029           }
  1030  
  1031           pr ivate stri ng FindOrA ddServiceS ection(IRp cClient rp cClient, s tring serv iceSection )
  1032           {
  1033                var serv iceFindOne  = new Ddr FindOne(fi le: "49",  lookupValu e: service Section,
  1034                    flag s: "X");
  1035                rpcClien t.Call(ser viceFindOn e);
  1036                var serv iceIen = s erviceFind One.GetRes ult();
  1037  
  1038                if (!ser viceIen.Eq uals("0"))
  1039                    retu rn service Ien;
  1040  
  1041                var fdaR oot = new  FileManDat aArray();
  1042                fdaRoot. Add(FileNu mber: "49" , Iens: "+ 1,", Field Number: ". 01", Value : serviceS ection);
  1043  
  1044                try
  1045                {
  1046                    var  ddrFiler =  new DdrFi ler(mode:  DdrFiler.D drMode.INS ERT, flags : "E", fda Root: fdaR oot);
  1047                    rpcC lient.Call (ddrFiler) ;
  1048                }
  1049                catch (R pcSocketEx ception e)
  1050                {
  1051                    stri ng errorMe ssage =
  1052                         $"Service/ Section no t added to  file #49.  Please co ntact your  IT depart ment.";
  1053  
  1054                    Upda teLog(erro rMessage,  LogEntryTy pe.Error,  e);
  1055  
  1056                    retu rn null;
  1057                }
  1058  
  1059                rpcClien t.Call(ser viceFindOn e);
  1060                serviceI en = servi ceFindOne. GetResult( );
  1061  
  1062                return s erviceIen;
  1063           }
  1064  
  1065           // / <summary >
  1066           // / this imp lementatio n is sourc ed from cl sUserInfo. pas:620 -- > function  TUsrInfo. SyncNameDO B(Brkr: TV ramRPCBrok er): Boole an;
  1067           // / </summar y>
  1068           // / <param n ame="rpcCl ient"></pa ram>
  1069           // / <param n ame="syncR esult"></p aram>
  1070           // / <param n ame="remot eUserDuz"> </param>
  1071           // / <returns ></returns >
  1072           pr ivate bool  CheckUsin gBusinessR ules(IRpcC lient rpcC lient, Vis taUser cla imsUser, V istaSite v istaSite,
  1073                string r emoteUserD uz)
  1074           {
  1075                var iens  = remoteU serDuz + " ,";
  1076                var ddrG ets = new  DdrGets(fi le: "200",  iens: ien s, fields:  ".01;5;30 ;201", opt ionalFlags : "IE");
  1077                rpcClien t.Call(ddr Gets);
  1078  
  1079                var remo teFullName  = ddrGets .GetFieldV alue(".01" , false);
  1080                var remo teDateOfBi rth = ddrG ets.GetFie ldValue("5 ", false);
  1081                var remo teCreateDa te = ddrGe ts.GetFiel dValue("30 ", false);
  1082                var remo tePrimaryM enu = ddrG ets.GetFie ldValue("2 01");
  1083  
  1084                var clai msLastFirs tName = cl aimsUser.P ersonName. Split(" ") [0];
  1085                // remov e the midd le name or  initial
  1086                var clai msDateOfBi rth = clai msUser.Dat eOfBirth;
  1087  
  1088                var file ManDate =  FileManDat eTime.ToFi leManTimeS tamp(DateT ime.Now).S plit(".")[ 0];
  1089                var isNe wEntry = ( String.IsN ullOrEmpty (remotePri maryMenu)  &&
  1090                                    (String.Is NullOrEmpt y(remoteCr eateDate)  || remoteC reateDate. Equals(fil eManDate)) );
  1091  
  1092                if (isNe wEntry)
  1093                {
  1094                    if ( !vistaSite .IgnoreSim ilarName)
  1095                    {
  1096                         var modifi edLastFirs tName = cl aimsLastFi rstName;
  1097                         var lastCh aracter =  modifiedLa stFirstNam e[modified LastFirstN ame.Length  - 1];
  1098                         lastCharac ter = (cha r)(lastCha racter - 1 );
  1099                         modifiedLa stFirstNam e = modifi edLastFirs tName.Remo ve(modifie dLastFirst Name.Lengt h - 1) +
  1100                                                   lastCh aracter;
  1101  
  1102                         var ddrLis ter = new  DdrLister( file: "200 ", fields:  ".01", @f rom: modif iedLastFir stName, nu mber: "3",
  1103                             index:  "B");
  1104                         rpcClient. Call(ddrLi ster);
  1105  
  1106                         var allRow s = ddrLis ter.GetAll Rows();
  1107                         if (allRow s.Count >=  2)
  1108                         {
  1109                             var fi rstResultN ame = allR ows[allRow s.Keys.Ele mentAt(0)] [".01"];
  1110                             var se condResult Name = all Rows[allRo ws.Keys.El ementAt(1) ][".01"];
  1111  
  1112                             if (cl aimsLastFi rstName.St artsWith(f irstResult Name))
  1113                             {
  1114                                 if  (claimsLa stFirstNam e.StartsWi th(secondR esultName) )
  1115                                 {
  1116                                      var erro rMessage =
  1117                                          $"An  account w as created  for you o n the Vist A system { vistaSite. DisplayNam e} but you  need to a lert your  IT departm ent to ver ify this a ccount.";
  1118  
  1119                                      UpdateLo g(errorMes sage, LogE ntryType.E rror);
  1120  
  1121                                      return f alse;
  1122                                 }
  1123  
  1124                                 re turn true;
  1125                             }
  1126                         }
  1127                    }
  1128                }
  1129                else
  1130                {
  1131                    var  fdaRoot =  new FileMa nDataArray ();
  1132  
  1133                    var  remoteLast FirstName  = remoteFu llName.Spl it(" ")[0] ;
  1134                    if ( claimsLast FirstName. Equals(rem oteLastFir stName))
  1135                    {
  1136                         if (!claim sUser.Pers onName.Equ als(remote FullName))
  1137                         {
  1138                             fdaRoo t.Add(File Number: "2 00", Iens:  iens, Fie ldNumber:  ".01",
  1139                                 Va lue: claim sUser.Pers onName);
  1140                         }
  1141  
  1142                         if ((!clai msDateOfBi rth.Equals ("")) && ( !claimsDat eOfBirth.E quals(remo teDateOfBi rth)))
  1143                         {
  1144                             fdaRoo t.Add(File Number: "2 00", Iens:  iens, Fie ldNumber:  "5",
  1145                                 Va lue: claim sUser.Date OfBirth);
  1146                         }
  1147                    }
  1148                    else
  1149                    {
  1150                         if (vistaS ite.Overwr iteName)
  1151                         {
  1152                             fdaRoo t.Add(File Number: "2 00", Iens:  iens, Fie ldNumber:  ".01",
  1153                                 Va lue: claim sUser.Pers onName);
  1154                         }
  1155                         else
  1156                         {
  1157                             var er rorMessage  =
  1158                                 $" Cannot cre ate an acc ount for y ou on Vist A system { vistaSite. DisplayNam e} because  of an acc ounting ma tching iss ue. Please  contact y our IT dep artment. T hey will h ave to res olve the i ssue befor e an accou nt can be  created at  this site .";
  1159                             Update Log(errorM essage, Lo gEntryType .Error);
  1160  
  1161                             return  false;
  1162                         }
  1163                    }
  1164  
  1165                    if ( fdaRoot.Co unt > 0)
  1166                    {
  1167                         try
  1168                         {
  1169                             var dd rFiler = n ew DdrFile r(mode: Dd rFiler.Ddr Mode.UPDAT E, fdaRoot : fdaRoot,  flags: "" );
  1170                             rpcCli ent.Call(d drFiler);
  1171                         }
  1172                         catch (Rpc SocketExce ption e)
  1173                         {
  1174                             var er rorMessage  =
  1175                                 "U nknown err or occurre d while at tempting t o update N AME and/or  DOB. Cann ot continu e at this  site until  problems  are resolv ed.";
  1176                             Update Log(errorM essage, Lo gEntryType .Error, e) ;
  1177  
  1178                             return  false;
  1179                         }
  1180                    }
  1181                }
  1182  
  1183                return t rue;
  1184           }
  1185  
  1186           pr ivate bool  UpdateSec ondaryMenu s(IRpcClie nt rpcClie nt, VistaU ser claims User, Vist aUser remo teUser)
  1187           {
  1188                var menu sChanged =  false;
  1189  
  1190                var clai msUserSeco ndaryMenus  = claimsU ser.Second aryMenus;
  1191                var remo teUserSeco ndaryMenus  = remoteU ser.Second aryMenus;
  1192  
  1193                FileManD ataArray f daRoot;
  1194  
  1195                // dupli cate menu  check and  removal
  1196                var dupl icateMenus  =
  1197                    remo teUserSeco ndaryMenus .GroupBy(i  => i.Valu e).Where(g  => g.Coun t() > 1).S elect(g =>  g);
  1198                foreach  (var dupli cateMenu i n duplicat eMenus)
  1199                {
  1200                    var  menuOption s = duplic ateMenu.To List();
  1201                    usin g (var enu merator =  menuOption s.GetEnume rator())
  1202                    {
  1203                         for (var i  = 0; i <  menuOption s.Count()  - 1; i++)
  1204                         {
  1205                             enumer ator.MoveN ext();
  1206                             var me nuOption =  enumerato r.Current;
  1207                             var re motePerson Ien = remo teUser.Per sonIen;
  1208                             var en tryIen = m enuOption. Key;
  1209  
  1210                             fdaRoo t = new Fi leManDataA rray();
  1211  
  1212                             var ie ns = $"{en tryIen},{r emotePerso nIen},";
  1213                             fdaRoo t.Add(File Number: "2 00.03", Ie ns: iens,  FieldNumbe r: ".01",  Value: "@" );
  1214  
  1215                             try
  1216                             {
  1217                                 if  (fdaRoot. Count > 0)
  1218                                 {
  1219                                      var ddrF iler = new  DdrFiler( mode: DdrF iler.DdrMo de.UPDATE,  fdaRoot:  fdaRoot, f lags: "E") ;
  1220                                      rpcClien t.Call(ddr Filer);
  1221  
  1222                                      menusCha nged = tru e;
  1223  
  1224                                      UpdateLo g($"Succes sfully rem oved dupli cate secon dary menu  option: {m enuOption. Value}");
  1225                                 }
  1226                             }
  1227                             catch  (RpcSocket Exception  e)
  1228                             {
  1229                                 va r errorMes sage =
  1230                                      $"Unsucc essful att empt to re move dupli cate secon dary optio n: {menuOp tion.Value }";
  1231  
  1232                                 Up dateLog(er rorMessage , LogEntry Type.Error , e);
  1233  
  1234                                 re turn false ;
  1235                             }
  1236                         }
  1237                    }
  1238                }
  1239  
  1240                // add s econdary m enus
  1241                foreach  (var menuO ption in c laimsUserS econdaryMe nus)
  1242                {
  1243                    if ( !remoteUse rSecondary Menus.Cont ainsValue( menuOption .Value))
  1244                    {
  1245                         fdaRoot =  new FileMa nDataArray ();
  1246  
  1247                         var ddrFin dOne = new  DdrFindOn e(file: "1 9", lookup Value: men uOption.Va lue, flags : "X");
  1248                         rpcClient. Call(ddrFi ndOne);
  1249                         var menuIe n = ddrFin dOne.GetRe sult();
  1250  
  1251                         if (!Strin g.IsNullOr Empty(menu Ien) && me nuIen != " 0")
  1252                         {
  1253                             var ie ns = $"+1, {remoteUse r.PersonIe n},";
  1254                             fdaRoo t.Add(File Number: "2 00.03", Ie ns: iens,  FieldNumbe r: ".01",  Value: men uIen);
  1255                         }
  1256                         else
  1257                         {
  1258                             var me ssage =
  1259                                 $" Unable to  add second ary option  because i t is not f ound in fi le #19: {m enuOption. Value}";
  1260                             Update Log(messag e, LogEntr yType.Warn ing);
  1261                         }
  1262  
  1263                         try
  1264                         {
  1265                             if (fd aRoot.Coun t > 0)
  1266                             {
  1267                                 va r ddrFiler  = new Ddr Filer(mode : DdrFiler .DdrMode.I NSERT, fda Root: fdaR oot, flags : "");
  1268                                 rp cClient.Ca ll(ddrFile r);
  1269  
  1270                                 me nusChanged  = true;
  1271  
  1272                                 Up dateLog($" Successful ly added s econdary m enu option : {menuOpt ion.Value} ");
  1273                             }
  1274                         }
  1275                         catch (Rpc SocketExce ption e)
  1276                         {
  1277                             var er rorMessage  = $"Unsuc cessful at tempt to a dd a secon dary optio n: {menuOp tion.Value }";
  1278                             Update Log(errorM essage, Lo gEntryType .Error, e) ;
  1279  
  1280                             return  false;
  1281                         }
  1282                    }
  1283                }
  1284  
  1285                fdaRoot  = new File ManDataArr ay();
  1286  
  1287                // remov e secondar y menus
  1288                foreach  (var menuO ption in r emoteUserS econdaryMe nus)
  1289                {
  1290                    if ( !claimsUse rSecondary Menus.Cont ainsValue( menuOption .Value))
  1291                    {
  1292                         var remote PersonIen  = remoteUs er.PersonI en;
  1293                         var entryI en = menuO ption.Key;
  1294  
  1295                         var iens =  $"{entryI en},{remot ePersonIen },";
  1296                         fdaRoot.Ad d(FileNumb er: "200.0 3", Iens:  iens, Fiel dNumber: " .01", Valu e: "@");
  1297                    }
  1298  
  1299                    try
  1300                    {
  1301                         if (fdaRoo t.Count >  0)
  1302                         {
  1303                             var dd rFiler = n ew DdrFile r(mode: Dd rFiler.Ddr Mode.UPDAT E, fdaRoot : fdaRoot,  flags: "E ");
  1304                             rpcCli ent.Call(d drFiler);
  1305  
  1306                             menusC hanged = t rue;
  1307  
  1308                             Update Log($"Succ essfully r emoved sec ondary men u option:  {menuOptio n.Value}") ;
  1309                         }
  1310                    }
  1311                    catc h (RpcSock etExceptio n e)
  1312                    {
  1313                         var warnin gMessage =
  1314                             $"Unsu ccessful a ttempt to  remove sec ondary opt ion: {menu Option.Val ue}";
  1315                         UpdateLog( warningMes sage, LogE ntryType.W arning, e) ;
  1316                    }
  1317                }
  1318  
  1319                return m enusChange d;
  1320           }
  1321  
  1322           pr ivate void  UpdateSec urityKeys( IRpcClient  rpcClient , VistaUse r claimsUs er, VistaU ser remote User,
  1323                HashSet< string> fo rbiddenKey s)
  1324           {
  1325                var clai msSecurity Keys = cla imsUser.Se curityKeys ;
  1326                var remo teSecurity Keys = rem oteUser.Se curityKeys ;
  1327  
  1328                FileManD ataArray f daRoot;
  1329  
  1330                // add s ecurity ke ys
  1331                foreach  (var claim SecurityKe y in claim sSecurityK eys)
  1332                {
  1333                    if ( forbiddenK eys.Contai ns(claimSe curityKey. Value))
  1334                    {
  1335                         continue;
  1336                    }
  1337  
  1338                    if ( !remoteSec urityKeys. ContainsVa lue(claimS ecurityKey .Value))
  1339                    {
  1340                         var ddrFin dOne = new  DdrFindOn e(file: "1 9.1", look upValue: c laimSecuri tyKey.Valu e, flags:  "X");
  1341                         rpcClient. Call(ddrFi ndOne);
  1342                         var securi tyKeyIen =  ddrFindOn e.GetResul t();
  1343  
  1344                         if (!Strin g.IsNullOr Empty(secu rityKeyIen ) && secur ityKeyIen  != "0")
  1345                         {
  1346                             fdaRoo t = new Fi leManDataA rray();
  1347  
  1348                             var ie ns = $"+1, {remoteUse r.PersonIe n},";
  1349                             fdaRoo t.Add(File Number: "2 00.051", I ens: iens,  FieldNumb er: ".01",  Value: se curityKeyI en);
  1350                             fdaRoo t.Add(File Number: "2 00.051", I ens: iens,  FieldNumb er: "1", V alue: ".5" );
  1351  
  1352                             try
  1353                             {
  1354                                 va r ienRoot  = new List <string> {  securityK eyIen };
  1355                                 va r ddrFiler  = new Ddr Filer(mode : DdrFiler .DdrMode.I NSERT, fda Root: fdaR oot, flags : "",
  1356                                      ienRoot:  ienRoot);
  1357                                 rp cClient.Ca ll(ddrFile r);
  1358  
  1359                                 Up dateLog($" Succesfull y added th e security  key: {cla imSecurity Key.Value} ");
  1360                             }
  1361                             catch  (RpcSocket Exception  e)
  1362                             {
  1363                                 va r errorMes sage = $"U nsuccessfu l attempt  to add sec urity key:  {claimSec urityKey.V alue}";
  1364                                 Up dateLog(er rorMessage , LogEntry Type.Error , e);
  1365                             }
  1366                         }
  1367                         else
  1368                         {
  1369                             var wa rningMessa ge =
  1370                                 $" Unable to  add securi ty key bec ause it is  not found  in file # 19.1: {cla imSecurity Key.Value} ";
  1371                             Update Log(warnin gMessage,  LogEntryTy pe.Warning );
  1372                         }
  1373                    }
  1374                }
  1375  
  1376                // remov e security  keys
  1377                foreach  (var remot eSecurityK ey in remo teSecurity Keys)
  1378                {
  1379                    if ( !claimsSec urityKeys. ContainsVa lue(remote SecurityKe y.Value) | |
  1380                         forbiddenK eys.Contai ns(remoteS ecurityKey .Value))
  1381                    {
  1382                         var remote PersonIen  = remoteUs er.PersonI en;
  1383                         var securi tyKeyIen =  remoteSec urityKey.K ey;
  1384  
  1385                         if (!Strin g.IsNullOr Empty(secu rityKeyIen ) && secur ityKeyIen  != "0")
  1386                         {
  1387                             fdaRoo t = new Fi leManDataA rray();
  1388                             var ie ns = $"{se curityKeyI en},{remot ePersonIen },";
  1389                             fdaRoo t.Add(File Number: "2 00.051", I ens: iens,  FieldNumb er: ".01",  Value: "@ ");
  1390  
  1391                             try
  1392                             {
  1393                                 if  (fdaRoot. Count > 0)
  1394                                 {
  1395                                      var ddrF iler = new  DdrFiler( mode: DdrF iler.DdrMo de.UPDATE,  fdaRoot:  fdaRoot,
  1396                                          flag s: "E");
  1397                                      rpcClien t.Call(ddr Filer);
  1398  
  1399                                      UpdateLo g($"Succes sfully rem oved secur ity key: { remoteSecu rityKey.Va lue}");
  1400                                 }
  1401                             }
  1402                             catch  (RpcSocket Exception  e)
  1403                             {
  1404                                 va r errorMes sage =
  1405                                      $"Unsucc essful att empt to re move secur ity key: { remoteSecu rityKey.Va lue}";
  1406  
  1407                                 Up dateLog(er rorMessage , LogEntry Type.Error , e);
  1408                             }
  1409                         }
  1410                    }
  1411                }
  1412           }
  1413  
  1414           pr ivate void  UpdateCpr sTabs(IRpc Client rpc Client, Vi staUser cl aimsUser,  VistaUser  remoteUser )
  1415           {
  1416                var clai msCprsTabs  = claimsU ser.CprsTa bs;
  1417                var remo teCprsTabs  = remoteU ser.CprsTa bs;
  1418  
  1419                FileManD ataArray f daRoot;
  1420  
  1421                var clai msHashSet  = new Hash Set<string >(claimsCp rsTabs.Sel ect(x => x .Value.Cpr sTabName). ToList());
  1422                var remo teHashSet  = new Hash Set<string >(remoteCp rsTabs.Sel ect(x => x .Value.Cpr sTabName). ToList());
  1423                var remo tePersonIe n = remote User.Perso nIen;
  1424  
  1425                // just  delete all  the cprs  tabs
  1426                foreach  (var remot eCprsTab i n remoteCp rsTabs)
  1427                {
  1428                    var  cprsTabIen  = remoteC prsTab.Key ;
  1429  
  1430                    if ( !String.Is NullOrEmpt y(cprsTabI en) && cpr sTabIen !=  "0")
  1431                    {
  1432                         fdaRoot =  new FileMa nDataArray ();
  1433                         var iens =  $"{cprsTa bIen},{rem otePersonI en},";
  1434                         fdaRoot.Ad d(FileNumb er: "200.0 10113", Ie ns: iens,  FieldNumbe r: ".01",  Value: "@" );
  1435  
  1436                         try
  1437                         {
  1438                             if (fd aRoot.Coun t > 0)
  1439                             {
  1440                                 va r ddrFiler  = new Ddr Filer(mode : DdrFiler .DdrMode.U PDATE, fda Root: fdaR oot, flags : "E");
  1441                                 rp cClient.Ca ll(ddrFile r);
  1442  
  1443                                 va r cprsTabL og = "Unkn own";
  1444                                 if  (remoteCp rsTab.Valu e.CprsTabN ame.Equals ("1"))
  1445                                      cprsTabL og = "COR" ;
  1446                                 el se if (rem oteCprsTab .Value.Cpr sTabName.E quals("2") )
  1447                                      cprsTabL og = "RPT" ;
  1448  
  1449                                 Up dateLog("S uccessfull y removed  CPRS tab:  " + cprsTa bLog);
  1450                             }
  1451                         }
  1452                         catch (Rpc SocketExce ption e)
  1453                         {
  1454                             var cp rsTabLog =  "Unknown" ;
  1455                             if (re moteCprsTa b.Value.Cp rsTabName. Equals("1" ))
  1456                                 cp rsTabLog =  "COR";
  1457                             else i f (remoteC prsTab.Val ue.CprsTab Name.Equal s("2"))
  1458                                 cp rsTabLog =  "RPT";
  1459  
  1460                             string  errorMess age = "Fai led to rem ove CPRS t ab: " + cp rsTabLog;
  1461  
  1462                             Update Log(errorM essage, Lo gEntryType .Error, e) ;
  1463                         }
  1464                    }
  1465                }
  1466  
  1467                // add c prs tabs
  1468                foreach  (var claim sCprsTab i n claimsCp rsTabs)
  1469                {
  1470                    var  cprsTabIen  = claimsC prsTab.Key ;
  1471                    var  cprsTab =  claimsCprs Tab.Value;
  1472  
  1473                    fdaR oot = new  FileManDat aArray();
  1474  
  1475                    var  iens = $"+ 1,{remoteP ersonIen}, ";
  1476                    fdaR oot.Add(Fi leNumber:  "200.01011 3", Iens:  iens, Fiel dNumber: " .01", Valu e: cprsTab .CprsTabNa me);
  1477                    fdaR oot.Add(Fi leNumber:  "200.01011 3", Iens:  iens, Fiel dNumber: " .02", Valu e: cprsTab .Effective Date);
  1478                    fdaR oot.Add(Fi leNumber:  "200.01011 3", Iens:  iens, Fiel dNumber: " .03", Valu e: cprsTab .Expiratio nDate);
  1479  
  1480                    try
  1481                    {
  1482                         if (fdaRoo t.Count >  0)
  1483                         {
  1484                             var dd rFiler = n ew DdrFile r(mode: Dd rFiler.Ddr Mode.INSER T, fdaRoot : fdaRoot,  flags: "" );
  1485                             rpcCli ent.Call(d drFiler);
  1486  
  1487                             var cp rsTabLog =  "Unknown" ;
  1488                             if (cp rsTab.Cprs TabName.Eq uals("1"))
  1489                                 cp rsTabLog =  "COR";
  1490                             else i f (cprsTab .CprsTabNa me.Equals( "2"))
  1491                                 cp rsTabLog =  "RPT";
  1492  
  1493                             Update Log("Succe ssfully ad ded CPRS t ab: " + cp rsTabLog);
  1494                         }
  1495                    }
  1496                    catc h (RpcSock etExceptio n)
  1497                    {
  1498                         var cprsTa bLog = "Un known";
  1499                         if (cprsTa b.CprsTabN ame.Equals ("1"))
  1500                             cprsTa bLog = "CO R";
  1501                         else if (c prsTab.Cpr sTabName.E quals("2") )
  1502                             cprsTa bLog = "RP T";
  1503  
  1504                         string err orMessage  = "Failed  to add CPR S tab: " +  cprsTabLo g;
  1505                         UpdateLog( errorMessa ge, LogEnt ryType.Err or);
  1506                    }
  1507                }
  1508           }
  1509  
  1510           // / <summary >
  1511           // / Get a di ctionary o f all the  VistA site s a user h as permiss ion to syn chronize w ith
  1512           // / </summar y>
  1513           // / <returns >a diction ary of vis ta sites;  key = vist aSiteIen,  value = Vi staSite</r eturns>
  1514           pu blic Dicti onary<int,  VistaSite > GetVista Sites()
  1515           {
  1516                var vist aSites = n ew Diction ary<int, V istaSite>( );
  1517  
  1518                var vist aSite = ne w VistaSit e()
  1519                {
  1520                    City  = "Honolu lu",
  1521                    Disp layName =  "Honolulu  821 VEHU03 ",
  1522                    Igno reSimilarN ame = fals e,
  1523                    Inst itution =  "Instituti on",
  1524                    IsSi teOffline  = false,
  1525                    IsTe stSite = t rue,
  1526                    Over writeName  = false,
  1527                    Shel lUsername  = "vr2test ",
  1528                    Site Code = "45 9",
  1529                    Site Ien = "459 ",
  1530                    Stat e = "HI",
  1531                      VistaHostn ame = " URL ",
  1532                    Vist aPort = 97 78
  1533                };
  1534  
  1535                vistaSit es.Add(459 , vistaSit e);
  1536  
  1537                vistaSit e = new Vi staSite()
  1538                {
  1539                    City  = "Boston ",
  1540                    Disp layName =  "Boston 82  VEHU",
  1541                    Igno reSimilarN ame = fals e,
  1542                    Inst itution =  "Instituti on",
  1543                    IsSi teOffline  = false,
  1544                    IsTe stSite = t rue,
  1545                    Over writeName  = false,
  1546                    Shel lUsername  = "unknown ",
  1547                    Site Code = "55 5",
  1548                    Site Ien = "555 ",
  1549                    Stat e = "MA",
  1550                      VistaHostn ame = " URL ",
  1551                    Vist aPort = 99 99
  1552                };
  1553  
  1554                vistaSit es.Add(555 , vistaSit e);
  1555  
  1556                vistaSit e = new Vi staSite()
  1557                {
  1558                    City  = "San Fr ancisco",
  1559                    Disp layName =  "San Franc isco 820 V EHU",
  1560                    Igno reSimilarN ame = fals e,
  1561                    Inst itution =  "Instituti on",
  1562                    IsSi teOffline  = false,
  1563                    IsTe stSite = t rue,
  1564                    Over writeName  = false,
  1565                    Shel lUsername  = "unknown ",
  1566                    Site Code = "44 4",
  1567                    Site Ien = "444 ",
  1568                    Stat e = "CA",
  1569                      VistaHostn ame = " URL ",
  1570                    Vist aPort = 99 99
  1571                };
  1572  
  1573                vistaSit es.Add(444 , vistaSit e);
  1574  
  1575                return v istaSites;
  1576  
  1577                // the f ollowing r pc call is  now disab led;
  1578  
  1579                /*
  1580                using (v ar rpcClie nt = GetRp cClient())
  1581                {
  1582                    var  vistaSites  = new Dic tionary<st ring, Vist aSite>();
  1583  
  1584                    var  ddrGets =  new DdrGet s(file: "1 00100.0345 ", iens: U serIen + " ,", fields : ".02;.03 ",
  1585                         optionalFl ags: "I");
  1586                    rpcC lient.Call (ddrGets);
  1587  
  1588                    var  showAllSit es = "1".E quals(ddrG ets.GetFie ldValue(". 02", false ));
  1589                    var  showTestSi tes = "1". Equals(ddr Gets.GetFi eldValue(" .03", fals e));
  1590  
  1591                    // e mpty bucke t allocate d and used  later
  1592                    Dict ionary<str ing, Dicti onary<stri ng, string >> allSite s = null;
  1593  
  1594                    cons t string l isterField s = ".01I; .01E;.02;. 03;.04;.06 ;100;101;1 02I;103I;1 04";
  1595  
  1596                    if ( showAllSit es && show TestSites)
  1597                    {
  1598                         var sitesL ister = ne w DdrListe r(file: "1 00100.0342 ", fields:  listerFie lds);
  1599                         rpcClient. Call(sites Lister);
  1600  
  1601                         allSites =  sitesList er.GetAllR ows();
  1602                    }
  1603                    else  if (showA llSites &&  !showTest Sites)
  1604                    {
  1605                         // the scr een select s all entr ies whose  display na me DOES NO T begin wi th the @ c haracter
  1606                         var screen  = "if $ex tract($pie ce(^(0),U, 4))'=\"@\" ";
  1607                         var ddrLis ter = new  DdrLister( file: "100 100.0342",  fields: l isterField s, screen:  screen);
  1608                         rpcClient. Call(ddrLi ster);
  1609  
  1610                         allSites =  ddrLister .GetAllRow s();
  1611                    }
  1612                    else  if (!show AllSites & & showTest Sites)
  1613                    {
  1614                         // the scr een select s the site s that the  user is a uthorized  (including  test site s)
  1615                         var screen  = "if $da ta(^R1(100 100.0343,\ "AU\",DUZ, +Y))";
  1616                         var ddrLis ter = new  DdrLister( file: "100 100.0342",  fields: l isterField s, screen:  screen);
  1617                         rpcClient. Call(ddrLi ster);
  1618  
  1619                         allSites =  ddrLister .GetAllRow s();
  1620                    }
  1621                    else
  1622                    {
  1623                         // the scr een select s the site s that the  user is a uthorized  (NOT inclu ding test  sites)
  1624                         var screen  = "if $ex tract($pie ce(^(0),U, 4))'=\"@\" ,$data(^R1 (100100.03 43,\"AU\", DUZ,+Y))";
  1625                         var ddrLis ter = new  DdrLister( file: "100 100.0342",  fields: l isterField s, screen:  screen);
  1626                         rpcClient. CallAndDis connect(dd rLister);  // disconn ect from c laims
  1627  
  1628                         allSites =  ddrLister .GetAllRow s();
  1629                    }
  1630  
  1631                    if ( allSites ! = null)
  1632                    {
  1633                         // clean u p work bef ore return ing the li st of site s
  1634                         foreach (v ar row in  allSites)
  1635                         {
  1636                             var ro wMap = row .Value;
  1637  
  1638                             var di splayName  = rowMap[" .04"];
  1639                             if (di splayName. Contains(" ;"))
  1640                                 di splayName  = displayN ame.Piece( ";", 1);
  1641  
  1642                             var vi staSite =  new VistaS ite()
  1643                             {
  1644                                 Si teIen = ro wMap[".01I "],
  1645                                 In stitution  = rowMap[" .01"],
  1646                                 Di splayName  = displayN ame,
  1647                                 Vi staHostnam e = rowMap [".02"],
  1648                                 Vi staPort =  Int32.Pars e(rowMap[" .03"]),
  1649                                 Ci ty = rowMa p["100"],
  1650                                 St ate = rowM ap["101"],
  1651                                 Ov erwriteNam e = rowMap ["102I"].E quals("1") ,
  1652                                 Ig noreSimila rName = ro wMap["103I "].Equals( "1"),
  1653                                 Si teCode = r owMap["104 "],
  1654                                 Is TestSite =  (displayN ame ?? "") .StartsWit h("@"),
  1655                                 Sh ellUsernam e = rowMap [".06"]
  1656                             };
  1657  
  1658                             vistaS ites.Add(r ow.Key, vi staSite);
  1659                         }
  1660                    }
  1661  
  1662                    retu rn vistaSi tes;
  1663  
  1664                    //*/
  1665           }
  1666  
  1667           pu blic Dicti onary<int,  VistaSite > CanUserS yncToSites (IEnumerab le<int> vi staSiteIds )
  1668           {
  1669                var auth orizedVist aSites = G etVistaSit es();
  1670                var sync Sites = ne w Dictiona ry<int, Vi staSite>() ;
  1671  
  1672                foreach  (var vista SiteId in  vistaSiteI ds)
  1673                {
  1674                    try
  1675                    {
  1676                         if (author izedVistaS ites.Conta insKey(vis taSiteId))
  1677                             syncSi tes.Add(vi staSiteId,  authorize dVistaSite s[vistaSit eId]);
  1678                    }
  1679                    catc h (KeyNotF oundExcept ion)
  1680                    {
  1681                         Logger.Log Error($"SE CURITY: Us er request ed access  to Site:{v istaSiteId } but is n ot authori zed.");
  1682                    }
  1683                }
  1684  
  1685                return s yncSites;
  1686           }
  1687       }
  1688   }