1. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 6/22/2017 3:20:58 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

1.1 Files compared

# Location File Last Modified
1 TMP_CIF.zip\TMP.CRM\Plugins\VA.TMP.CRM.Plugins\Email EMailCreatePostStageRunner.cs Thu Jun 22 18:35:32 2017 UTC
2 TMP_CIF.zip\TMP.CRM\Plugins\VA.TMP.CRM.Plugins\Email EMailCreatePostStageRunner.cs Thu Jun 22 19:14:51 2017 UTC

1.2 Comparison summary

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

1.3 Comparison options

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

1.4 Active regular expressions

No regular expressions were active.

1.5 Comparison detail

  1   using MCSS hared;
  2   using Micr osoft.Crm. Sdk.Messag es;
  3   using Micr osoft.Xrm. Sdk;
  4   using Micr osoft.Xrm. Sdk.Query;
  5   using Syst em;
  6   using Syst em.Collect ions.Gener ic;
  7   using Syst em.Globali zation;
  8   using Syst em.Linq;
  9   using Syst em.Text;
  10   using VA.T MP.DataMod el;
  11   using VA.T MP.OptionS ets;
  12  
  13   namespace  VA.TMP.CRM
  14   {
  15       public  class EMa ilCreatePo stStageRun ner : Plug inRunner
  16       {         
  17           pu blic EMail CreatePost StageRunne r(IService Provider s erviceProv ider) : ba se(service Provider)  { }
  18           // Declare gl obal varia bles
  19           st ring custo mMessage;
  20           // Emergency  Contact In fo
  21           st ring SiteM ainPhone,  ProTCTName , ProTCTPh one, ProTC TEmail, Pa tTCTName,  PatTCTPhon e, PatTCTE mail, ProR oom, PatRo om, SiteLo cal911Phon e, TSAProv Emergency,  TSAPatEme rgency;
  22           
  23           st ring Patie ntVirtualM eetingSpac e = string .Empty, Pr oviderVirt ualMeeting Space = st ring.Empty ;
  24           Bo olean isCV TTablet =  false;
  25           cv t_componen t VirtualM eetingSpac e = new cv t_componen t();
  26           st ring steth IP = "";
  27  
  28           #r egion Impl ementation
  29           // / <summary >
  30           // / Called b y PluginRu nner - Dec ide which  email to s end out (a ka which b ranch of t he plugin  to run)
  31           // / </summar y>
  32           pu blic overr ide void E xecute()
  33           {
  34  
  35                Email em ail = (Ema il)Organiz ationServi ce.Retriev e(Email.En tityLogica lName.ToSt ring(), Pr imaryEntit y.Id, new  ColumnSet( true));
  36                if (emai l.Subject. StartsWith ("FW:") ||  email.Sub ject.Start sWith("RE: "))
  37                    retu rn;
  38                if (emai l.mcs_Rela tedService Activity ! = null)
  39                {
  40                    Serv iceAppoint ment relat edAppt = ( ServiceApp ointment)O rganizatio nService.R etrieve(
  41                         ServiceApp ointment.E ntityLogic alName.ToS tring(), e mail.mcs_R elatedServ iceActivit y.Id, new  ColumnSet( true));
  42                    Logg er.WriteTo File(email .Subject);
  43  
  44                    if ( (relatedAp pt.StatusC ode.Value  == 9 || re latedAppt. StatusCode .Value ==  4 || relat edAppt.Sta tusCode.Va lue == 917 290000) &&  email.Reg ardingObje ctId == nu ll)
  45                    {
  46                         if (email. Subject.St artsWith(" TMP Schedu ler Action :"))
  47                         {
  48                             Logger .WriteDebu gMessage(" Beginning  Vista Remi nder Email ");
  49                             SendVi staReminde r(email);
  50                             Logger .WriteDebu gMessage(" Completed  Vista Remi nder Email ");
  51                         }
  52                         else if (e mail.Subje ct.Contain s("Telehea lth Appoin tment Noti fication f or"))
  53                         {
  54                             Logger .WriteDebu gMessage(" Beginning  Service Ac tivity Not ification  Email");
  55                             Notify Participan tsOfAppoin tment(emai l, related Appt);
  56                             Logger .WriteDebu gMessage(" Completed  Service Ac tivity Not ification  Email");
  57                         }
  58                    }
  59                    //Se nd Patient  Email (th is email i s created  at the end  of the No tifyPartic ipantsOfAp pointment,  so this c ode will t rigger a 2 nd round o f the plug in executi on to get  to this br anch)
  60                    else  if (email .Regarding ObjectId ! = null &&  email.Rega rdingObjec tId.Logica lName == C ontact.Ent ityLogical Name)
  61                    {
  62                         Logger.Wri teDebugMes sage("Begi nning Pati ent Email" );
  63                         CreateCale ndarAppoin tmentAttac hment(emai l, related Appt, rela tedAppt.St atusCode.V alue, "");
  64                         CvtHelper. UpdateSend Email(emai l, Organiz ationServi ce);
  65                         Logger.Wri teDebugMes sage("Comp leted Pati ent Email" );
  66                    }
  67                    else
  68                         return;
  69                }
  70  
  71                if (emai l.Regardin gObjectId  != null)
  72                {
  73                    Logg er.WriteDe bugMessage ("Beginnin g Send Ema il");
  74                    swit ch (email. RegardingO bjectId.Lo gicalName)
  75                    {
  76                         //Regardin g Object:  TSA
  77                         case mcs_s ervices.En tityLogica lName:
  78                             SendTS AEmail(ema il, email. RegardingO bjectId.Id );
  79                             Logger .WriteDebu gMessage(" Completed  Send TSA E mail");
  80                             break;
  81                         //Regardin g Object:  TSS Privil eging
  82                         case cvt_t ssprivileg ing.Entity LogicalNam e:
  83                             SendPr ivilegingE mail(email , email.Re gardingObj ectId.Id,  email.Rega rdingObjec tId.Logica lName);
  84                             Logger .WriteDebu gMessage(" Completed  Send Privi leging Ema il");
  85                             break;
  86                         //Regardin g Object:  Quality Ch eck
  87                         case cvt_q ualitychec k.EntityLo gicalName:
  88                             SendTr iggerEmail (email, em ail.Regard ingObjectI d.Id, emai l.Regardin gObjectId. LogicalNam e);
  89                             Logger .WriteDebu gMessage(" Completed  FPPE/OPPE  Email");
  90                             break;
  91                         //Regardin g Object:  PPE Review
  92                         case cvt_p pereview.E ntityLogic alName:
  93                             SendPP EReviewEma il(email,  email.Rega rdingObjec tId.Id, em ail.Regard ingObjectI d.LogicalN ame);
  94                             Logger .WriteDebu gMessage(" Completed  PPE Review  Email");
  95                             break;
  96                         //Regardin g Object:  PPE Feedba ck
  97                         case cvt_p pefeedback .EntityLog icalName:
  98                             SendPP EFeedbackE mail(email , email.Re gardingObj ectId.Id,  email.Rega rdingObjec tId.Logica lName);
  99                             Logger .WriteDebu gMessage(" Completed  PPE Feedba ck Email") ;
  100                             break;
  101                         //Regardin g Object:  Provider S ite Resour ce
  102                         case cvt_p roviderres ourcegroup .EntityLog icalName:
  103                         case mcs_g roupresour ce.EntityL ogicalName :
  104                             SendTS AProviderE mail(email , email.Re gardingObj ectId.Id,  email.Rega rdingObjec tId.Logica lName);
  105                             Logger .WriteDebu gMessage(" Completed  Add Prov t o TSA Emai l");
  106                             break;  
  107                    }
  108                }
  109           }
  110  
  111   #endregion
  112  
  113           #r egion Comm only Used  Functions
  114  
  115           // / <summary >
  116           // / Overload  for basic  generateE mailBody -  displays  the url as  the messa ge for "Cl ick Here"
  117           // / </summar y>
  118           // / <param n ame="recor d">ID of t he email</ param>
  119           // / <param n ame="entit yStringNam e">string  name of th e entity -  to retrie ve object  type code< /param>
  120           // / <param n ame="custo mMessage"> The messag e</param>
  121           // / <returns ></returns >
  122           in ternal str ing genera teEmailBod y(Guid rec ord, strin g entitySt ringName,  string cus tomMessage ){
  123                return g enerateEma ilBody(rec ord, entit yStringNam e, customM essage, nu ll);
  124           }
  125  
  126           // / <summary >
  127           // / Standard  "boilerpl ate" E-Mai l body
  128           // / </summar y>
  129           // / <param n ame="recor d">ID of t he email r ecord</par am>
  130           // / <param n ame="entit yStringNam e">The str ing name o f the obje ct type co de</param>
  131           // / <param n ame="custo mMessage"> The custom  string th at goes in to the ema il body</p aram>
  132           // / <param n ame="click HereMessag e">The mes sage that  is used as  the displ ay for the  hyperlink </param>
  133           // / <returns >the body  of the ema il</return s>
  134           in ternal str ing genera teEmailBod y(Guid rec ord, strin g entitySt ringName,  string cus tomMessage , string c lickHereMe ssage)
  135           {
  136                string b ody;
  137                var etc  = CvtHelpe r.GetEntit yTypeCode( Organizati onService,  entityStr ingName);
  138                string s ervernameA ndOrgname  = CvtHelpe r.getServe rURL(Organ izationSer vice);
  139                string u rl = serve rnameAndOr gname + "/ userDefine d/edit.asp x?etc=" +  etc + "&id =" + recor d;
  140                clickHer eMessage =  (clickHer eMessage = = null ||  clickHereM essage ==  string.Emp ty) ? url  : clickHer eMessage;
  141                //Custom  email tex t
  142                body = " <br/><a hr ef=\"" + u rl + "\">"  + clickHe reMessage  + "</a>";
  143                body +=  "<br/><br/ >" + custo mMessage;
  144  
  145                //Standa rd email t ext
  146                body +=  "<br/><br/ >This is a n automate d notifica tion from  the Telehe alth Manag ement Plat form.";
  147  
  148                return b ody;
  149           }
  150  
  151           // TODO TO-DO : Consolid ate with E mail Autom ation func tion, shou ld we add  check for  User's Ema il existin g before a dding to t he AP List ?
  152           in ternal Lis t<Activity Party> Ret rieveFacil ityTeamMem bers(Email  email, Gu id TeamId,  IEnumerab le<Activit yParty> or iginalPart y)
  153           {
  154                Logger.W riteDebugM essage("st arting Ret rieveFacil ityTeamMem bers");
  155                using (v ar srv = n ew Xrm(Org anizationS ervice))
  156                {
  157                    var  teamMember s = (List< TeamMember ship>)(srv .TeamMembe rshipSet.W here(t =>  t.TeamId = = TeamId). ToList());
  158                    var  recipientL ist = new  List<Activ ityParty>( );
  159  
  160                    if ( originalPa rty != nul l)
  161                         recipientL ist.AddRan ge(origina lParty);
  162  
  163                    Logg er.WriteDe bugMessage ("About to  add membe rs of team .");
  164                    fore ach (var m ember in t eamMembers )
  165                    {
  166                         var party  = new Acti vityParty( )
  167                         {
  168                             Activi tyId = new  EntityRef erence(ema il.Logical Name, emai l.Id),
  169                             PartyI d = new En tityRefere nce(System User.Entit yLogicalNa me, member .SystemUse rId.Value)
  170                         };
  171                         recipientL ist.Add(pa rty);
  172                    }
  173                    Logg er.WriteDe bugMessage ("Finished  adding me mbers of t eam.");
  174                    retu rn recipie ntList;
  175                }
  176           }
  177           #e ndregion
  178  
  179           // TO-DO: fix  patient n otificatio n email wh en tsa is  created (t o send to  team inste ad of indi vidual use r)
  180           #r egion Send TSAEmails
  181  
  182           // / <summary >
  183           // / Returns  a string v alue repre senting th e body of  the email  for TSA ap proval not ification
  184           // / </summar y>
  185           // / <param n ame="email ">the obje ct represe nting the  email whic h is being  sent</par am>
  186           // / <param n ame="recor d">the Gui d of the T SA which i s causing  this notif ication to  be sent</ param>
  187           // / <param n ame="entit yStringNam e">the ent ity logica l name of  the tsa (i .e. "mcs_s ervices")< /param>
  188           // / <returns ></returns >
  189           in ternal str ing Approv alEmailBod y(Email em ail)
  190           {
  191  
  192                var appr over = Str ing.Empty;
  193                var next Team = Str ing.Empty;
  194                var FTC  = String.E mpty;
  195                var patF acility =  String.Emp ty;
  196                //Get th e Previous  approvers  by queryi ng most re cent note
  197                using (v ar srv = n ew Xrm(Org anizationS ervice))
  198                {
  199                    var  TSANote =  srv.Annota tionSet.Wh ere(n => n .ObjectId. Id == emai l.Regardin gObjectId. Id).OrderB yDescendin g(n => n.C reatedOn). First(n =>  n.NoteTex t.Contains ("Approved  by"));
  200                    //mo st recent  approver
  201                    appr over = TSA Note.Creat edBy.Name;
  202                    var  tsa = srv. mcs_servic esSet.Firs tOrDefault (t => t.Id  == email. RegardingO bjectId.Id );
  203                    patF acility =  tsa.cvt_Pa tientFacil ity == nul l ? String .Empty : "  To " + ts a.cvt_Pati entFacilit y.Name;
  204                    if ( tsa.cvt_Se rviceScope .Value ==  917290001)
  205                         patFacilit y = " (Int rafacility )";
  206                    //Ge t the next  approver  up and get  the FTC w ho created  the TSA ( assumed to  be provid er side) a nd the FTC  who first  approved  the TSA (a ssumed to  be patient  side)
  207                    swit ch (tsa.st atuscode.V alue)
  208                    {
  209                         case (int) mcs_servic es_statusc ode.Approv edbyPatFTC
  210                             nextTe am = "Prov ider FTC T eam";
  211                             goto c ase 0;
  212                         case (int) mcs_servic es_statusc ode.Approv edbyProvFT C:
  213                             nextTe am = "Prov ider Servi ce Chief T eam";
  214                             goto c ase 0;
  215                         case (int) mcs_servic es_statusc ode.Approv edbyProvSe rviceChief :
  216                             nextTe am = "Prov ider Chief  of Staff  Team";
  217                             goto c ase 0;
  218                         case (int) mcs_servic es_statusc ode.Approv edbyProvCh iefofStaff
  219                             nextTe am = "Pati ent Servic e Chief Te am";
  220                             goto c ase -1;
  221                         case (int) mcs_servic es_statusc ode.Approv edbyPatSer viceChief:  
  222                             nextTe am = "Pati ent Chief  of Staff T eam";
  223                             goto c ase -1;
  224                         case 0: // if Provide r side - g et the use r who crea ted the TS A - assume d to be th e Provider  FTC
  225                             FTC =  srv.System UserSet.Fi rstOrDefau lt(u => u. Id == tsa. CreatedBy. Id).FullNa me;
  226                             break;
  227                         case -1: / /If patien t side - g et user wh o first ap proved the  TSA - ass umed to be  the Patie nt FTC
  228                             var fi rstApprove r = srv.An notationSe t.Where(n  => n.Objec tId.Id ==  email.Rega rdingObjec tId.Id).Or derBy(n =>  n.Created On).First( n => n.Not eText.Cont ains("Appr oved by")) ;
  229                             FTC =  firstAppro ver.Create dBy.Name;
  230                             break;
  231                    }
  232                }
  233  
  234                //TODO:  Add patien t facility , change s pacing
  235                //get th e FTC for  whichever  side the T SA is awai ting appro val
  236                string h yperlink =  GetTSALin k(email);
  237                  string Ops Manual = " http://vaw w.infoshar e. DNS     /sites/tel ehealth/do cs/tmp-use r-tsa-appr .docx";
  238                  string Rol lOut = "ht tp://vaww. telehealth . DNS     /quality/t mp/index.a sp";
  239                string e mailBody =  String.Fo rmat("A Te lehealth S ervice Agr eement (TS A), {0} is  awaiting  your appro val. <br/> <ul><li>Pr evious App rover: {1} </li>" +
  240                    "<li >{2} is th e next in  line for t he TSA App roval Proc ess. </ul> The hyperl ink below  will take  you to the  Telehealt h Service  Agreement.   If you w ish to mak e changes  to the TSA  prior to  approval,  please con tact {3}.   If you ch oose to ap prove the  TSA, pleas e select t he Green B utton on t he top lef t corner.   If you ch oose to de cline appr oval, plea se select  the Red Bu tton on th e top left  corner.<b r/><br/><b >Click her e to take  action on  the TSA</b >: {4} <br /><br/>",  email.Rega rdingObjec tId.Name +  patFacili ty, approv er, nextTe am, FTC, h yperlink);
  241                string l oginNotes  = String.F ormat("Not e: A passw ord is not  required  to access  TMP.  Your  credentia ls are pas sed from W indows aut henticatio n used to  log on to  your compu ter.  Simp ly click t he link ab ove.  For  first time  access, o r access a fter a lon g period o f time, yo u may be p rompted to  choose \" VA Account s\" on a p op-up form .  After t hat, click ing the li nk will ta ke you dir ectly to t he TSA.  < br/><br/>T o see a br ief tutori al for app rovers, cl ick this l ink: {0} < br/><br/>T o access a ll resourc es (traini ng materia ls, operat ions manua l, etc.) f or TMP use rs, click  this link:  {1}", "<a  href=\""  + OpsManua l + "\">"  + OpsManua l + "</a>" , "<a href =\"" + Rol lOut + "\" >" + RollO ut + "</a> ");
  242           
  243                return e mailBody +  loginNote s;
  244           }
  245  
  246           // Send appro priate ema il based o n subject  line (deni al, under  revision,  reminder t o take act ion, waiti ng for app roval)
  247           in ternal voi d SendTSAE mail(Email  email, Gu id tsaID)
  248           {
  249                switch ( email.Subj ect)
  250                {
  251                    case  "A Telehe alth Servi ce Agreeme nt has bee n denied":  //Denial
  252                         email.Desc ription =  generateEm ailBody(ts aID, "mcs_ services",  "The foll owing Tele health Ser vice Agree ment has b een Denied .  Please  review the  notes to  see the De nial Reaso n and corr ect any mi stakes if  applicable .", "Click  Here to v iew this T SA");
  253                         break;
  254                    case  "TSA unde r revision ": //Revis ion
  255                         customMess age = "The  following  Telehealt h Service  Agreement  is Under R evision.";
  256                         break;
  257                    case  "Please T ake Action  on the fo llowing TS A": //Remi nder
  258                         customMess age = "Thi s is a rem inder that  the follo wing Teleh ealth Serv ice Agreem ent is wai ting for y ou to take  action.";
  259                         break;
  260                    case  "FYI: A T elehealth  Service Ag reement ha s been com pleted": / /Productio n Notifica tion
  261                         email.Desc ription =  TSANotific ationText( email);
  262                         break;
  263                    case  "A TSA to  your Faci lity has b een create d": //Noti fy patient  site that  TSA was c reated
  264                         email.Desc ription =  generateEm ailBody(ts aID, "mcs_ services",  "Please c oordinate  with the P rovider Si te FTC to  set up the  following  TSA.  Onc e all the  details ar e finalize d, it is t he respons ibility of  the Patie nt Site FT C to begin  the Signa ture colle ction proc ess.", "Cl ick Here t o view thi s TSA");
  265                         break;
  266                    defa ult:
  267                         if (email. Subject.Co ntains("Te lehealth S ervice Agr eement is  awaiting y our approv al")) //Ap proval
  268                             email. Descriptio n = Approv alEmailBod y(email);
  269                         else
  270                         {
  271                             Logger .WriteToFi le("Unable  to match  email subj ect to val id TSA ema il type, e xiting plu gin");
  272                             return ;
  273                         }
  274                         break;
  275                }
  276                //Get Te am Members  will quer y the Team  Members t able and r eturn an A ctivity Pa rty List o f the peop le listed  on the tea m specifie d
  277                //If can t find tea m members,  log the e rror and c ontinue at tempting t o populate  the messa ge descrip tion
  278                try
  279                {
  280                    emai l.To = Get TeamMember s(email, t saID);
  281                    Logg er.WriteDe bugMessage ("Populate d Email Re cipients") ;
  282                }
  283                catch (E xception e x)
  284                {
  285                    Logg er.WriteTo File(ex.Me ssage);
  286                }
  287                if (emai l.Descript ion == nul l)
  288                    emai l.Descript ion = gene rateEmailB ody(tsaID,  "mcs_serv ices", cus tomMessage , "Click H ere to app rove/deny  this TSA") ;
  289                //Get th e owner of  the workf low for th e From fie ld
  290                if (emai l.From.Cou nt() == 0)
  291                    emai l.From = C vtHelper.G etWorkflow Owner("TSA  Approval  Step 1 - A waiting Pr ov FTC", O rganizatio nService);
  292                Logger.W riteDebugM essage("Se nding TSA  Email");
  293                CvtHelpe r.UpdateSe ndEmail(em ail, Organ izationSer vice);
  294                Logger.W riteDebugM essage("TS A Email Se nt");
  295           }
  296  
  297           in ternal str ing GetTSA Link(Email  email)
  298           {
  299                var etc  = CvtHelpe r.GetEntit yTypeCode( Organizati onService,  mcs_servi ces.Entity LogicalNam e);
  300                string s ervernameA ndOrgname  = CvtHelpe r.getServe rURL(Organ izationSer vice);
  301                string u rl = serve rnameAndOr gname + "/ userDefine d/edit.asp x?etc=" +  etc + "&id =" + email .Regarding ObjectId.I d;
  302                return S tring.Form at("<a hre f=\"{0}\"> {1}</a>",  url, url);
  303           }
  304  
  305           in ternal str ing TSANot ificationT ext(Email  email)
  306           {
  307                  return Str ing.Format ("For your  informati on, a Tele health Ser vice Agree ment (TSA) , {0} has  been appro ved.    <br/>The h yperlink b elow will  take you t o the Tele health Ser vice Agree ment. \n\n Click here  to view t he TSA: {1 } <br /><b r />Note:  A password  is not re quired to  access TMP . Your cre dentials a re passed  from Windo ws authent ication us ed to log  on to your  computer.  Simply cl ick the li nk above.  For first  time acces s, or acce ss after a  long peri od of time , you may  be prompte d to choos e \"VA Acc ounts\" on  a pop-up  form.    After that , clicking  the link  will take  you direct ly to the  TSA.    <br /><br  />To acces s all reso urces (tra ining mate rials, ope rations ma nual, etc. ) for TMP  users, cli ck this li nk: {2}",  email.Rega rdingObjec tId.Name,  GetTSALink (email), S tring.Form at("<a hre f=\"{0}\"> {0}</a>",  "http://va ww.telehea lth. DNS     /quality/t mp/index.a sp"));
  308           }
  309  
  310           // / <summary >
  311           // / Query th e team mem bership ta ble to get  the team  appropriat e for the  status of  the TSA.   return the  list of a ctivity pa rties corr esponding  to the sys tem users  that are m embers of  the team.   
  312           // / </summar y>
  313           // / <param n ame="email ">This is  the email  record tha t is being  built and  eventuall y gets sen t out</par am>
  314           // / <param n ame="tsaID ">This is  the ID of  the TSA th at generat ed this em ail.  Base d on the s tatus of t he TSA, a  specific t eam will b e selected </param>
  315           // / <returns >Activity  Party List  correspon ding to Sy stem users  that are  members of  the team< /returns>
  316           in ternal Lis t<Activity Party> Get TeamMember s(Email em ail, Guid  tsaID)
  317           {
  318                //Status  Listing:  917290002= =Approved  by Pat FTC , 91729000 0==Prov FT C, 9172900 01==Prov S C, 9172900 04==Prov C oS, 917290 005==Pat S C, 9172900 06==Pendin g Privileg ing, 25192 0000==PROD , 91729000 3==DENIED,  917290007 ==UNDER RE VISION; 91 7290008==A pproved by  Prov C&P
  319                var memb ers = new  List<Activ ityParty>( );
  320                var team Members =  new List<T eamMembers hip>();
  321                using (v ar srv = n ew Xrm(Org anizationS ervice))
  322                {
  323                    //Ge t both the  Patient a nd Provide r Facility  to check  for the te ams on bot h sides
  324                    var  tsa = srv. mcs_servic esSet.Firs t(t => t.I d == tsaID );
  325                    var  proFacilit yId = tsa. cvt_Provid erFacility .Id;
  326                    var  patFacilit yId = tsa. cvt_Patien tFacility  != null ?  tsa.cvt_Pa tientFacil ity.Id : G uid.Empty;
  327                    var  team = new  Team();
  328                    swit ch (tsa.st atuscode.V alue)
  329                    {
  330                         case (int) mcs_servic es_statusc ode.Draft:  //For Dra ft TSAs, s end notifi cation tha t TSA has  been creat ed for the ir site. 
  331                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == patFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == (int)Te amcvt_Type .FTC);
  332                             break;
  333                         case (int) mcs_servic es_statusc ode.Approv edbyPatFTC ://Approve d by Patie nt Site FT C (get Pro vider Site  FTC Team)  - Workflo w Step 1
  334                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == (int)Te amcvt_Type .FTC);
  335                             break;
  336                         case (int) mcs_servic es_statusc ode.Approv edbyProvFT C://Approv ed by Prov ider Site  FTC (get P rovider Se rvice Chie f Team) -  Workflow S tep 2
  337                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&
  338                                 t. cvt_Type ! = null &&  t.cvt_Type .Value ==  (int)Teamc vt_Type.Se rviceChief  && t.cvt_ ServiceTyp e.Id == ts a.cvt_serv icetype.Id );
  339                             break;
  340                         case (int) mcs_servic es_statusc ode.Approv edbyProvSe rviceChief ://Approve d by Provi der Servic e Chief (g et Prov Ch ief of Sta ff Team) -  Workflow  Step 3
  341                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == (int)Te amcvt_Type .ChiefofSt aff);
  342                             break;
  343                         case (int) mcs_servic es_statusc ode.Approv edbyProvCh iefofStaff ://Approve d by Provi der Site C hief of St aff (Get P atient Sit e Service  Chief) - W orkflow St ep 5
  344                             if (pa tFacilityI d != Guid. Empty)
  345                                 te am = srv.T eamSet.Fir stOrDefaul t(t => t.c vt_Facilit y.Id == pa tFacilityI d &&
  346                                      t.cvt_Ty pe != null  && t.cvt_ Type.Value  == (int)T eamcvt_Typ e.ServiceC hief && t. cvt_Servic eType.Id = = tsa.cvt_ servicetyp e.Id);
  347                             break;
  348                         case (int) mcs_servic es_statusc ode.Approv edbyPatSer viceChief: //Approved  by Patien t Site Ser vice Chief  (Get Pati ent Site C hief of St aff) - Wor kflow Step  6
  349                             if (pa tFacilityI d != Guid. Empty)
  350                                 te am = srv.T eamSet.Fir stOrDefaul t(t => t.c vt_Facilit y.Id == pa tFacilityI d && t.cvt _Type != n ull && t.c vt_Type.Va lue == (in t)Teamcvt_ Type.Chief ofStaff);
  351                             break;
  352                         case (int) mcs_servic es_statusc ode.UnderR evision:// Get both s ide FTCs w hether it  is in Deni ed status  or in Unde r Revision
  353                         case (int) mcs_servic es_statusc ode.Denied :
  354                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == (int)Te amcvt_Type .FTC);
  355                             if (te am != null )
  356                                 te amMembers  = (List<Te amMembersh ip>)(srv.T eamMembers hipSet.Whe re(t => t. TeamId ==  team.Id).T oList());
  357  
  358                             //repu rpose team  variable  to get pat ient facil ity (prov  facility t eam member s have alr eady been  added abov e) and add  team memb ers from p at facilit y
  359                             if (pa tFacilityI d != Guid. Empty)
  360                             {
  361                                 te am = srv.T eamSet.Fir stOrDefaul t(t => t.c vt_Facilit y.Id == pa tFacilityI d && t.cvt _Type != n ull && t.c vt_Type.Va lue == (in t)Teamcvt_ Type.FTC);
  362                                 if  (team !=  null)
  363                                 {
  364                                      if (team Members.Co unt == 0)
  365                                          team Members =  (List<Team Membership >)(srv.Tea mMembershi pSet.Where (t => t.Te amId == te am.Id).ToL ist());
  366                                      else
  367                                          team Members.Ad dRange((Li st<TeamMem bership>)( srv.TeamMe mbershipSe t.Where(t  => t.TeamI d == team. Id).ToList ()));
  368                                 }
  369                             }
  370                             break;
  371                         case (int) mcs_servic es_statusc ode.Produc tion: //PR OD - Get B oth sides  notificati on team fo r TSA Noti fication e mail
  372                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == (int)Te amcvt_Type .TSANotifi cation);
  373                             if (te am != null )
  374                                 te amMembers  = (List<Te amMembersh ip>)(srv.T eamMembers hipSet.Whe re(t => t. TeamId ==  team.Id).T oList());
  375  
  376                             //repu rpose team  variable  to get pat ient facil ity (prov  facility t eam member s have alr eady been  added abov e) and add  team memb ers from p at facilit y (if not  intrafacil ity)
  377                             if (pa tFacilityI d != Guid. Empty && p atFacility Id != proF acilityId)
  378                             {
  379                                 te am = srv.T eamSet.Fir stOrDefaul t(t => t.c vt_Facilit y.Id == pa tFacilityI d && t.cvt _Type != n ull && t.c vt_Type.Va lue == (in t)Teamcvt_ Type.TSANo tification );
  380                                 if  (team !=  null)
  381                                 {
  382                                      if (team Members.Co unt == 0)
  383                                          team Members =  (List<Team Membership >)(srv.Tea mMembershi pSet.Where (t => t.Te amId == te am.Id).ToL ist());
  384                                      else
  385                                          team Members.Ad dRange((Li st<TeamMem bership>)( srv.TeamMe mbershipSe t.Where(t  => t.TeamI d == team. Id).ToList ()));
  386                                 }
  387                             }
  388                             break;  
  389                    }
  390                    if ( team == nu ll)
  391                         throw new  InvalidPlu ginExecuti onExceptio n("No Team  was found  to receiv e this ema il, please  verify th e team is  set up");
  392                    if ( teamMember s.Count ==  0) //if y ou havent  already ad ded the te am members  (everthin g other th an prod no tification , under re vision and  denial) t hen add no w
  393                         teamMember s = (List< TeamMember ship>)(srv .TeamMembe rshipSet.W here(t =>  t.TeamId = = team.Id) .ToList()) ;
  394                    fore ach (var m ember in t eamMembers )
  395                    {
  396                         var party  = new Acti vityParty( ){
  397                             Activi tyId = new  EntityRef erence(ema il.Logical Name, emai l.Id),
  398                             PartyI d = new En tityRefere nce(System User.Entit yLogicalNa me, member .SystemUse rId.Value)
  399                         };
  400                         members.Ad d(party);
  401                    }
  402                }
  403                if (memb ers.Count  == 0)
  404                    memb ers.AddRan ge(email.T o);
  405                return m embers;
  406           }
  407  
  408           #e ndregion
  409  
  410           #r egion Send serviceapp ointmentNo tification s
  411  
  412           // / <summary >
  413           // / Primary  function w hich gener ates the S ervice Act ivity noti fication ( including  ical)
  414           // / </summar y>
  415           // / <param n ame="email ">The emai l object c orrespondi ng to the  email reco rd created  which tri ggered thi s plugin</ param>
  416           // / <param n ame="relat edAppt">Th e service  activity w hich gener ated the e mail and i s the subj ect of the  notificat ion</param >
  417           in ternal voi d NotifyPa rticipants OfAppointm ent(Email  email, Ser viceAppoin tment rela tedAppt)
  418           {
  419                List<Sys temUser> p roTCTuser  = new List <SystemUse r>();
  420                List<Sys temUser> p atTCTuser  = new List <SystemUse r>();
  421  
  422                //Get th e TSA so y ou can fig ure out wh ether the  resource i s provider  or patien t side
  423                mcs_serv ices tsa =  (mcs_serv ices)Organ izationSer vice.Retri eve(mcs_se rvices.Ent ityLogical Name, rela tedAppt.mc s_relatedt sa.Id, new  ColumnSet (true));
  424  
  425                //Get th e Pro/Pat  Emergency  Info from  TSA
  426                TSAProvE mergency =  tsa.cvt_P roviderSta ffEmergenc yResponsib ilities;
  427                TSAPatEm ergency =  tsa.cvt_Pa tientStaff EmergencyR esponsibil ities;
  428  
  429                if (tsa. cvt_Patien tSiteClini calPOC !=  null)
  430                {
  431                    Guid  TCTonTSA  = tsa.cvt_ PatientSit eClinicalP OC.Id;
  432                    //Ge t the TCTs  Mobile or  Office ph one 
  433                    Syst emUser tct  = (System User)Organ izationSer vice.Retri eve(System User.Entit yLogicalNa me, TCTonT SA, new Co lumnSet("m obilephone ", "cvt_of ficephone" , "firstna me", "last name", "in ternalemai laddress") );
  434                    PatT CTPhone =  tct.Mobile Phone;  // Use the TC T number
  435                    PatT CTName = t ct.FirstNa me + " " +  tct.LastN ame;
  436                    PatT CTEmail =  tct.Intern alEMailAdd ress;
  437                    patT CTuser.Add (tct);
  438                    if ( PatTCTPhon e == null)
  439                         PatTCTPhon e = tct.cv t_officeph one;  //Us e the TCT  number
  440                }
  441  
  442                //Get th e Pro TCT
  443                if (tsa. cvt_Provid erSiteClin icalPOC !=  null)
  444                {
  445                    Guid  TCTonTSA  = tsa.cvt_ ProviderSi teClinical POC.Id;
  446                    //Ge t the TCTs  Mobile or  Office ph one 
  447                    Syst emUser tct  = (System User)Organ izationSer vice.Retri eve(System User.Entit yLogicalNa me, TCTonT SA, new Co lumnSet("m obilephone ", "cvt_of ficephone" , "firstna me", "last name", "in ternalemai laddress") );
  448                    ProT CTPhone =  tct.Mobile Phone;  // Use the TC T number
  449                    ProT CTName = t ct.FirstNa me + " " +  tct.LastN ame;
  450                    ProT CTEmail =  tct.Intern alEMailAdd ress;
  451                    proT CTuser.Add (tct);
  452                    if ( ProTCTPhon e == null)
  453                         ProTCTPhon e = tct.cv t_officeph one;  //Us e the TCT  number
  454                }
  455                //Pro Le ad TCT
  456                if (ProT CTPhone ==  null) //N o Phone fr om TCT fro m TSA, loo k at Site  specified  one.
  457                {
  458                    if ( tsa.cvt_re latedprovi dersiteid. Id != null ) //Check  for TSA Pr ovider Sit e
  459                    {
  460                         //Get Prov ider Site
  461                         //get the  TSA's rela ted patien t site
  462                         mcs_site r elatedpros ite = (mcs _site)Orga nizationSe rvice.Retr ieve(mcs_s ite.Entity LogicalNam e, tsa.cvt _relatedpr ovidersite id.Id, new  ColumnSet (true));
  463  
  464                         if (relate dprosite.c vt_LeadTCT  != null)
  465                         {
  466                             //Get  the Lead T CTs Mobile  or Office  phone 
  467                             System User tct =  (SystemUs er)Organiz ationServi ce.Retriev e(SystemUs er.EntityL ogicalName , relatedp rosite.cvt _LeadTCT.I d, new Col umnSet("mo bilephone" , "cvt_off icephone",  "firstnam e", "lastn ame", "int ernalemail address")) ;
  468                             ProTCT Phone = tc t.MobilePh one;  //Us e the TCT  number
  469                             ProTCT Name = tct .FirstName  + " " + t ct.LastNam e;
  470                             ProTCT Email = tc t.Internal EMailAddre ss;
  471                             proTCT user.Clear ();
  472                             proTCT user.Add(t ct);
  473                             if (Pr oTCTPhone  == null)
  474                                 Pr oTCTPhone  = tct.cvt_ officephon e;  //Use  the TCT nu mber
  475                         }
  476                    }
  477                }
  478                //If CVT  to Home,  there is n o patient  site
  479                if ((tsa .cvt_Type  != true) & & (tsa.cvt _groupappo intment !=  true))
  480                {
  481                    //ge t the TSA' s related  patient si te
  482                    mcs_ site relat edpatsite  = (mcs_sit e)Organiza tionServic e.Retrieve (mcs_site. EntityLogi calName, t sa.cvt_rel atedpatien tsiteid.Id , new Colu mnSet(true ));
  483                    //Ge t the Site 's Emergen cy Contact  Info
  484                    if ( relatedpat site.cvt_L ocal911 !=  null)
  485                         SiteLocal9 11Phone =  relatedpat site.cvt_L ocal911; / /Use the L ocal 911
  486                    if ( relatedpat site.cvt_p hone != nu ll)
  487                         SiteMainPh one = rela tedpatsite .cvt_phone ; //Use th e Site Pho ne
  488  
  489                    //Pa t Lead TCT
  490                    if ( PatTCTPhon e == null)  //No Phon e from TCT  from TSA,  look at P at Site sp ecified on e.
  491                    {
  492                         if (relate dpatsite.c vt_LeadTCT  != null)
  493                         {
  494                             //Get  the Lead T CTs Mobile  or Office  phone 
  495                             System User tct =  (SystemUs er)Organiz ationServi ce.Retriev e(SystemUs er.EntityL ogicalName , relatedp atsite.cvt _LeadTCT.I d, new Col umnSet("mo bilephone" , "cvt_off icephone",  "firstnam e", "lastn ame", "int ernalemail address")) ;
  496                             PatTCT Phone = tc t.MobilePh one;  //Us e the TCT  number
  497                             PatTCT Name = tct .FirstName  + " " + t ct.LastNam e;
  498                             PatTCT Email = tc t.Internal EMailAddre ss;
  499                             patTCT user.Clear ();
  500                             patTCT user.Add(t ct);
  501                             if (Pa tTCTPhone  == null)
  502                                 Pa tTCTPhone  = tct.cvt_ officephon e;  //Use  the TCT nu mber
  503                         }
  504                    }
  505                }
  506  
  507                //Get th e Pat TCT
  508                //Get th e resource s listed o n the serv ice activi ty
  509                var reso urces = re latedAppt. GetAttribu teValue<En tityCollec tion>("res ources");
  510                EntityCo llection u sers = new  EntityCol lection();
  511                EntityCo llection e quipmentRe sources =  new Entity Collection ();
  512                resource s.Entities .AddRange( GetApptRes ources(rel atedAppt,  string.Emp ty));
  513  
  514                //Get th e users fr om the res ource list  (filter o ut equipme nt)
  515                foreach  (var res i n resource s.Entities )
  516                {
  517                    var  party = re s.ToEntity <ActivityP arty>();
  518                    if ( party.Part yId.Logica lName == S ystemUser. EntityLogi calName)
  519                    {
  520                         ActivityPa rty p = ne w Activity Party()
  521                         {
  522                             PartyI d = new En tityRefere nce(System User.Entit yLogicalNa me, party. PartyId.Id )
  523                         };
  524                         users.Enti ties.Add(p );
  525                    }
  526                    else
  527                    {
  528                         Equipment  e = (Equip ment)Organ izationSer vice.Retri eve(Equipm ent.Entity LogicalNam e, party.P artyId.Id,  new Colum nSet("equi pmentid",  "mcs_relat edresource "));
  529                         mcs_resour ce equip =  (mcs_reso urce)Organ izationSer vice.Retri eve(mcs_re source.Ent ityLogical Name, e.mc s_relatedr esource.Id , new Colu mnSet(true ));
  530                         equipmentR esources.E ntities.Ad d(equip);
  531                    }
  532                }
  533  
  534                //Get th e rooms an d techs an d segment  them by pa tient/prov ider site
  535                var tsaP roResource s = getPRG s(tsa.Id,  "provider" );
  536                var tsaP atResource s = getPRG s(tsa.Id,  "patient") ;
  537                var prov iderTechs  = Classify Resources( equipmentR esources,  tsaProReso urces, (in t)mcs_reso urcetype.T echnology) ;
  538                var pati entTechs =  ClassifyR esources(e quipmentRe sources, t saPatResou rces, (int )mcs_resou rcetype.Te chnology);
  539                var prov iderRooms  = Classify Resources( equipmentR esources,  tsaProReso urces, (in t)mcs_reso urcetype.R oom);
  540                var pati entRooms =  ClassifyR esources(e quipmentRe sources, t saPatResou rces, (int )mcs_resou rcetype.Ro om);
  541  
  542                //select  which use rs to send  the email  to (provi ders/patie nts): null  means pro vider side , 1 means  patient si de (and 0  means both )
  543                var prov iderResour ces = GetR ecipients( users, tsa ProResourc es);
  544                var pati entResourc es = GetRe cipients(u sers, tsaP atResource s);
  545  
  546                //Get pr oviders so  we can pa ss in stri ng for lis t of clini cians to p atient ema il
  547                var clin icians = p roviderRes ources;
  548  
  549                //format  body of t he email ( telepresen ters can b e duplicat ed)
  550                var date  = string. Empty;
  551                var patS ite = tsa. cvt_relate dpatientsi teid;
  552                var patS iteString  = patSite  != null ?  patSite.Na me : strin g.Empty;
  553                if (patS iteString  == string. Empty)
  554                    patS iteString  = tsa.cvt_ groupappoi ntment.Val ue == true  ? tsa.cvt _PatientFa cility.Nam e : "Home/ Mobile";
  555                email.De scription  = formatNo tification EmailBody( providerTe chs, patie ntTechs, p roviderRoo ms, patien tRooms, pa tientResou rces, rela tedAppt, t sa, provid erResource s, out dat e);
  556                email.Su bject = em ail.Subjec t.Trim() +  " " + pat SiteString  + " " + d ate;
  557                //Combin e the list s and then  add them  as the ema il recipie nts
  558                provider Resources. AddRange(p atientReso urces);
  559  
  560                //Add th e Pro and  Pat TCT to  the .To
  561                provider Resources. AddRange(p roTCTuser) ;
  562                provider Resources. AddRange(p atTCTuser) ;
  563  
  564                email.To  = CvtHelp er.SetPart yList(prov iderResour ces);
  565  
  566                //Get th e owner of  the workf low for th e From fie ld    
  567                if (emai l.From.Cou nt() == 0)
  568                    emai l.From = C vtHelper.G etWorkflow Owner("Ser vice Activ ity Notifi cation", O rganizatio nService);
  569                //Organi zationServ ice.Update (email);
  570  
  571                //Send a  Calendar  Appointmen t if the a ppointment  is schedu led (if ca nceled, se nd cancell ation upda te)
  572                CreateCa lendarAppo intmentAtt achment(em ail, relat edAppt, re latedAppt. StatusCode .Value, st ethIP);
  573                CvtHelpe r.UpdateSe ndEmail(em ail, Organ izationSer vice);
  574  
  575                // Only  send patie nt email f or Home/Mo bile TSAs 
  576                // Futur e Phase TO DO: use st atic VMRs  and notify  patient t o hit desk top icon
  577                if (tsa. cvt_Type.V alue == tr ue)
  578                {
  579                    //Cr eate and S end Email  to Patient /Veteran ( copy sende r from Pro vider Emai l)
  580                    var  providerEm ailSender  = new Enti tyCollecti on();
  581                    prov iderEmailS ender.Enti ties.AddRa nge(email. From);
  582                    Send PatientEma il(related Appt, prov iderEmailS ender, cli nicians);
  583                }
  584           }
  585  
  586           in ternal str ing getPat ientVirtua lMeetingSp ace(Servic eAppointme nt sa, out  bool? pat ientSpace)
  587           {
  588                Logger.W riteDebugM essage("Ge tting Virt ual Meetin g Space");
  589                patientS pace = nul l;
  590                if (sa.m cs_Patient Url != nul l && sa.mc s_provider url != nul l)
  591                {
  592                    Pati entVirtual MeetingSpa ce = sa.mc s_PatientU rl;
  593                    Prov iderVirtua lMeetingSp ace = sa.m cs_provide rurl;
  594                    Logg er.WriteDe bugMessage ("Virtual  Meeting Sp ace is fro m Service  Activity R ecord: " +  PatientVi rtualMeeti ngSpace +  ", " + Pro viderVirtu alMeetingS pace);
  595                }
  596                else
  597                {
  598                    var  patientAP  = sa.Custo mers.First OrDefault( );
  599                    if ( patientAP  == null ||  patientAP .PartyId = = null)
  600                         return str ing.Empty;
  601                    Logg er.WriteDe bugMessage (sa.Custom ers.ToList ().Count() .ToString( ) + " pati ents " + p atientAP.P artyId.Nam e.ToString ());
  602                    var  patient =  (Contact)O rganizatio nService.R etrieve(Co ntact.Enti tyLogicalN ame, patie ntAP.Party Id.Id, new  ColumnSet (true));
  603                    Logg er.WriteDe bugMessage ("Contact:  " + patie nt.FullNam e + " VMR:  " + patie nt.cvt_Pat ientVirtua lMeetingSp ace + " an d Tablet:  " + patien t.cvt_BLTa blet);
  604                    if ( patient !=  null && p atient.cvt _PatientVi rtualMeeti ngSpace !=  null)
  605                    {
  606                         patientSpa ce = true;
  607                         PatientVir tualMeetin gSpace = p atient.cvt _PatientVi rtualMeeti ngSpace;
  608                         ProviderVi rtualMeeti ngSpace =  patient.cv t_Provider VirtualMee tingSpace;
  609                    }
  610                    else  if (patie nt != null  && patien t.cvt_BLTa blet != nu ll)
  611                    {
  612                         patientSpa ce = false ;
  613                         PatientVir tualMeetin gSpace = p atient.cvt _BLTablet;
  614                         isCVTTable t = true;
  615                    }
  616                    else  if (Virtu alMeetingS pace.Id !=  new Guid( ))
  617                         PatientVir tualMeetin gSpace = V irtualMeet ingSpace.c vt_webinte rfaceurl;
  618                    else
  619                         PatientVir tualMeetin gSpace = " Please Con tact Your  TCT for We b Meeting  Details";
  620                    Logg er.WriteDe bugMessage (PatientVi rtualMeeti ngSpace +  ": Virtual  Meeting S pace is fr om Patient  record =  " + patien tSpace.ToS tring());
  621                }
  622                return P atientVirt ualMeeting Space;
  623           }
  624  
  625           in ternal voi d SendPati entEmail(S erviceAppo intment sa , EntityCo llection F rom, List< SystemUser > provs)
  626           {
  627                if (Virt ualMeeting Space != n ull && Vir tualMeetin gSpace.Id  != Guid.Em pty || Pat ientVirtua lMeetingSp ace.IndexO f("Please  Contact Yo ur") == -1
  628                    // l ast check  is only re levant if  we do not  want to ge nerate ema il at all  given the  scenario w here no vi rtual meet ing space  is provide d
  629                {
  630                    //Ge t the Pati ent and th eir timezo ne
  631                    var  patientAP  = sa.Custo mers.First OrDefault( );
  632                    if ( patientAP  == null)
  633                         Logger.Wri teToFile(" No Patient  was found  to receiv e the emai l for foll owing Serv ice Activi ty: " + sa .Id);
  634                    else
  635                    {
  636                         var recipi ent = new  ActivityPa rty()
  637                         {
  638                             PartyI d = new En tityRefere nce(Contac t.EntityLo gicalName,  patientAP .PartyId.I d)
  639                         };
  640                         Logger.Wri teDebugMes sage("Send ing Patien t Email to  " + patie ntAP.Party Id.Name);
  641                         var patien t = (Conta ct)Organiz ationServi ce.Retriev e(Contact. EntityLogi calName, r ecipient.P artyId.Id,  new Colum nSet(true) );
  642  
  643                         //Setup va riables to  get timeZ one conver sion prope rly
  644                         DateTime t imeConvers ion = sa.S cheduledSt art.Value;
  645                         string ful lDate = st ring.Empty , timeZone sString =  string.Emp ty;
  646                         bool conve rtSuccess  = false;
  647                         bool isCan celled = ( sa.StatusC ode.Value  == 9 || sa .StatusCod e.Value ==  917290000 ) ? true :  false; // Cancellati on
  648                         int timeZo ne = patie nt.cvt_Tim eZone != n ull ? pati ent.cvt_Ti meZone.Val ue : 35; / /default t ime zone t o East Coa st if its  not listed  on the pa tient reco rd
  649  
  650                         timeConver sion = Con vertTimeZo ne(sa.Sche duledStart .Value, ti meZone, ou t timeZone sString, o ut convert Success);
  651                         Logger.Wri teDebugMes sage("Time  converted  to " + ti meZonesStr ing);
  652                         fullDate =  convertSu ccess ? ti meConversi on.ToStrin g("dddd dd  MMMM yyyy  HH:mm") +  " " + tim eZonesStri ng : timeC onversion. ToString(" dddd dd MM MM yyyy HH :mm") + "  GMT";
  653  
  654                         //Creating  the Subje ct text
  655                         var subjec t = "Your  VA Video V isit has b een ";
  656                         subject +=  (isCancel led) ? "ca nceled" :  "scheduled ";
  657                         subject +=  " for " +  fullDate. Trim();
  658                         Logger.Wri teDebugMes sage("Loca l Time: "  + fullDate );
  659  
  660                         //Getting  the Subjec t Specialt y, Special ty Sub Typ e
  661                         var tsa =  (mcs_servi ces)Organi zationServ ice.Retrie ve(mcs_ser vices.Enti tyLogicalN ame, sa.mc s_relatedt sa.Id, new  ColumnSet (true));
  662                         var servic eText = (t sa.cvt_ser vicetype ! = null) ?  "<b>Specia lty:</b> "  + tsa.cvt _servicety pe.Name +  "<br />" :  "";
  663                         serviceTex t += (tsa. cvt_servic esubtype ! = null) ?  "<b>Specia lty Sub Ty pe:</b> "  + tsa.cvt_ servicesub type.Name  + "<br />"  : "";
  664  
  665  
  666                         var clinic ians = str ing.Empty;
  667                         foreach (S ystemUser  user in pr ovs)
  668                         {
  669                             if (!s tring.IsNu llOrEmpty( clinicians ))
  670                                 cl inicians + = "; ";
  671                             clinic ians += us er.FullNam e;
  672                         }
  673                         if (provs. Count == 1 )
  674                             clinic ians = "<b >Clinician :</b> " +  clinicians  + "<br /> ";
  675                         else if (p rovs.Count  > 1)
  676                             clinic ians = "<b >Clinician s:</b> " +  clinician s + "<br / >";
  677  
  678                         //if you c an't find  "Please Co ntact Your " that mea ns a real  url was en tered, so  use it as  a hyperlin k, otherwi se, displa y the "Ple ase Contac t Your..."  message a s it comes  across
  679                         var meetin gSpace = P atientVirt ualMeeting Space.Inde xOf("Pleas e Contact  Your") ==  -1 ?
  680                             CvtHel per.buildH TMLUrl(Pat ientVirtua lMeetingSp ace, "Clic k Here to  Join the V irtual Med ical Room" )
  681                             : "<b> Your virtu al meeting  room was  not found,  " + Patie ntVirtualM eetingSpac e + "</b>" ;
  682  
  683                         var dynami cBody = is CVTTablet  ? "Your pr ovider wil l call you r CVT tabl et for the  appointme nt." : "Pl ease click  the follo wing link  to access  the virtua l medical  room.  Thi s will tak e you into  the virtu al waiting  room unti l your pro vider join s.<br />";
  684  
  685                         //Set up d ifference  in Schedul ed vs Canc elation te xt
  686                         var descrS tatus = "r eminder of  your";
  687                         var attach mentText =  "<br /><b r />A cale ndar appoi ntment is  attached t o this ema il; you ca n open the  attachmen t and save  it to you r calendar .";
  688                         var deskto pLink = "h ttps://vao ts.blackbo ard.com/bb cswebdav/i nstitution /CVT/TSS/v mr-pat-des ktop/index .htm";
  689                         var iosLin k = "https ://vaots.b lackboard. com/bbcswe bdav/insti tution/CVT /TSS/vmr-p at-ios/ind ex.htm";
  690                         var traini ngLink = " <br /><br  />For info rmation on  how to us e VMRs fro m Desktop  and Androi d tablet d evices, pl ease <a hr ef=" + des ktopLink+  ">Click He re</a>" +
  691                             "<br / >For infor mation on  how to use  VMRs from  iOS/Apple  devices ( e.g. iPad,  iPhone, e tc.), plea se <a href =" + iosLi nk + ">Cli ck Here</a >";
  692  
  693                         if (isCanc elled) //C anceled
  694                         {
  695                             descrS tatus = "c ancelation  notice fo r your pre viously sc heduled";
  696                             attach mentText =  "<br /><b r />A cale ndar appoi ntment can celation i s attached  to this e mail, you  can open t he attachm ent and cl ick \"Remo ve from Ca lendar\" t o remove t his event  from your  calendar." ;
  697                             dynami cBody = "" ;
  698                             meetin gSpace = " ";
  699                             traini ngLink = " ";
  700                         }
  701  
  702                         var descri ption = St ring.Forma t(
  703                             "This  is a {0} V ideo Visit  with a VA  clinician  on <b>{1} </b>. {2}{ 3}<br /><b r />{4}<br  /><br />{ 5}{6}<br / >If you ha ve any que stions or  concerns,  please con tact your  clinic. <b r />{7}{8} {9}",
  704                             descrS tatus,
  705                             fullDa te,
  706                             dynami cBody,
  707                             (!isCV TTablet ?  meetingSpa ce : ""),
  708                             Patien tSafetyChe cks() + "< br />",
  709                             servic eText,
  710                             clinic ians,
  711                             attach mentText,
  712                             traini ngLink,
  713                             "<br / ><br />" +  CvtHelper .EmailFoot er());
  714                         Email pati entEmail =  new Email ()
  715                         {
  716                             Subjec t = subjec t,
  717                             Descri ption = de scription,
  718                             mcs_Re latedServi ceActivity  = new Ent ityReferen ce(Service Appointmen t.EntityLo gicalName,  sa.Id),
  719                             Regard ingObjectI d = new En tityRefere nce(Contac t.EntityLo gicalName,  patientAP .PartyId.I d),
  720                             From =  CvtHelper .GetWorkfl owOwner("S ervice Act ivity Noti fication",  Organizat ionService )
  721                         };
  722                         patientEma il.To = Cv tHelper.Se tPartyList (recipient );
  723  
  724                         Organizati onService. Create(pat ientEmail) ;
  725                         Logger.Wri teDebugMes sage("Pati ent Email  Created Su ccessfully ");
  726                    }
  727                }
  728                else
  729                    Logg er.WriteTo File("No V MR informa tion could  be found" );
  730           }
  731  
  732           pu blic DateT ime Conver tTimeZone( DateTime d ate, int C RMTimeZone Code, out  string tim eZonesStri ng, out bo ol success )
  733           {
  734                success  = false;
  735                timeZone sString =  string.Emp ty;
  736                try
  737                {
  738                    Logg er.WriteDe bugMessage ("Converti ng Time to  Appropria te Time Zo ne");
  739                    usin g (var srv  = new Xrm (Organizat ionService ))
  740                    {
  741                         var timeZo nerecord =  srv.TimeZ oneDefinit ionSet.Fir stOrDefaul t(t => t.T imeZoneCod e != null  && t.TimeZ oneCode.Va lue == CRM TimeZoneCo de);
  742                         timeZonesS tring = ti meZonereco rd.Standar dName;
  743                    }
  744                    var  timeZoneCo de = TimeZ oneInfo.Fi ndSystemTi meZoneById (timeZones String);
  745                    var  localTime  = TimeZone Info.Conve rtTimeFrom Utc(date,  timeZoneCo de);
  746                    succ ess = true ;
  747                    retu rn localTi me;
  748                }
  749                catch (T imeZoneNot FoundExcep tion ex)
  750                {
  751                    Logg er.WriteTo File("Coul d not find  " + timeZ onesString  + " time  zone with  code " + C RMTimeZone Code.ToStr ing() + ":  " + ex.Me ssage + "  ; using UT C instead" );
  752                }
  753                catch (E xception e x)
  754                {
  755                    Logg er.WriteTo File("Time  Zone conv ersion iss ue" + ex.M essage + "  ; using U TC instead ");
  756                }
  757                return d ate;
  758           }
  759  
  760           // / <summary >
  761           // / This met hod create s the .ics  attachmen t and appe nds it to  the email
  762           // / </summar y>
  763           // / <param n ame="email ">This is  the email  that the a ttachment  is attachi ng to</par am>
  764           // / <param n ame="sa">T he service  appointme nt which < /param>
  765           // / <param n ame="statu sCode">The  status of  the email  - which s ets the st atus of th e attachme nt as well  as the su bject of t he email</ param>
  766           in ternal voi d CreateCa lendarAppo intmentAtt achment(Em ail email,  ServiceAp pointment  sa, int st atusCode,  string ste thIP)
  767           {
  768                bool gro up = false ;
  769                if (sa.m cs_groupap pointment  != null)
  770                {
  771                    grou p = sa.mcs _groupappo intment.Va lue;
  772                }
  773                Logger.W riteTxnTim ingMessage ("Begin Cr eating Cal endar Appo intment");
  774                string s chLocation  = "See De scription" ;
  775                string s chSubject  = group ==  true ? "T elehealth  Visit-Grou p Appointm ent: Do No t Reply" :  
  776                    "Tel ehealth Vi sit-Single  Appointme nt: Do Not  Reply";
  777                string s chDescript ion = emai l.Descript ion;
  778                System.D ateTime sc hBeginDate  = (System .DateTime) sa.Schedul edStart;
  779                System.D ateTime sc hEndDate =  (System.D ateTime)sa .Scheduled End;
  780                string s equence =  "";
  781                string s tatus = "C ONFIRMED";
  782                string m ethod = "" ;
  783                //if the  appointme nt is canc eled, send  a cancell ation noti ce based o n the UID  of the pre vious entr y sent
  784                if (stat usCode ==  9 || statu sCode == 9 17290000)
  785                {
  786                    meth od = "METH OD:CANCEL\ n";
  787                    sequ ence = "SE QUENCE:1\n ";
  788                    stat us = "CANC ELLED";
  789                    schS ubject = " Canceled:  Telehealth  Visit: Do  Not Reply ";
  790                }
  791  
  792                //attach  a ClearSt eth CVL fi le if a st eth is in  the compon ents
  793                string c vlAtttachm ent = stri ng.IsNullO rEmpty(ste thIP) ? ""  :
  794                    "ATT ACH;ENCODI NG=BASE64; VALUE=BINA RY;X-FILEN AME=invita tion.cvl:"  + Convert .ToBase64S tring(new  ASCIIEncod ing().GetB ytes("<?xm l version= \"1.0\" en coding=\"U TF-8\"?><C VL><IP>" +  stethIP +  "</IP ><P ort>9005</ Port><Conf erenceId>1 2345</Conf erenceId>< /CVL>")) +  "\n";
  795    
  796                string a tt =  "BEG IN:VCALEND AR\n"+
  797                                    "PRODID:-/ /VA//Veter ans Affair s//EN\n"+
  798                                    method +
  799                                    "BEGIN:VEV ENT\n"+
  800                                    cvlAtttach ment +
  801                                    "UID:" + s a.Id + "\n " + sequen ce + 
  802                                    "DTSTART:"  + schBegi nDate.ToUn iversalTim e().ToStri ng("yyyyMM dd\\THHmms s\\Z")+"\n "+
  803                                    "DTEND:" +  schEndDat e.ToUniver salTime(). ToString(" yyyyMMdd\\ THHmmss\\Z ")+"\n"+
  804                                    "LOCATION: " + schLoc ation +
  805                                    //Use Desc ription ta g for emai l clients  that cant  handle x-a lt-desc ta g with HTM L
  806                                    "\nDESCRIP TION;ENCOD ING=QUOTED -PRINTABLE :" + schDe scription. Replace("< br/>", "") .Replace(" <b>", ""). Replace("< /b>", ""). Replace("< u>", "").R eplace("</ u>", "") +
  807                                    "\nSUMMARY :" + schSu bject + "\ nPRIORITY: 3\n" +
  808                                    "STATUS:"  + status +  "\n" +
  809                                    //Include  alternate  descriptio n if the c alendar cl ient can h andle html  x-alt-des c tag
  810                                    "X-ALT-DES C;FMTTYPE= text/html: <html>"+ s chDescript ion.Replac e("\n","<b r/>") +"</ html>" + " \n" +
  811                               "END :VEVENT\n"  + "END:VC ALENDAR\n" ;
  812  
  813                Activity MimeAttach ment calen darAttachm ent = new  ActivityMi meAttachme nt()
  814                {
  815                    Obje ctId = new  EntityRef erence(Ema il.EntityL ogicalName , email.Id ),
  816                    Obje ctTypeCode  = Email.E ntityLogic alName,
  817                    Subj ect = stri ng.Format( "Telehealt h Visit"),
  818                    Body  = Convert .ToBase64S tring(
  819                             new AS CIIEncodin g().GetByt es(att)),
  820                    File Name = str ing.Format (CultureIn fo.Current Culture, " Telehealth -Appointme nt.ics")
  821                 };
  822                Organiza tionServic e.Create(c alendarAtt achment);
  823                Logger.W riteTxnTim ingMessage ("Finished  Creating  Calendar A ppointment ");
  824                return;
  825           }
  826  
  827           in ternal str ing format Notificati onEmailBod y(List<mcs _resource>  providerT echs, List <mcs_resou rce> patie ntTechs, L ist<mcs_re source> pr oviderRoom s,
  828                List<mcs _resource>  patientRo oms, List< SystemUser > telepres enters, Se rviceAppoi ntment sa,  mcs_servi ces tsa, L ist<System User> prov iders, out  string co nvertedDat e)
  829           {
  830                Logger.W riteDebugM essage("St arting For matting Em ail Body") ;
  831                converte dDate = st ring.Empty ;
  832                string e mailBody =  "";
  833                string p roviderTec hsString =  "";
  834                string p atientTech sString =  null;
  835                string p roviderRoo msString =  null;
  836                string p atientRoom sString =  null;
  837                string t elepresent ersString  = null;
  838                string p rovidersSt ring = nul l;
  839                string D EALicensed  = "";
  840  
  841                //DEA Li censed
  842                DEALicen sed = (sa. cvt_Type.V alue == tr ue) ? "Thi s is a Hom e/Mobile v isit; cons ider Ryan  Haight reg ulations p rior to pr escribing  any contro lled medic ations." :  "";
  843  
  844                foreach  (mcs_resou rce r in p roviderTec hs)
  845                {
  846                    prov iderTechsS tring += r .mcs_name;
  847                    if ( r.cvt_rela teduser !=  null)
  848                    {
  849                         SystemUser  poc = (Sy stemUser)O rganizatio nService.R etrieve(Sy stemUser.E ntityLogic alName, r. cvt_relate duser.Id,  new Column Set("fulln ame", "mob ilephone",  "cvt_offi cephone",  "cvt_telew orkphone") );
  850                         providerTe chsString  += "; POC  Name: " +  poc.FullNa me + "; ";
  851                         var phone  = poc.Mobi lePhone ==  null ? po c.cvt_offi cephone :  poc.Mobile Phone;
  852  
  853                         //If TSA i s telework  (true), t hen add th at number  here as we ll.
  854                         providerTe chsString  += ((tsa.c vt_Provide rLocationT ype != nul l) && (tsa .cvt_Provi derLocatio nType.Valu e == true)  && (poc.c vt_Telewor kPhone !=  null)) ? " POC Telewo rk Phone # : " + poc. cvt_Telewo rkPhone +  ";" : "";
  855                         providerTe chsString  += (phone  != null) ?  "POC Phon e #: " + p hone : "";                 
  856                    }
  857                    prov iderTechsS tring += " <br/>";
  858                    prov iderTechsS tring += g etComponen ts(r, sa);
  859                }
  860  
  861                foreach  (mcs_resou rce r in p atientTech s)
  862                {
  863                    pati entTechsSt ring += r. mcs_name;
  864                    if ( r.cvt_rela teduser !=  null)
  865                    {
  866                         SystemUser  poc = (Sy stemUser)O rganizatio nService.R etrieve(
  867                             System User.Entit yLogicalNa me, r.cvt_ relateduse r.Id, new  ColumnSet( "fullname" , "mobilep hone", "cv t_officeph one"));
  868                         patientTec hsString + = "; POC N ame: " + p oc.FullNam e + "; ";
  869                         var phone  = poc.Mobi lePhone ==  null ? po c.cvt_offi cephone :  poc.Mobile Phone;
  870                         patientTec hsString + = "POC Pho ne #: " +  phone;
  871                    }
  872                    pati entTechsSt ring += "< br/>";
  873                    pati entTechsSt ring += ge tComponent s(r, sa);
  874                }
  875  
  876                foreach  (mcs_resou rce r in p roviderRoo ms)
  877                {
  878                    prov iderRoomsS tring += " <b><u>Room :</u></b>  " + r.mcs_ name;
  879                    if ( r.cvt_phon e != null)
  880                         ProRoom +=  (ProRoom  == null) ?  r.cvt_pho ne : ", "  + r.cvt_ph one;
  881                             
  882                    prov iderRoomsS tring += " <br/>";
  883                }
  884  
  885                foreach  (mcs_resou rce r in p atientRoom s)
  886                {
  887                    pati entRoomsSt ring += "< b><u>Room: </u></b> "  + r.mcs_n ame;
  888                    if ( r.cvt_phon e != null)
  889                    {
  890                         PatRoom +=  (PatRoom  == null) ?  r.cvt_pho ne : ", "  + r.cvt_ph one;
  891                    }
  892                    if ( DEALicense d == "" &&  r.mcs_Rel atedSiteId  != null)  {                      
  893                         var resour ceSite = ( mcs_site)O rganizatio nService.R etrieve(mc s_site.Ent ityLogical Name, r.mc s_RelatedS iteId.Id,  new Column Set(true)) ;
  894  
  895                         if (resour ceSite.cvt _DEALicens ed != null  && resour ceSite.cvt _DEALicens ed.Value = = true)
  896                             patien tRoomsStri ng += ";   <u><b>Note : The pati ent care s ite is DEA  registere d.</u></b> ";
  897                         else
  898                             patien tRoomsStri ng += ";   <u><b>Note : The pati ent care s ite is NOT  DEA regis tered.</u> </b>";
  899                    }
  900                    pati entRoomsSt ring += "< br/>";
  901                }
  902  
  903                foreach  (SystemUse r t in tel epresenter s)
  904                {
  905                    var  phone = t. cvt_office phone != n ull ? t.cv t_officeph one : t.Mo bilePhone;
  906                    tele presenters String +=  "<b><u>Tel epresenter :</u></b>  " + t.Full Name + ":  " + phone  + "<br/>";
  907                }
  908                foreach  (SystemUse r t in pro viders)
  909                {
  910                    var  phone = t. cvt_office phone != n ull ? t.cv t_officeph one : t.Mo bilePhone;
  911                    prov idersStrin g += "<b>< u>Provider :</u></b>  " + t.Full Name;
  912                    prov idersStrin g += (phon e != null)  ? "; Phon e: " + pho ne : "";
  913                    
  914                    //If  TSA is te lework (tr ue), then  add that n umber here  as well.
  915                    if ( (tsa.cvt_P roviderLoc ationType  != null) & & (tsa.cvt _ProviderL ocationTyp e.Value ==  true))
  916                    {
  917                         //Check us er for tel ework numb er                   
  918                         providersS tring += ( t.cvt_Tele workPhone  != null) ?  "; Telewo rk Phone:  " + t.cvt_ TeleworkPh one + ";"  : "";
  919                        
  920                    }
  921                    prov idersStrin g += "<br/ >";
  922                }
  923  
  924               
  925  
  926                Logger.W riteDebugM essage("Ge tting Time  Zone to c onvert Str ing");
  927                var proS iteId = sa .mcs_relat edprovider site;
  928                int proS iteTimeZon e = 35;
  929                if (proS iteId != n ull)
  930                {
  931                    usin g (var srv  = new Xrm (Organizat ionService ))
  932                    {
  933                         var site =  srv.mcs_s iteSet.Fir stOrDefaul t(s => s.I d == proSi teId.Id);
  934                         if (site ! = null)
  935                             proSit eTimeZone  = site.mcs _TimeZone  != null ?  site.mcs_T imeZone.Va lue : proS iteTimeZon e;
  936                    }
  937                }
  938                var conv ersionSucc ess = fals e;
  939                var time ZoneString  = string. Empty; //t his will b e retrieve d in Conve rtTimeZone
  940                var conv ertedTime  = ConvertT imeZone(sa .Scheduled Start.Valu e, proSite TimeZone,  out timeZo neString,  out conver sionSucces s);
  941                var full Date = con versionSuc cess ? con vertedTime .ToString( "dddd dd M MMM yyyy H H:mm") + "  " + timeZ oneString  : converte dTime.ToSt ring("dddd  dd MMMM y yyy HH:mm" ) + " GMT" ;
  942                converte dDate = fu llDate;
  943                Logger.W riteDebugM essage(str ing.Format ("Converte d Time Zon e to {0}",  timeZoneS tring));
  944  
  945                if (sa.S tatusCode. Value == 9  || sa.Sta tusCode.Va lue == 917 290000)
  946                {
  947                    emai lBody += " This is an  automated  Message t o notify y ou that a  Telehealth  Appointme nt previou sly schedu led for "  + fullDate  +
  948                    "has  been <fon t color='r ed'><u>Can celed</u>< /font>.  P lease open  the attac hment and  click \"Re move from  Calendar\"  to remove  this even t from you r calendar .  " +
  949                    "The  details a re listed  below: <br /><br/>";
  950                }
  951                else if  (sa.Status Code.Value  == 4)
  952                {
  953                    emai lBody += " This is an  automated  Message t o notify y ou that a  Telehealth  Appointme nt has bee n <font co lor='green '><u>Sched uled</u></ font> " +
  954                         "for " + f ullDate +  ".  " + 
  955                         "Please op en the att achment an d click \" Save and C lose\" to  add this e vent to yo ur calenda r.  " +
  956                         "The detai ls are lis ted below:  <br/><br/ >";
  957                }
  958  
  959                //Provid er Info
  960                emailBod y += "<br/ ><font siz e='5' colo r='blue'>P rovider Si te Informa tion:</fon t><br/>";
  961                emailBod y += provi derRoomsSt ring;
  962                emailBod y += (tsa. cvt_provsi tevistacli nics != nu ll) ? "<b> <u>Vista C linic:</u> </b> " + t sa.cvt_pro vsitevista clinics.To String() :  ""; //Nee ds to be s pecific Pr ov VC, not  all
  963                emailBod y += (!Str ing.IsNull OrEmpty(pr oviderTech sString))  ? "<br/><b ><u>Techno logies: </ u></b><br/ > " + prov iderTechsS tring + "< br/>" : "" ;
  964                emailBod y += provi dersString ;
  965                emailBod y += (TSAP rovEmergen cy != "")  ? "<u><b>P rovider Si te Emergen cy Respons ibilities: </u></b><b r/> " + TS AProvEmerg ency + "<b r/>" : "";
  966  
  967                if ((Pro Room != nu ll) || (Pr oTCTPhone  != null &&  ProTCTNam e != null) )
  968                {
  969                    emai lBody += " <u><b>Tele phone Cont act Inform ation:</u> </b><br/>  <ul>";
  970                    emai lBody += ( ProRoom !=  null) ? " <li>To dir ect dial t he room: "  + ProRoom  + "</li>"  : "";
  971                    emai lBody += ( ProTCTPhon e != null  && ProTCTN ame != nul l) ? "<li> To contact  the TCT a t the prov ider site,  call " +  ProTCTName  + " at "  + ProTCTPh one + ".</ li><br/><b r/>" : "";
  972                    emai lBody += " </ul>";
  973                }
  974  
  975                //Patien t Info
  976                if (tsa. cvt_Type ! = true)
  977                {
  978                    emai lBody += " <br/><font  size='5'  color='blu e'>Patient  Site Info rmation:</ font><br/> ";
  979                    emai lBody += p atientRoom sString;
  980                    emai lBody += ( tsa.cvt_pa tsitevista clinics !=  null) ? " <b><u>Vist a Clinic:< /u></b> "  + tsa.cvt_ patsitevis taclinics. ToString()  + "<br/>"  : "";
  981                    emai lBody += ( !String.Is NullOrEmpt y(patientT echsString )) ? "<b>< u>Technolo gies: </u> </b><br/>"  + patient TechsStrin g + "<br/> " : "";
  982                    emai lBody += t elepresent ersString;
  983                    emai lBody += ( TSAPatEmer gency != " ") ? "<b>< u>Patient  Site Emerg ency Respo nsibilitie s:</u></b> <br/> " +  TSAPatEmer gency + "< br/>" : "" ;
  984                    
  985                    if ( (PatRoom ! = null) ||  (SiteMain Phone != n ull) || (S iteLocal91 1Phone !=  null) || ( PatTCTPhon e != null  && PatTCTN ame != nul l))
  986                    {
  987                         emailBody  += "<u><b> Telephone  Contact In formation: </u></b><b r/> <ul>";
  988                         emailBody  += (PatRoo m != null)  ? "<li>To  direct di al the roo m: " + Pat Room + "</ li>" : "";
  989                         emailBody  += (SiteMa inPhone !=  null) ? " <li>To rea ch the mai n phone nu mber for t he patient  side clin ic: " + Si teMainPhon e + "</li> " : "";
  990                         emailBody  += (SiteLo cal911Phon e != null)  ? "<li>If  you are o ut of area , this is  the number  to reach  emergency  services:  " + SiteLo cal911Phon e + "</li> " : "";
  991                         emailBody  += (PatTCT Phone != n ull && Pat TCTName !=  null) ? " <li>To con tact the T CT at the  patient si te, call "  + PatTCTN ame + " at  " + PatTC TPhone + " .</li>" :  "";
  992                         emailBody  += "</ul>" ;
  993                    }
  994                }
  995                else  // Condition  for CVT to  Home
  996                {
  997                    bool ? patient  = null;
  998                    var  meetingSpa ce = getPa tientVirtu alMeetingS pace(sa, o ut patient );
  999  
  1000                    emai lBody += " <br/><br/> <font size ='5' color ='blue'>Ho me/Mobile  Informatio n:</font>< br/>";
  1001                    emai lBody += ( DEALicense d != "") ?  "<u><b>Si te DEA Lic ensed:</u> </b><br/>  " + DEALic ensed + "< br/>" : "" ;
  1002                    emai lBody += ( patient ==  false) ?  "<br/> Pat ient CVT T ablet: <br />" : "<br /> Virtual  Meeting S pace: <br/ >";
  1003  
  1004                    if ( meetingSpa ce == stri ng.Empty)
  1005                         meetingSpa ce = "Plea se Contact  Your Clin ician for  Web Meetin g Details" ;
  1006  
  1007                    //Ch ange to re ad the Pro viderVirtu alMeetingS pace on th e patient  record.
  1008                    // h ttps://pex ipdemo.com /px/vatest /#/?name=P roviderNam e&join=1&m edia=&esca late=1&con ference=va test@pexip demo.com&p in=1234  
  1009                    if ( patient ==  true || P roviderVir tualMeetin gSpace !=  string.Emp ty)
  1010                    {
  1011                         emailBody  += "From y our Web br owser: " +  CvtHelper .buildHTML Url(Provid erVirtualM eetingSpac e, "Click  Here to Jo in Virtual  Medical R oom") + "< br/>";
  1012  
  1013                         var conf =  getParamV alue(Provi derVirtual MeetingSpa ce, "confe rence=");
  1014                         var cid =  getParamVa lue(Provid erVirtualM eetingSpac e, "pin=") ;
  1015  
  1016                         if (!strin g.IsNullOr Empty(conf ) && !stri ng.IsNullO rEmpty(cid ) )
  1017                             emailB ody += Str ing.Format ("<br/>And  if you wa nted to di al from yo ur VTC dev ice:<br/>< br/>From a ny VTC dev ice: {0}<b r/>Host CI D: {1}", c onf, cid);
  1018                    }
  1019                    else
  1020                         emailBody  += meeting Space + "< br/>";
  1021  
  1022                    emai lBody += " <br />" +  ProviderSa fetyChecks ();
  1023                }
  1024                emailBod y += CvtHe lper.Email Footer();
  1025  
  1026                Logger.W riteDebugM essage("Fi nishing Fo rmatting E mail Body" );
  1027                return e mailBody;
  1028           }
  1029  
  1030           in ternal str ing Provid erSafetyCh ecks()
  1031           {
  1032                var safe tyChecks =  "During y our initia l assessme nt be sure  to verify  the follo wing: ";
  1033                safetyCh ecks += "< ul><li>Do  you have a ny concern s about su icide?</li >";
  1034                safetyCh ecks += "< li>The Pat ient verba lly consen ts to the  telehealth  visit?</l i>";
  1035                safetyCh ecks += "< li>If the  line drops , what num ber can I  call you a t?</li>";
  1036                safetyCh ecks += "< li>What is  the name,  phone num ber, and r elationshi p of the p erson we s hould cont act in the  case of a n emergenc y?</li>";
  1037                safetyCh ecks += "< li>What is  your loca l 10 digit  phone num ber for la w enforcem ent in you r communit y?</li>";
  1038                safetyCh ecks += "< li>What is  the addre ss of your  location  during thi s visit?</ li></ul>";
  1039                safetyCh ecks += "< li>Are you  in a safe  and priva te place?< /li></ul>" ;
  1040                return s afetyCheck s;
  1041           }
  1042  
  1043           in ternal str ing Patien tSafetyChe cks()
  1044           {
  1045                var safe tyChecks =  "Prior to  your visi t, ensure  the place  you will b e in is pr ivate and  safe, and  have the f ollowing i nformation  available :";
  1046                safetyCh ecks += "< ul><li>At  what phone  number sh ould we co ntact you  if the cal l drops?</ li>";
  1047                safetyCh ecks += "< li>What is  your loca l 10 digit  phone num ber for la w enforcem ent in you r communit y?</li>";
  1048                safetyCh ecks += "< li>What is  the name,  phone num ber, and r elationshi p of the p erson we s hould cont act in the  case of a n emergenc y?</li>";
  1049                safetyCh ecks += "< li>What is  the addre ss of your  location  during thi s visit?</ li></ul>";
  1050                return s afetyCheck s;
  1051           }
  1052  
  1053           in ternal str ing getPar amValue(st ring url,  string key )
  1054           {
  1055                var resu lt = strin g.Empty;
  1056                var para meter = ur l.Split('& ').LastOrD efault(s = > s.ToLowe r().Contai ns(key));
  1057                var para meterKeyVa lue = para meter != n ull ? para meter.Spli t('=') : n ull;
  1058                if (para meterKeyVa lue != nul l && param eterKeyVal ue.Count()  == 2)
  1059                    resu lt = param eterKeyVal ue[1];
  1060                return r esult;
  1061           }
  1062  
  1063           in ternal str ing getCom ponents(mc s_resource  technolog y, Service Appointmen t SA)
  1064           {
  1065                //Get al l the comp onents and  include t he CEVN Al ias and IP  Addresses  for each.   Return t he formatt ed string  with a lin e for each  Component
  1066                //virtua lMeetingSp ace = null ;
  1067                string c omponents  = null; 
  1068                using (v ar context  = new Xrm (Organizat ionService ))
  1069                {
  1070                    var  compList =  context.c vt_compone ntSet.Wher e(c => c.c vt_related resourceid .Id == tec hnology.Id );
  1071                    fore ach (cvt_c omponent c  in compLi st)
  1072                    {
  1073                         if (compon ents == nu ll)
  1074                             compon ents += "< ul>";
  1075                         components  += "<li>"  + c.cvt_n ame;
  1076                         switch (c. cvt_name)
  1077                         {
  1078                             case " Codec, Har dware":
  1079                                 if  (c.cvt_ce vnalias !=  null)
  1080                                      componen ts += "; C EVN Alias:  " + c.cvt _cevnalias ;
  1081                                 br eak;
  1082                             case " Telemedici ne Encount er Managem ent":
  1083                             case " Telemed En counter Ma nagement":
  1084                             case " TEMS (Tele medicine E ncounter M anagement  Software)" :
  1085                             case " TEMS (Tele med Encoun ter Manage ment Softw are)":
  1086                                 if  (c.cvt_ip address !=  null)
  1087                                      componen ts += "; I P Address:  " + CvtHe lper.build HTMLUrl(c. cvt_ipaddr ess);
  1088                                 br eak;
  1089                             case " CVT Patien t Tablet":
  1090                                 if  (c.cvt_se rialnumber  != null)
  1091                                      componen ts += "; S erial Numb er: " + c. cvt_serial number;
  1092                                 br eak;
  1093                             case " Virtual Me eting Spac e":
  1094                                 Vi rtualMeeti ngSpace =  c;
  1095                                 br eak;
  1096                             case " Digital St ethoscope  Peripheral ":
  1097                                 st ethIP = c. cvt_ipaddr ess;
  1098                                 br eak;
  1099                         }
  1100                         //Send URL
  1101                         var url =  "";
  1102                         var contac t = getDum myContact( );
  1103                         var second aryEntitie s = new Li st<Entity> ();
  1104                         secondaryE ntities.Ad d(SA);
  1105                         secondaryE ntities.Ad d(contact) ;
  1106                         if (UrlBui lder.TryGe tUrl(Organ izationSer vice, this .GetType() .ToString( ), c, seco ndaryEntit ies, out u rl))
  1107                             compon ents += ";  <a href="  + url + " >" + url +  "</a>";
  1108                         components  += "</li> ";                      
  1109                    }
  1110                    if ( components  != null)
  1111                         components  += "</ul> ";
  1112                }
  1113                return c omponents;         
  1114           }
  1115  
  1116           in ternal Con tact getDu mmyContact ()
  1117           {
  1118                Contact  c = new Co ntact();
  1119                using (v ar srv = n ew Xrm(Org anizationS ervice)){
  1120                    c =  srv.Contac tSet.First OrDefault( );
  1121                }
  1122                return c ;
  1123           }
  1124  
  1125           in ternal Lis t<Entity>  getPRGs(Gu id tsaId,  string loc ation)
  1126           {
  1127                QueryByA ttribute q a = new Qu eryByAttri bute("cvt_ "+location +"resource group");
  1128                qa.Colum nSet = new  ColumnSet ("cvt_tsar esourcetyp e", "cvt_r elateduser id", "cvt_ relatedres ourcegroup id", "cvt_ relatedres ourceid");
  1129                qa.AddAt tributeVal ue("cvt_re latedtsaid ", tsaId);
  1130                var resu lts = Orga nizationSe rvice.Retr ieveMultip le(qa);
  1131                return r esults.Ent ities.ToLi st();
  1132           }
  1133  
  1134           // if patient OrProvider  == 1, the n get prov ider resou rces, othe rwise get  patient re sources
  1135           in ternal Ent ityCollect ion getPRG s(mcs_serv ices tsa,  int? patie ntOrProvid er)
  1136           {
  1137                EntityCo llection P RGCollecti on = new E ntityColle ction();
  1138                using (v ar context  = new Xrm (Organizat ionService )){
  1139                    if ( patientOrP rovider ==  1)
  1140                    {
  1141                         var ProvRG s = contex t.cvt_prov iderresour cegroupSet .Where(prg  => prg.cv t_RelatedT SAid.Id ==  tsa.Id);
  1142                         foreach (v ar res in  ProvRGs)
  1143                             PRGCol lection.En tities.Add (res);
  1144                    }
  1145                    else
  1146                    {
  1147                         var PatRGs  = context .cvt_patie ntresource groupSet.W here(prg = > prg.cvt_ RelatedTSA id.Id == t sa.Id);
  1148                         foreach (v ar res in  PatRGs)
  1149                             PRGCol lection.En tities.Add (res);
  1150                    }
  1151                }
  1152                return P RGCollecti on;
  1153           }
  1154  
  1155           // / <summary >
  1156           // / looks to  find a gr oup resour ce record  for the gr oup and us er listed
  1157           // / </summar y>
  1158           // / <param n ame="user" >user Id o f the grou p resource </param>
  1159           // / <param n ame="group ">group id  of the gr oup resour ce</param>
  1160           // / <returns >true if a  record ex ists for t he group p assed in a nd the use r passed i t</returns >
  1161           in ternal boo l MatchRes ourceToGro up(Guid us erId, Guid  groupId)
  1162           {
  1163                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1164                    retu rn srv.mcs _groupreso urceSet.Fi rstOrDefau lt(gr => g r.mcs_rela tedResourc eGroupId.I d == group Id && gr.m cs_Related UserId.Id  == userId)  != null;
  1165           }
  1166  
  1167           // / <summary >
  1168           // / looks to  find a gr oup resour ce record  for the gr oup and re source lis ted
  1169           // / </summar y>
  1170           // / <param n ame="resou rce">resou rce record  of the gr oup resour ce</param>
  1171           // / <param n ame="group ">resource  record of  the group  resource< /param>
  1172           // / <returns >true if a  record ex ists for t he group p assed in a nd the res ource pass ed it</ret urns>
  1173  
  1174           in ternal boo l MatchRes ourceToGro up(mcs_res ource reso urce, mcs_ resourcegr oup group)
  1175           {
  1176                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1177                    retu rn srv.mcs _groupreso urceSet.Fi rstOrDefau lt(gr => g r.mcs_rela tedResourc eGroupId.I d == group .Id && gr. mcs_Relate dResourceI d.Id == re source.Id)  != null;
  1178           }
  1179  
  1180           // / <summary >
  1181           // / returns  the list o f users ba sed on the  location  (provider  or patient ) and 
  1182           // / </summar y>
  1183           // / <param n ame="users ">list of  user activ ity partie s in the S A.Resource s field</p aram>
  1184           // / <param n ame="locat ion">"pati ent" or "p rovider"</ param>
  1185           // / <param n ame="tsaId ">id of th e tsa asso ciated wit h the serv ice activi ty that ge nerated th is email</ param>
  1186           // / <returns ></returns >
  1187           in ternal Lis t<SystemUs er> GetRec ipients(En tityCollec tion users , List<Ent ity> prgs)
  1188           {
  1189                List<Sys temUser> r ecipients  = new List <SystemUse r>();
  1190                var sing les = prgs .Where(p = > p.Attrib utes.Conta ins("cvt_t saresource type") &&  ((OptionSe tValue)p.A ttributes[ "cvt_tsare sourcetype "]).Value  == (int)cv t_tsaresou rcetype.Si ngleProvid er).ToList ();
  1191                var grou ps = prgs. Where(p =>  p.Attribu tes.Contai ns("cvt_ts aresourcet ype") && ( (OptionSet Value)p.At tributes[" cvt_tsares ourcetype" ]).Value = = (int)cvt _tsaresour cetype.Res ourceGroup ).ToList() ;
  1192  
  1193                foreach  (var singl ePRG in si ngles)
  1194                {
  1195                    if ( singlePRG. Attributes .Contains( "cvt_relat eduserid")  && single PRG.Attrib utes["cvt_ relateduse rid"] != n ull)
  1196                    {
  1197                         SystemUser  singleUse r = (Syste mUser)Orga nizationSe rvice.Retr ieve(Syste mUser.Enti tyLogicalN ame,
  1198                             ((Enti tyReferenc e)singlePR G.Attribut es["cvt_re lateduseri d"]).Id, n ew ColumnS et(true));
  1199                         if (single User != nu ll && sing leUser.Id  != Guid.Em pty)
  1200                         {
  1201                             foreac h (Activit yParty u i n users.En tities)
  1202                             {
  1203                                 if  (singleUs er.Id == u .PartyId.I d)
  1204                                 {
  1205                                      recipien ts.Add(sin gleUser);
  1206                                      break;
  1207                                 }
  1208                             }
  1209                         }
  1210                    }
  1211                }
  1212                foreach  (var group PRG in gro ups)
  1213                {
  1214                    if ( groupPRG.A ttributes. Contains(" cvt_relate dresourceg roupid") & & groupPRG .Attribute s["cvt_rel atedresour cegroupid" ] != null)
  1215                    {
  1216                         mcs_resour cegroup gr oup = (mcs _resourceg roup)Organ izationSer vice.Retri eve(
  1217                                 mc s_resource group.Enti tyLogicalN ame, ((Ent ityReferen ce)groupPR G.Attribut es["cvt_re latedresou rcegroupid "]).Id, ne w ColumnSe t(true));
  1218                         //if group  type valu e is any o f the "use r-type" gr oups (prov ider or al l required  or telepr esenter)
  1219                         if ((group .mcs_Type. Value == ( int)mcs_re sourcetype .Provider)  || (group .mcs_Type. Value == ( int)mcs_re sourcetype .AllRequir ed) || 
  1220                             (group .mcs_Type. Value == ( int)mcs_re sourcetype .Teleprese nterImager ))
  1221                         {
  1222                             //if t he user se lected is  in the res ource grou p, return  true and a dd the use r to the e ntitycolle ction
  1223                             foreac h (Activit yParty u i n users.En tities)
  1224                             {
  1225                                 va r user = ( SystemUser )Organizat ionService .Retrieve( SystemUser .EntityLog icalName,  u.PartyId. Id, new Co lumnSet(tr ue));
  1226                                 if  (MatchRes ourceToGro up(user.Id , group.Id ))
  1227                                      recipien ts.Add(use r);
  1228                             }
  1229                         }
  1230                    }
  1231                }
  1232                return r ecipients;
  1233           }
  1234  
  1235           // separates  user types  based on  value pass ed into pa rameter -  if user ty pe = null,  then only  providers , if 0 the n both, if  1 then pa tient
  1236           in ternal Ent ityCollect ion GetRec ipients(En tityCollec tion users , int? use rType, mcs _services  tsa)
  1237           {
  1238                EntityCo llection p roviders =  new Entit yCollectio n();
  1239  
  1240                foreach  (ActivityP arty u in  users.Enti ties)
  1241                {
  1242                    Syst emUser use r = (Syste mUser)Orga nizationSe rvice.Retr ieve(Syste mUser.Enti tyLogicalN ame, u.Par tyId.Id, n ew ColumnS et(true));
  1243  
  1244                    //se arch provi der resour ce group r ecords for  a resourc e of type  single pro vider who  matches th e user fro m the list  of resour ces select ed
  1245                    //ot herwise lo ok for a r esource gr oup that c ontains th e user
  1246                    //if  userType  is null, r eturn prov iders, if  0 - return  both (pat ients adde d below)
  1247                    if ( userType = = null ||  userType = = 0)
  1248                    {
  1249                         //get prov iderResour ceGroups f or the giv en TSA
  1250                         var queryR esult = ge tPRGs(tsa,  1).Entiti es;
  1251  
  1252                         var single Providers  = queryRes ult.Where( p => ((cvt _providerr esourcegro up)p).cvt_ TSAResourc eType.Valu e == 2);
  1253                         var resour ceGroups =  queryResu lt.Where(p  => ((cvt_ providerre sourcegrou p)p).cvt_T SAResource Type.Value  == 0);
  1254                         if (single Providers. Count() >  0)
  1255                         {
  1256                             foreac h (cvt_pro viderresou rcegroup p  in single Providers)
  1257                             {
  1258                                 Sy stemUser s ingleProvi derUser =  (SystemUse r)Organiza tionServic e.Retrieve (SystemUse r.EntityLo gicalName,  p.cvt_Rel atedUserId .Id, new C olumnSet(t rue));
  1259                                 if  (singlePr oviderUser  != null & & singlePr oviderUser .Id == use r.Id)
  1260                                     providers .Entities. Add(user);
  1261                             }
  1262                         }
  1263                         if (resour ceGroups.C ount() > 0 )
  1264                         {
  1265                             //for  each resou rce group,  check if  the type i s provider .  If so,  then retri eve the re source gro up, retrie ve get all  the resou rces liste d, and com pare 
  1266                             //the  list of re sources in  the group  to the re source on  the Servic e Activity
  1267                             foreac h (cvt_pro viderresou rcegroup r g in resou rceGroups)
  1268                             {
  1269                                 mc s_resource group grou p = (mcs_r esourcegro up)Organiz ationServi ce.Retriev e(
  1270                                      mcs_reso urcegroup. EntityLogi calName, r g.cvt_Rela tedResourc eGroupid.I d, new Col umnSet(tru e));
  1271                                 // if group t ype value  is provide r or all r equired
  1272                                 if  ((group.m cs_Type.Va lue == 999 99999) ||  (group.mcs _Type.Valu e == 91729 0000))
  1273                                 {
  1274                                      //if the  user sele cted is in  the resou rce group,  return tr ue and add  the user  to the ent itycollect ion
  1275                                      if (Matc hResourceT oGroup(use r.Id, grou p.Id))
  1276                                          prov iders.Enti ties.Add(u ser);
  1277                                 }
  1278                             }
  1279                         }                
  1280                    }
  1281                    //if  userType  is 1, retu rn patient s only, if  0 - retur n both (pr oviders ad ded above)
  1282                    if ( userType = = 0 || use rType == 1 )
  1283                    {
  1284                         //get pati entresourc egroup rec ords for t he TSA
  1285                         var queryR esult = ge tPRGs(tsa,  0).Entiti es;
  1286                         var single Patients =  queryResu lt.Where(p sr => ((cv t_patientr esourcegro up)psr).cv t_TSAResou rceType.Va lue == 3);
  1287                         var resour ceGroups =  queryResu lt.Where(p sr => ((cv t_patientr esourcegro up)psr).cv t_TSAResou rceType.Va lue == 0);
  1288                         if (single Patients.C ount() > 0 )
  1289                         {
  1290                             foreac h (cvt_pat ientresour cegroup p  in singleP atients)
  1291                             {
  1292                                 Sy stemUser s inglePatie ntUser = ( SystemUser )Organizat ionService .Retrieve(
  1293                                      SystemUs er.EntityL ogicalName , p.cvt_Re latedUserI d.Id, new  ColumnSet( true));
  1294                                 if  (singlePa tientUser  != null &&  singlePat ientUser.I d == user. Id)
  1295                                 pr oviders.En tities.Add (user);
  1296                             }
  1297                         }
  1298                         if (resour ceGroups.C ount() > 0 )
  1299                         {
  1300                             foreac h (cvt_pat ientresour cegroup rg  in resour ceGroups)
  1301                             {
  1302                                 mc s_resource group grou p = (mcs_r esourcegro up)Organiz ationServi ce.Retriev e(
  1303                                      mcs_reso urcegroup. EntityLogi calName, r g.cvt_Rela tedResourc eGroupid.I d, new Col umnSet(tru e));
  1304                                 if  (group.mc s_Type.Val ue == 1000 00000)
  1305                                 {
  1306                                      if (Matc hResourceT oGroup(use r.Id, grou p.Id))
  1307                                          prov iders.Enti ties.Add(u ser);
  1308                                 }
  1309                             }
  1310                         }
  1311                    }
  1312                }
  1313                return p roviders;
  1314           }
  1315  
  1316           // / <summary >
  1317           // / filters  down the l ist of all  equipment  on SA bas ed on crit eria provi ded
  1318           // / </summar y>
  1319           // / <param n ame="equip ment">coll ection of  mcs_resour ces that c orrespond  to the equ ipment in  the resour ces field  on the sa< /param>
  1320           // / <param n ame="tsa"> tsa for th e Service  Activity</ param>
  1321           // / <param n ame="prgs" >cvt_patie ntresource group or c vt_provide rresourceg roup for a ll resourc es on the  tsa</param >
  1322           // / <param n ame="equip Type">type  of mcs_re source (ro om, tech,  vista clin ic, etc.)< /param>
  1323           // / <returns >the list  of mcs_res ources bas ed on the  filters li sted (pro  or pat loc ation and  equipment  type)</ret urns>
  1324           in ternal Lis t<mcs_reso urce> Clas sifyResour ces(Entity Collection  equipment , List<Ent ity> prgs,  int? equi pType)
  1325           {
  1326                List<mcs _resource>  relevantR esources =  new List< mcs_resour ce>();
  1327  
  1328                var sing les = prgs .Where(prg  => ((Opti onSetValue )(prg.Attr ibutes["cv t_tsaresou rcetype"]) ).Value ==  (int)cvt_ tsaresourc etype.Sing leResource ).ToList() ;
  1329                var grou ps = prgs. Where(prg  => ((Optio nSetValue) (prg.Attri butes["cvt _tsaresour cetype"])) .Value ==  (int)cvt_t saresource type.Resou rceGroup). ToList();
  1330  
  1331                foreach  (Entity si nglePRG in  singles)
  1332                {
  1333                    if ( singlePRG. Attributes .Contains( "cvt_relat edresource id") && si nglePRG.At tributes[" cvt_relate dresourcei d"] != nul l)
  1334                    {
  1335                         foreach (m cs_resourc e r in equ ipment.Ent ities)
  1336                         {
  1337                             if (r. mcs_Type.V alue != eq uipType &&  equipType  != null)
  1338                                 co ntinue;
  1339  
  1340                             mcs_re source res ource = (m cs_resourc e)Organiza tionServic e.Retrieve (mcs_resou rce.Entity LogicalNam e,
  1341                                      ((Entity Reference) singlePRG. Attributes ["cvt_rela tedresourc eid"]).Id,  new Colum nSet(true) );
  1342                             if (re source !=  null && re source.Id  == r.Id)
  1343                                 re levantReso urces.Add( r);
  1344                         }
  1345                    }
  1346                }
  1347                foreach  (Entity gr oupPRG in  groups)
  1348                {
  1349                    if ( groupPRG.A ttributes. Contains(" cvt_relate dresourceg roupid") & & groupPRG .Attribute s["cvt_rel atedresour cegroupid" ] != null)
  1350                    {
  1351                         mcs_resour cegroup gr oup = (mcs _resourceg roup)Organ izationSer vice.Retri eve(mcs_re sourcegrou p.EntityLo gicalName,  
  1352                                      ((Entity Reference) groupPRG.A ttributes[ "cvt_relat edresource groupid"]) .Id, new C olumnSet(t rue));
  1353                         if (group. mcs_Type.V alue == (i nt)mcs_res ourcetype. Room || gr oup.mcs_Ty pe.Value = = (int)mcs _resourcet ype.Techno logy || gr oup.mcs_Ty pe.Value = = (int)mcs _resourcet ype.AllReq uired)
  1354                         {
  1355                             foreac h (mcs_res ource r in  equipment .Entities)
  1356                             {
  1357                                 if  (r.mcs_Ty pe.Value ! = equipTyp e && equip Type != nu ll)
  1358                                      continue ;
  1359  
  1360                                 if  (MatchRes ourceToGro up(r, grou p))
  1361                                 {
  1362                                      relevant Resources. Add(r);
  1363                                      break;
  1364                                 }
  1365                             }
  1366                         }
  1367                    }
  1368                }
  1369                
  1370                return r elevantRes ources;
  1371           }
  1372           #e ndregion
  1373  
  1374           #r egion Vist a Reminder  Email
  1375           in ternal voi d SendVist aReminder( Email emai l)
  1376           {
  1377                Logger.W riteDebugM essage("Be ginning Vi sta Remind er");
  1378                var prov TeamMember s = new Li st<TeamMem bership>() ;
  1379                var patT eamMembers  = new Lis t<TeamMemb ership>();
  1380                ServiceA ppointment  sa = (Ser viceAppoin tment)Orga nizationSe rvice.Retr ieve(Servi ceAppointm ent.Entity LogicalNam e, email.m cs_Related ServiceAct ivity.Id,  new Column Set(true)) ;
  1381                var crea tor = sa.C reatedBy;
  1382                //Either  get the P rov/Pat Fa cility fro m TSA or f rom the SA .
  1383                mcs_serv ices tsa =  (mcs_serv ices)Organ izationSer vice.Retri eve(mcs_se rvices.Ent ityLogical Name, sa.m cs_related tsa.Id, ne w ColumnSe t(true));
  1384  
  1385                Logger.W riteDebugM essage("Re trieved Se rvice Acti vity and T SA associa ted with t his Email" );
  1386  
  1387                //if (ts a.cvt_Type  != null & & tsa.cvt_ Type.Value )
  1388                //{
  1389                //    De leteVistaR eminder(em ail, "Home /Mobile em ail does n ot require  a VistA R eminder, d eleting em ail");
  1390                //    re turn;
  1391                //}
  1392  
  1393                var prov FacilityId  = tsa.cvt _ProviderF acility.Id ;
  1394                var patF acilityId  = tsa.cvt_ PatientFac ility != n ull ? tsa. cvt_Patien tFacility. Id : Guid. Empty;
  1395                var intr aFacility  = (provFac ilityId ==  patFacili tyId) ? tr ue : false ;
  1396  
  1397                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1398                {
  1399                    var  provTeam =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == provFa cilityId & & t.cvt_Ty pe != null  && t.cvt_ Type.Value  == 917290 005);
  1400                    if ( provTeam ! = null)
  1401                    prov TeamMember s = srv.Te amMembersh ipSet.Wher e(TM => TM .TeamId ==  provTeam. Id).ToList ();
  1402                    else
  1403                         Logger.Wri teToFile(" The provid er side Sc heduler Te am was una ble to be  found for  Service Ac tivity: "  + sa.Id);
  1404  
  1405                    var  patTeam =  srv.TeamSe t.FirstOrD efault(t = > t.cvt_Fa cility.Id  == patFaci lityId &&  t.cvt_Type  != null & & t.cvt_Ty pe.Value = = 91729000 5);
  1406                    if ( patTeam !=  null)
  1407                    patT eamMembers  = srv.Tea mMembershi pSet.Where (TM => TM. TeamId ==  patTeam.Id ).ToList() ;
  1408                    else
  1409                         Logger.Wri teToFile(" The patien t side Sch eduler Tea m was unab le to be f ound for S ervice Act ivity: " +  sa.Id);
  1410                }
  1411  
  1412                Logger.W riteDebugM essage(str ing.Format ("Retrieve d {0} Pat  Team Membe rs and {1}  Pro Team  Members",  patTeamMem bers.Count , provTeam Members.Co unt));
  1413                bool pro vCheck = f alse;
  1414                bool pat Check = fa lse;
  1415                EntityCo llection p rovMembers  = new Ent ityCollect ion();
  1416                EntityCo llection p atMembers  = new Enti tyCollecti on();
  1417                var subS pecialty =  sa.mcs_se rvicesubty pe != null  ? sa.mcs_ servicesub type.Id :  Guid.Empty ;
  1418  
  1419                if (prov TeamMember s.Count ==  0)
  1420                    Logg er.WriteTo File("Ther e are no m embers of  the Schedu ler team a t " + tsa. cvt_Provid erFacility .Name + ".   Please c ontact the  FTC and e nsure this  is correc ted.");
  1421                else
  1422                {
  1423                    fore ach (TeamM embership  tm in prov TeamMember s)
  1424                    {
  1425                         if (tm.Sys temUserId  != null)
  1426                         {
  1427                             if (Fi lterMember sBySpecial ty(tm.Syst emUserId.V alue, sa.m cs_service type.Id, s ubSpecialt y))
  1428                             {
  1429                                 Ac tivityPart y p = new  ActivityPa rty()
  1430                                 {
  1431                                      PartyId  = new Enti tyReferenc e(SystemUs er.EntityL ogicalName , tm.Syste mUserId.Va lue)
  1432                                 };
  1433                                 pr ovMembers. Entities.A dd(p);
  1434                             }
  1435                             if (cr eator.Id = = tm.Syste mUserId.Va lue)
  1436                                 pr ovCheck =  true;
  1437                         }
  1438                    }
  1439                }
  1440                if (patT eamMembers .Count ==  0 && !tsa. cvt_Type.V alue)
  1441                    Logg er.WriteTo File(strin g.Format(" There are  no members  of the Sc heduler te am at {0}.   Please c ontact the  FTC and e nsure this  is correc ted.", tsa .cvt_Patie ntFacility  != null ?  tsa.cvt_P atientFaci lity.Name  : "\"No Fa cility Lis ted\""));
  1442                else
  1443                {
  1444                    fore ach (TeamM embership  tm in patT eamMembers )
  1445                    {
  1446                         if (tm.Sys temUserId  != null)
  1447                         {
  1448                             if (Fi lterMember sBySpecial ty(tm.Syst emUserId.V alue, sa.m cs_service type.Id, s ubSpecialt y))
  1449                             {
  1450                                 Ac tivityPart y p = new  ActivityPa rty()
  1451                                 {
  1452                                      PartyId  = new Enti tyReferenc e(SystemUs er.EntityL ogicalName , tm.Syste mUserId.Va lue)
  1453                                 };
  1454                                 pa tMembers.E ntities.Ad d(p);
  1455                             }
  1456                             if (cr eator.Id = = tm.Syste mUserId.Va lue)
  1457                                 pa tCheck = t rue;
  1458                         }
  1459                    }
  1460                }
  1461                //If TSA  is Store  Forward an d the sche duler is o n the pati ent Schedu ler team s ide OR if  the schedu ler is on  both Sched uler Teams , then don 't send em ail
  1462                if ((tsa .cvt_Avail ableTelehe althModali ties != nu ll && tsa. cvt_Availa bleTelehea lthModalit ies.Value  == (int)mc s_services cvt_Availa bleTelehea lthModalit ies.Storea ndForward  && patChec k) || (pat Check && p rovCheck))
  1463                {
  1464                    Logg er.WriteDe bugMessage ("No need  to send ou t email, D eleting Em ail.  TSA  is SFT and  Scheduler  is on Pat  Team OR S cheduler i s on Both  Pat and Pr ov Team");
  1465                    try
  1466                    {
  1467                         Organizati onService. Delete(ema il.Logical Name, emai l.Id);
  1468                         Logger.Wri teDebugMes sage("Emai l Deleted" );
  1469                    }
  1470                    catc h (Excepti on ex)
  1471                    {
  1472                         Logger.Wri teToFile(" Unable to  Delete Ema il " + ex. Message +  ".  Leavin g email as  is.");
  1473                    }
  1474                    retu rn;
  1475                }
  1476                else
  1477                {
  1478                    Setu pVistaRemi nderEmail( email, pro vMembers,  patMembers , tsa, pro vCheck, pa tCheck, sa );
  1479                }
  1480           }
  1481  
  1482           in ternal voi d DeleteVi staReminde r(Email em ail, strin g debugMes sage)
  1483           {
  1484                Logger.W riteDebugM essage(deb ugMessage) ;
  1485                try
  1486                {
  1487                    Orga nizationSe rvice.Dele te(email.L ogicalName , email.Id );
  1488                    Logg er.WriteDe bugMessage ("Email De leted");
  1489                }
  1490                catch (E xception e x)
  1491                {
  1492                    Logg er.WriteTo File("Unab le to Dele te Email "  + ex.Mess age + ".   Leaving em ail as is. ");
  1493                }
  1494           }
  1495  
  1496           // / <summary >
  1497           // / returns  false if t he user is  not assoc iated with  the speci alty on SA  (or sub-s pecialty i f listed)
  1498           // / </summar y>
  1499           // / <param n ame="userI d">id of u ser to che ck for spe cialties</ param>
  1500           // / <param n ame="speci alty">spec ialty to c heck</para m>
  1501           // / <param n ame="subSp ecialty">s ub-special ty to chec k</param>
  1502           // / <returns >true if u ser is ass ociated wi th special ty/sub-spe cialty or  false if n ot</return s>
  1503           in ternal boo l FilterMe mbersBySpe cialty(Gui d userId,  Guid speci alty, Guid  subSpecia lty)
  1504           {
  1505                var user Associated WithSpecia lty = fals e;
  1506                var user Associated WithSubSpe cialty = f alse;
  1507                var spec ialties =  new List<m cs_service type>();
  1508                var subS pecialties  = new Lis t<mcs_serv icesubtype >();
  1509                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1510                {
  1511                    var  user = srv .SystemUse rSet.First OrDefault( u => u.Id  == userId) ;
  1512  
  1513                    //Re trieve rel ated recor ds through  N:N assoc iation - C RM doesn't  eager loa d, so have  to call t his.  It r eturns nul l if no it ems are in  the list,  so also n eed to nul l check be fore conve rting to L ist
  1514                    srv. LoadProper ty(user, " cvt_system user_mcs_s ervicetype ");
  1515                    var  specialtyR elated = u ser.cvt_sy stemuser_m cs_service type;
  1516                    if ( specialtyR elated !=  null)
  1517                         specialtie s = specia ltyRelated .ToList();
  1518  
  1519                    if ( subSpecial ty != Guid .Empty)
  1520                    {
  1521                         //Same com ment as ab ove
  1522                         srv.LoadPr operty(use r, "cvt_sy stemuser_m cs_service subtype");
  1523                         var subSpe cialtyRela ted = user .cvt_syste muser_mcs_ servicesub type;
  1524                         if (subSpe cialtyRela ted != nul l)
  1525                             subSpe cialties =  subSpecia ltyRelated .ToList();
  1526                         if (subSpe cialties.C ount == 0)
  1527                         {
  1528                             userAs sociatedWi thSubSpeci alty = tru e;
  1529                             Logger .WriteDebu gMessage(s tring.Form at("{0} ha s no sub-s pecialties  listed, c hecking sp ecialties" , user.Ful lName));
  1530                         }
  1531                         else
  1532                         {
  1533                             var su bMatch = s ubSpecialt ies.FirstO rDefault(s  => s.Id = = subSpeci alty);
  1534                             userAs sociatedWi thSubSpeci alty = sub Match != n ull;
  1535                             Logger .WriteDebu gMessage(S tring.Form at("{0} {1 } {2} as a  sub-speci alty", use r.FullName , userAsso ciatedWith SubSpecial ty ? "has"  : "does n ot have",  subSpecial ty));
  1536                             return  userAssoc iatedWithS ubSpecialt y;
  1537                         }
  1538                    }
  1539                    if ( specialtie s.Count ==  0)
  1540                    {
  1541                         userAssoci atedWithSp ecialty =  true;
  1542                         Logger.Wri teDebugMes sage("User  has no sp ecialties  listed, au to-opting  in " + use r.FullName  + " to em ails");
  1543                    }
  1544                    else
  1545                    {
  1546                         var match  = specialt ies.FirstO rDefault(s  => s.Id = = specialt y);
  1547                         userAssoci atedWithSp ecialty =  match != n ull;
  1548                         Logger.Wri teDebugMes sage(Strin g.Format(" {0} {1} {2 } as a spe cialty", u ser.FullNa me, userAs sociatedWi thSpecialt y ? "has"  : "does no t have", s pecialty)) ;
  1549                    }
  1550                }
  1551                return u serAssocia tedWithSpe cialty;
  1552           }
  1553  
  1554           in ternal voi d SetupVis taReminder Email(Emai l email, E ntityColle ction prov Members, E ntityColle ction patM embers, mc s_services  tsa, bool  provCheck , bool pat Check, Ser viceAppoin tment sa)
  1555           {
  1556                Logger.W riteDebugM essage("Be ginning Se tupVistaRe minderEmai l");
  1557                mcs_faci lity patFa cility = n ull;
  1558                if (tsa. cvt_Patien tFacility  != null)
  1559                    patF acility =  (mcs_facil ity)Organi zationServ ice.Retrie ve(mcs_fac ility.Enti tyLogicalN ame, tsa.c vt_Patient Facility.I d, new Col umnSet("mc s_stationn umber"));
  1560                var patS tation = p atFacility  == null ?  string.Em pty : " ("  + patFaci lity.mcs_S tationNumb er + ")";
  1561                mcs_faci lity proFa cility = n ull;
  1562                if (tsa. cvt_Provid erFacility  != null)
  1563                    proF acility =  (mcs_facil ity)Organi zationServ ice.Retrie ve(mcs_fac ility.Enti tyLogicalN ame, tsa.c vt_Provide rFacility. Id, new Co lumnSet("m cs_station number"));
  1564                var proS tation = p roFacility  == null ?  string.Em pty : " ("  + proFaci lity.mcs_S tationNumb er + ")";
  1565                email.Fr om = CvtHe lper.SetPa rtyList(sa .CreatedBy );
  1566                int time Zone = 0;
  1567                List<Act ivityParty > To = new  List<Acti vityParty> ();
  1568                Logger.W riteDebugM essage(str ing.Format ("Retrieve d pat {0}  and pro {1 } faciliti es and set  the email  sender {2 }", patSta tion, proS tation, em ail.From.T oString()) );
  1569                if (prov Check == f alse)
  1570                {
  1571                    //Ad d Prov Sch eduler Tea m Members  to To Line
  1572                    fore ach (Activ ityParty a p in provM embers.Ent ities)
  1573                    {
  1574                         To.Add(ap) ;
  1575                    }
  1576                    //To  = provMem bers.Entit ies.ToList <ActivityP arty>();
  1577                    Enti ty proSite ; //Either  the site  or facilit y of the p rovider
  1578                    if ( tsa.cvt_re latedprovi dersiteid  != null)
  1579                         proSite =  (mcs_site) Organizati onService. Retrieve(m cs_site.En tityLogica lName, tsa .cvt_relat edprovider siteid.Id,  new Colum nSet(true) );
  1580                    else
  1581                         proSite =  (mcs_facil ity)Organi zationServ ice.Retrie ve(mcs_fac ility.Enti tyLogicalN ame, tsa.c vt_Provide rFacility. Id, new Co lumnSet(tr ue));
  1582                    time Zone = (in t)proSite. Attributes ["mcs_time zone"];
  1583                }
  1584                if (patC heck == fa lse)
  1585                {
  1586                    //Ad d Pat Sche duler Team  Members t o To Line
  1587                    fore ach (Activ ityParty a p in patMe mbers.Enti ties)
  1588                    {
  1589                         To.Add(ap) ;
  1590                    }
  1591                    To =  To.GroupB y(A => A.P artyId.Id) .Select(g  => g.First ()).ToList <ActivityP arty>(); / /Method to  select di stinct rec ipients ba sed on rec ipient ID  (since ent ire Activi ty Party m ay not be  duplicate)
  1592                    Enti ty patSite ;
  1593                    if ( tsa.cvt_re latedprovi dersiteid  != null)
  1594                         patSite =  (mcs_site) Organizati onService. Retrieve(m cs_site.En tityLogica lName, tsa .cvt_relat edprovider siteid.Id,  new Colum nSet(true) );
  1595                    else
  1596                         patSite =  (mcs_facil ity)Organi zationServ ice.Retrie ve(mcs_fac ility.Enti tyLogicalN ame, tsa.c vt_Provide rFacility. Id, new Co lumnSet(tr ue));
  1597                    time Zone = (in t)patSite. Attributes ["mcs_time zone"];
  1598                }
  1599                email.To  = To;
  1600                string t imeZonesSt ring = str ing.Empty;
  1601                bool con vertSucces s = false;
  1602                var time Conversion  = Convert TimeZone(s a.Schedule dStart.Val ue, timeZo ne, out ti meZonesStr ing, out c onvertSucc ess);
  1603                Logger.W riteDebugM essage("Vi sta Remind er (for sc heduler ac tion) Time  converted  to " + ti meZonesStr ing);
  1604                var equi ps = sa.Re sources.Wh ere(ap =>  ap.PartyId .LogicalNa me == Equi pment.Enti tyLogicalN ame).ToLis t();
  1605  
  1606                //Added  to ensure  that resou rces from  child appo intments ( for Group  SAs) are a lso retrie ved and in cluded in  the list o f resource s
  1607                var chil dEquips =  GetApptRes ources(sa,  Equipment .EntityLog icalName);  
  1608                equips.A ddRange(ch ildEquips) ;
  1609                var vist aClinics =  "Vista Cl inic(s): " ;
  1610                foreach  (var equip ment in eq uips)
  1611                {
  1612                    var  e = (Equip ment)Organ izationSer vice.Retri eve(Equipm ent.Entity LogicalNam e, equipme nt.PartyId .Id, new C olumnSet(" mcs_relate dresource" ));
  1613                    var  resource =  (mcs_reso urce)Organ izationSer vice.Retri eve(mcs_re source.Ent ityLogical Name, e.mc s_relatedr esource.Id , new Colu mnSet("mcs _name","mc s_type"));
  1614                    if ( resource.m cs_Type.Va lue == 251 920000)
  1615                         vistaClini cs += reso urce.mcs_n ame + "; " ;
  1616                }
  1617                Logger.W riteDebugM essage("Ad ded vista  clinics to  Scheduler  Action em ail: " + v istaClinic s);
  1618                var disp layTime =  "Appointme nt Start T ime: " + t imeConvers ion + " "  + timeZone sString +  "; <br/>";
  1619                var body  = generat eEmailBody (sa.Id, Se rviceAppoi ntment.Ent ityLogical Name, disp layTime +  vistaClini cs, "Click  Here to o pen the Se rvice Acti vity in TM P");
  1620                var serv iceType =  tsa.cvt_se rvicetype. Name;
  1621                if (tsa. cvt_servic esubtype ! = null)
  1622                    serv iceType +=  " : " + t sa.cvt_ser vicesubtyp e.Name;
  1623                var stat us = sa.St atusCode.V alue == 4  ? "schedul ed" : "can celed";
  1624                var proF acName = t sa.cvt_Pro viderFacil ity == nul l ? string .Empty : t sa.cvt_Pro viderFacil ity.Name +  proStatio n;
  1625                var patF acName = t sa.cvt_Pat ientFacili ty == null   ? string .Empty : t sa.cvt_Pat ientFacili ty.Name +  patStation ;
  1626  
  1627                if (tsa. cvt_Type ! = null &&  tsa.cvt_Ty pe.Value)
  1628                    patF acName = " Home/Mobil e";
  1629  
  1630                email.De scription  = string.F ormat("A { 0} telehea lth appoin tment has  been {1} a t a remote  facility,  please {2 } this pat ient in Vi stA. The p rovider fa cility is:  {3}. The  patient fa cility is:  {4}. {5}{ 6}",
  1631                    serv iceType,
  1632                    stat us,
  1633                    stat us == "sch eduled" ?  "schedule"  : "cancel ",
  1634                    proF acName, 
  1635                    patF acName, 
  1636                    body ,
  1637                    CvtH elper.Emai lFooter()) ;
  1638  
  1639                if (tsa. cvt_relate dpatientsi teid == nu ll)
  1640                    emai l.Subject  += patFacN ame;
  1641  
  1642                CvtHelpe r.UpdateSe ndEmail(em ail, Organ izationSer vice);
  1643           }
  1644  
  1645           in ternal Lis t<Activity Party> Get ApptResour ces(Servic eAppointme nt sa, str ing filter  = "")
  1646           {
  1647                var chil dResources  = new Lis t<Activity Party>();
  1648                var chil dAppts = n ew List<Ap pointment> ();
  1649                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1650                {
  1651                    chil dAppts = s rv.Appoint mentSet.Wh ere(a => a .cvt_servi ceactivity id.Id == s a.Id && a. ScheduledS tart.Value  == sa.Sch eduledStar t.Value).T oList();
  1652                }
  1653                foreach  (var appt  in childAp pts)
  1654                {
  1655                    //If  there is  no entityT ype filter  listed, t hen just a dd all mem bers of ap pointment  requiredAt tendees
  1656                    if ( string.IsN ullOrEmpty (filter))
  1657                         childResou rces.AddRa nge(appt.R equiredAtt endees);
  1658                    else
  1659                    {
  1660                         foreach (v ar resourc e in appt. RequiredAt tendees)
  1661                         {
  1662                             //Part yID should  never be  null, but  added null  check jus t in case.   
  1663                             if (re source.Par tyId != nu ll && reso urce.Party Id.Logical Name == fi lter) 
  1664                                 ch ildResourc es.Add(res ource);
  1665                         }
  1666                    }
  1667                }
  1668                Logger.W riteDebugM essage("Ap pointment  Resources  retrieved  for Servic e Activity : " + sa.I d);
  1669                return c hildResour ces;
  1670           }
  1671           #e ndregion
  1672  
  1673           #r egion TSS  Privilege  e-mails
  1674           in ternal voi d SendPriv ilegingEma il(Email e mail, Guid  tssprivil egeId, str ing record Type)
  1675           {
  1676                Logger.W riteDebugM essage("St arting Sen dPrivilegi ngEmail");
  1677                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1678                {
  1679                    //Ge t the rela ted TSS Pr ivileging  record
  1680                    cvt_ tssprivile ging tsspr ivileging  = (cvt_tss privilegin g)Organiza tionServic e.Retrieve (cvt_tsspr ivileging. EntityLogi calName, t ssprivileg eId, new C olumnSet(t rue));
  1681                    if ( tssprivile ging.cvt_P rivilegedA tId != nul l) //Alway s filled
  1682                    {
  1683                         #region va riables
  1684                         //Notifica tion of Pr ivileging  Status Cha nge
  1685                         List<Team>  TOTeam =  new List<T eam>();
  1686                         //Establis h paramete rs to clea n up queri es
  1687                         List<Activ ityParty>  recipient  = new List <ActivityP arty>();
  1688                         List<Team>  homeCPTea m = new Li st<Team>() ;
  1689                         List<Team>  proxyCPTe am = new L ist<Team>( );
  1690                         #endregion
  1691  
  1692                         #region if Regarding  =home
  1693                         Boolean is RegardingP rivHome =  true;
  1694                         cvt_tsspri vileging h omePrivRec ord = tssp rivileging ;
  1695                         cvt_tsspri vileging p roxyPrivRe cord = new  cvt_tsspr ivileging( );
  1696  
  1697                         #endregion
  1698                         #region if Regarding  =proxy
  1699                         //Regardin g is Proxy , overwrit e homeProv Record and  isRegardi ngPrivHome
  1700                         if ((tsspr ivileging. cvt_Typeof Privilegin g != null)  && (tsspr ivileging. cvt_Typeof Privilegin g.Value ==  917290001 ) && (tssp rivileging .cvt_Refer encedPrivi legeId !=  null))
  1701                         {
  1702                             isRega rdingPrivH ome = fals e;
  1703                             homePr ivRecord =  (cvt_tssp rivileging )Organizat ionService .Retrieve( cvt_tsspri vileging.E ntityLogic alName, ts sprivilegi ng.cvt_Ref erencedPri vilegeId.I d, new Col umnSet(tru e));
  1704                             proxyP rivRecord  = tssprivi leging;
  1705                             proxyC PTeam = sr v.TeamSet. Where(p =>  p.cvt_Fac ility.Id = = proxyPri vRecord.cv t_Privileg edAtId.Id  && p.cvt_T ype.Value  == 9172900 03).Distin ct().ToLis t();
  1706                         }
  1707                         #endregion
  1708  
  1709                         //Home CPT eam is alw ays set
  1710                         homeCPTeam  = srv.Tea mSet.Where (p => p.cv t_Facility .Id == hom ePrivRecor d.cvt_Priv ilegedAtId .Id && p.c vt_Type.Va lue == 917 290003).Di stinct().T oList();
  1711  
  1712                         #region Pr ivilege St atus Chang e
  1713                         if (email. Subject.In dexOf("Not ification  of Privile ging Statu s Change")  != -1)
  1714                         {
  1715                             Logger .WriteDebu gMessage(" Privilege  Status Cha nge branch ");
  1716                             #regio n Record i s Active
  1717                             //Chec k if recor d is inact ive or act ive
  1718                             if (ts sprivilegi ng.stateco de.Value = = cvt_tssp rivileging State.Acti ve)
  1719                             {
  1720                                 cu stomMessag e = String .Format("T his is to  notify all  affected  Facilities  that this  provider  is now pri vileged at  {0}.  If  this provi der posses sed proxy  privileges  for telem edicine pu rposes at  your facil ity, those  privilege s may be r einstated. <br/><br/> This provi der may no w be inclu ded in Tel ehealth Se rvice Agre ements and  schedulin g for this  provider  may commen ce.", tssp rivileging .cvt_Privi legedAtId. Name);
  1721                                 cu stomMessag e += "<br/ ><br/>Plea se get the  new privi leging doc uments fro m the home  facility. ";
  1722  
  1723                                 // TO FTC, Se rvice Chie f and C&P  Teams (Pro xy Privile ging Facil ities)
  1724                                 // Loop throu gh each Pr oxy Privil ege
  1725                                 va r proxys =  srv.cvt_t ssprivileg ingSet.Whe re(p => p. cvt_Refere ncedPrivil egeId.Id = = tssprivi leging.Id) ;
  1726  
  1727                                 fo reach (cvt _tssprivil eging prox y in proxy s)
  1728                                 {
  1729                                      List<Tea m> FTCTeam  = new Lis t<Team>();
  1730                                      List<Tea m> SCTeam  = new List <Team>();
  1731                                      List<Tea m> CPTeam  = new List <Team>();
  1732                                      FTCTeam  = srv.Team Set.Where( p => p.cvt _Facility. Id == prox y.cvt_Priv ilegedAtId .Id && p.c vt_Type.Va lue == (in t)Teamcvt_ Type.FTC). Distinct() .ToList();
  1733                                      SCTeam =  srv.TeamS et.Where(p  => p.cvt_ Facility.I d == proxy .cvt_Privi legedAtId. Id && p.cv t_Type.Val ue == (int )Teamcvt_T ype.Servic eChief &&  p.cvt_Serv iceType.Id  == proxy. cvt_Servic eTypeId.Id ).Distinct ().ToList( );
  1734                                      CPTeam =  srv.TeamS et.Where(p  => p.cvt_ Facility.I d == proxy .cvt_Privi legedAtId. Id && p.cv t_Type.Val ue == (int )Teamcvt_T ype.Creden tialingand Privilegin g).Distinc t().ToList ();
  1735  
  1736                                      //Loop t he results  into the  TO field
  1737                                      foreach  (var resul t in FTCTe am)
  1738                                      {
  1739                                          emai l.To = Ret rieveFacil ityTeamMem bers(email , result.I d, email.T o);
  1740                                      }
  1741                                      foreach  (var resul t in SCTea m)
  1742                                      {
  1743                                          emai l.To = Ret rieveFacil ityTeamMem bers(email , result.I d, email.T o);
  1744                                      }
  1745                                      foreach  (var resul t in CPTea m)
  1746                                      {
  1747                                          emai l.To = Ret rieveFacil ityTeamMem bers(email , result.I d, email.T o);
  1748                                      }
  1749                                 }
  1750  
  1751  
  1752                                 // Enable Use r Record.
  1753                                 Se tStateRequ est reques tEnable =  new SetSta teRequest( )
  1754                                 {
  1755                                      EntityMo niker = ne w EntityRe ference(Sy stemUser.E ntityLogic alName, ts sprivilegi ng.cvt_Pro viderId.Id ),
  1756                                      State =  new Option SetValue(0 ),//1=disa bled, 0=en abled
  1757                                      Status =  new Optio nSetValue( -1)
  1758                                 };
  1759  
  1760                                 Or ganization Service.Ex ecute(requ estEnable) ;
  1761                                 // Discuss: A utomatical ly reactiv ate TSS Pr ivileging  for Proxy?
  1762  
  1763                             }
  1764                             #endre gion
  1765                             #regio n Record i s Deactiva ted
  1766                             else / /Deactivat e
  1767                             {
  1768                                 cu stomMessag e = String .Format("T his is to  notify all  affected  Facilities  that this  provider  is no long er privile ged at {0} .If this p rovider po ssessed pr oxy privil eges for t elemedicin e purposes  at your f acility, t hey are no  longer in  effect.<b r/><br/>Th is provide r will nee d to be re placed on  any existi ng Service  Agreement s or new S ervice Agr eements wi ll need to  be compos ed for a n ew provide r.<br/><br />Any Serv ice Activi ties that  have been  scheduled  for this p rovider wi ll need to  be resche duled with  another." , tssprivi leging.cvt _Privilege dAtId.Name );
  1769  
  1770                                 // TO FTC, Se rvice Chie f and C&P  Teams
  1771                                 Li st<Team> F TCTeam = n ew List<Te am>();
  1772                                 Li st<Team> S CTeam = ne w List<Tea m>();
  1773                                 Li st<Team> C PTeam = ne w List<Tea m>();
  1774                                 FT CTeam = sr v.TeamSet. Where(p =>  p.cvt_Fac ility.Id = = tssprivi leging.cvt _Privilege dAtId.Id & & p.cvt_Ty pe.Value = = (int)Tea mcvt_Type. FTC).Disti nct().ToLi st();
  1775                                 SC Team = srv .TeamSet.W here(p =>  p.cvt_Faci lity.Id ==  tssprivil eging.cvt_ Privileged AtId.Id &&  p.cvt_Typ e.Value ==  (int)Team cvt_Type.S erviceChie f && p.cvt _ServiceTy pe.Id == t ssprivileg ing.cvt_Se rviceTypeI d.Id).Dist inct().ToL ist();
  1776                                 CP Team = srv .TeamSet.W here(p =>  p.cvt_Faci lity.Id ==  tssprivil eging.cvt_ Privileged AtId.Id &&  p.cvt_Typ e.Value ==  (int)Team cvt_Type.C redentiali ngandPrivi leging).Di stinct().T oList();
  1777  
  1778                                 // Loop the r esults int o the TO f ield
  1779                                 fo reach (var  result in  FTCTeam)
  1780                                 {
  1781                                      email.To  = Retriev eFacilityT eamMembers (email, re sult.Id, e mail.To);
  1782                                 }
  1783                                 fo reach (var  result in  SCTeam)
  1784                                 {
  1785                                      email.To  = Retriev eFacilityT eamMembers (email, re sult.Id, e mail.To);
  1786                                 }
  1787                                 fo reach (var  result in  CPTeam)
  1788                                 {
  1789                                      email.To  = Retriev eFacilityT eamMembers (email, re sult.Id, e mail.To);
  1790                                 }
  1791  
  1792                                 // Disable Us er Record.
  1793                                 // Remvoves t he value f rom the fi eld
  1794                                 Sy stemUser p rovUpdate  = new Syst emUser()
  1795                                 {
  1796                                      Id = tss privilegin g.cvt_Prov iderId.Id,
  1797                                      cvt_disa ble = null
  1798                                 };
  1799  
  1800                                 // Disable th e provider 's user re cord here
  1801                                 Se tStateRequ est reques tDisable =  new SetSt ateRequest ()
  1802                                 {
  1803                                      EntityMo niker = ne w EntityRe ference(Sy stemUser.E ntityLogic alName, ts sprivilegi ng.cvt_Pro viderId.Id ),
  1804                                      State =  new Option SetValue(1 ),
  1805                                      Status =  new Optio nSetValue( -1)
  1806                                 };
  1807  
  1808                                 Or ganization Service.Up date(provU pdate);
  1809                                 Or ganization Service.Ex ecute(requ estDisable );
  1810                                 // Automatica lly disabl e Proxy TS S Privileg ing record s
  1811                                 va r proxys =  srv.cvt_t ssprivileg ingSet.Whe re(p => p. cvt_Refere ncedPrivil egeId.Id = = tssprivi leging.Id) ;
  1812  
  1813                                 fo reach (cvt _tssprivil eging prox y in proxy s)
  1814                                 {
  1815                                      SetState Request di sableProxy  = new Set StateReque st()
  1816                                      {
  1817                                          Enti tyMoniker  = new Enti tyReferenc e(cvt_tssp rivileging .EntityLog icalName,  proxy.Id),
  1818                                          Stat e = new Op tionSetVal ue(1),
  1819                                          Stat us = new O ptionSetVa lue(-1)
  1820                                      };
  1821                                      Organiza tionServic e.Execute( disablePro xy);
  1822                                 }
  1823                                 Lo gger.Write DebugMessa ge("Disabl ed all Pro xy Privile ges.");
  1824                             }
  1825                             #endre gion
  1826                             
  1827                         }
  1828                         #endregion
  1829                         #region In itial Priv ileging
  1830                         //Initial  Privilegin g
  1831                         if (email. Subject.In dexOf("Tel ehealth No tification : A Provid er is now  privileged ") != -1)
  1832                         {
  1833                             Logger .WriteDebu gMessage(" Initial Pr ivileging  branch");
  1834                             if (is RegardingP rivHome) / /Home
  1835                             {
  1836                                 fo reach (var  cp in hom eCPTeam)
  1837                                 {
  1838                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1839                                 }
  1840                                 // Add FTC an d SC team
  1841                                 em ail = addF acilityTea mstoEmail( email, hom ePrivRecor d.cvt_Priv ilegedAtId .Id, homeP rivRecord. cvt_Servic eTypeId.Id );
  1842                                 cu stomMessag e = "A Hom e Privileg e has been  granted a t Facility : " + home PrivRecord .cvt_Privi legedAtId. Name;
  1843                             }
  1844                             else / /Proxy
  1845                             {
  1846                                 fo reach (var  cp in pro xyCPTeam)
  1847                                 {
  1848                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1849                                 }
  1850                                 // Add FTC an d SC team
  1851                                 em ail = addF acilityTea mstoEmail( email, pro xyPrivReco rd.cvt_Pri vilegedAtI d.Id, home PrivRecord .cvt_Servi ceTypeId.I d);
  1852  
  1853                                 fo reach (var  cp in hom eCPTeam)
  1854                                 {
  1855                                      email.Cc  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1856                                 }
  1857                                 // Add FTC an d SC team
  1858                                 em ail = addF acilityTea mstoEmail( email, hom ePrivRecor d.cvt_Priv ilegedAtId .Id, homeP rivRecord. cvt_Servic eTypeId.Id );
  1859  
  1860                                 cu stomMessag e = "A Pro xy Privile ge has bee n granted  at Facilit y: " + pro xyPrivReco rd.cvt_Pri vilegedAtI d.Name;
  1861                                 cu stomMessag e += "<br/ >Home Priv ilege: The  provider' s HOME pri vileging i s at Facil ity: " + h omePrivRec ord.cvt_Pr ivilegedAt Id.Name;
  1862                                 cu stomMessag e += "<br/ >Reminder:  Please en ter the pr ovider int o your loc al PPE pro cess.";
  1863                             }
  1864                         }
  1865                         #endregion
  1866                         #region Re newal
  1867                         //Check if  E-mail su bject = "R enewal"
  1868                         else if (e mail.Subje ct.IndexOf ("Teleheal th Notific ation: Upc oming Rene wal for a  Provider")  != -1)
  1869                         {
  1870                             Logger .WriteDebu gMessage(" Renewal br anch");
  1871                             if (is RegardingP rivHome ==  true)
  1872                             {
  1873                                 // Update Hom e/Primary  TSS Privil ege //If S tatus Reas on = Privi leged; set  to In Ren ewal
  1874                                 if  (homePriv Record.sta tuscode.Va lue == 917 290001)
  1875                                 {
  1876                                      //Declar e new obje ct
  1877                                      cvt_tssp rivileging  homeRecor d = new cv t_tssprivi leging()
  1878                                      {
  1879                                          Id =  homePrivR ecord.Id,
  1880                                          stat uscode = n ew OptionS etValue(91 7290002)
  1881                                      };
  1882                                      Organiza tionServic e.Update(h omeRecord) ;
  1883                                 }
  1884                                 fo reach (var  cp in hom eCPTeam)
  1885                                 {
  1886                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1887                                 }
  1888  
  1889                                 va r homeSC =  srv.TeamS et.Where(t  => t.cvt_ Facility.I d == homeP rivRecord. cvt_Privil egedAtId.I d && t.cvt _ServiceTy pe.Id == h omePrivRec ord.cvt_Se rviceTypeI d.Id && t. cvt_Type.V alue == (i nt)Teamcvt _Type.Serv iceChief);
  1890                                 fo reach (var  sc in hom eSC)
  1891                                 {
  1892                                      email.Cc  = Retriev eFacilityT eamMembers (email, sc .Id, email .To);
  1893                                 }
  1894  
  1895                                 // Edit the E -mail body
  1896                                 cu stomMessag e = homePr ivRecord.c vt_Provide rId.Name +  "'s Home  Privilege  is up for  renewal at  Facility:  " + homeP rivRecord. cvt_Privil egedAtId.N ame;
  1897                                 cu stomMessag e += "<br/ >The privi leges are  due to exp ire on " +  homePrivR ecord.cvt_ Expiration Date + "." ;
  1898                                 cu stomMessag e += "<br/ ><br/>Note : Home Pri vilege has  been set  to 'In Ren ewal' stat us.";
  1899                             }
  1900                         }
  1901                         #endregion
  1902                         #region Su spended
  1903                         //Else if  Suspended
  1904                         else if (e mail.Subje ct.IndexOf ("Teleheal th Notific ation: A P rovider's  Privilegin g has been  Suspended ") != -1)
  1905                         {
  1906                             Logger .WriteDebu gMessage(" Privilege  Suspended  branch");
  1907                             if (is RegardingP rivHome ==  true)
  1908                             {
  1909                                 fo reach (var  cp in hom eCPTeam)
  1910                                 {
  1911                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1912                                 }
  1913                                 // Update the  provider' s record
  1914                                 Sy stemUser p rovider =  (SystemUse r)Organiza tionServic e.Retrieve (SystemUse r.EntityLo gicalName,  tssprivil eging.cvt_ ProviderId .Id, new C olumnSet(t rue));
  1915                                 pr ovider.cvt _disable =  true;
  1916                                 Or ganization Service.Up date(provi der);
  1917  
  1918                                 // Edit the E -mail body
  1919                                 cu stomMessag e = "A pro vider's HO ME privile ging has b een suspen ded at Fac ility: " +  homePrivR ecord.cvt_ Privileged AtId.Name;
  1920                                 cu stomMessag e += "<br/ >Note: THE  PROVIDER' S USER REC ORD HAS BE EN DISABLE D.  This P rovider ca n no longe r be sched uled in th e system." ;
  1921                                 cu stomMessag e += "<br/ >Suspensio n: The sus pension oc curred at  Facility:  " + homePr ivRecord.c vt_Privile gedAtId.Na me;
  1922                             }
  1923                             else
  1924                             {
  1925                                 fo reach (var  cp in hom eCPTeam)
  1926                                 {
  1927                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1928                                 }
  1929                                 fo reach (var  cp in pro xyCPTeam)
  1930                                 {
  1931                                      email.Cc  = Retriev eFacilityT eamMembers (email, cp .Id, email .Cc);
  1932                                 }
  1933  
  1934                                 // Edit the E -mail body
  1935                                 cu stomMessag e = "A pro vider's PR OXY privil eging has  been suspe nded at Fa cility: "  + proxyPri vRecord.cv t_Privileg edAtId.Nam e;
  1936                                 cu stomMessag e += "<br/ >Note: Thi s Provider  is still  schedulabl e in the s ystem.";
  1937                                 cu stomMessag e += "<br/ >Suspensio n: The sus pension oc curred at  Facility:"  + proxyPr ivRecord.c vt_Privile gedAtId.Na me;
  1938                                 cu stomMessag e += "<br/ >Home Priv ilege: The  provider' s HOME pri vileging i s at Facil ity: " + h omePrivRec ord.cvt_Pr ivilegedAt Id.Name;
  1939                             }
  1940                         }
  1941                         #endregion
  1942  
  1943                         //Generate  body and  then send
  1944                         customMess age += "<b r/>Reminde r: Notify  all pertin ent C&P Of ficers and  Service C hiefs.";
  1945                         email.Desc ription =  generateEm ailBody(ts sprivilege Id, "cvt_t ssprivileg ing", cust omMessage,  "Please c lick this  link to vi ew the Pri vileging r ecord.");
  1946  
  1947                         //Get the  owner of t he workflo w for the  From field
  1948                         email.From  = CvtHelp er.GetWork flowOwner( "Privilegi ng: PPE Su bmitted",  Organizati onService) ;
  1949  
  1950                         if (email. To != null )
  1951                         {
  1952                             CvtHel per.Update SendEmail( email, Org anizationS ervice);
  1953                         }
  1954                    }
  1955                }
  1956           }
  1957  
  1958           in ternal Ema il addFaci lityTeamst oEmail(Ema il email,  Guid facil ity, Guid  specialtyI d)
  1959           {
  1960                Logger.W riteDebugM essage("St arting add FacilityTe amstoEmail ");
  1961                if (faci lity != nu ll)
  1962                {
  1963                    usin g (var srv  = new Xrm (Organizat ionService ))
  1964                    {
  1965                         //Provider
  1966                         List<Team>  FTCTeam =  new List< Team>();
  1967                         List<Team>  SCTeam =  new List<T eam>();
  1968                         FTCTeam =  srv.TeamSe t.Where(p  => p.cvt_F acility.Id  == facili ty && p.cv t_Type.Val ue == (int )Teamcvt_T ype.FTC).D istinct(). ToList();
  1969                         SCTeam = s rv.TeamSet .Where(p = > p.cvt_Fa cility.Id  == facilit y && p.cvt _Type.Valu e == (int) Teamcvt_Ty pe.Service Chief && p .cvt_Servi ceType.Id  == special tyId).Dist inct().ToL ist();
  1970  
  1971                         //Loop the  results i nto the TO  field
  1972                         foreach (v ar result  in FTCTeam )
  1973                         {
  1974                             email. To = Retri eveFacilit yTeamMembe rs(email,  result.Id,  email.To) ;
  1975                         }
  1976                         Logger.Wri teDebugMes sage("Adde d FTC Team  members t o the TO." );
  1977                         foreach (v ar result  in SCTeam)
  1978                         {
  1979                             email. To = Retri eveFacilit yTeamMembe rs(email,  result.Id,  email.To) ;
  1980                         }
  1981                         Logger.Wri teDebugMes sage("Adde d SC Team  members to  the TO.") ;
  1982                    }                 
  1983                }
  1984                return e mail;
  1985           }
  1986           #e ndregion 
  1987  
  1988           #r egion FPPE /OPPE Chec k e-mail
  1989           // Add SC Tea m to TO/CC  7/24/15
  1990           in ternal voi d SendTrig gerEmail(E mail email , Guid fpp eID, strin g recordTy pe)
  1991           {
  1992                Logger.s etMethod =  "SendTrig gerEmail";
  1993                Logger.W riteDebugM essage("St arting");
  1994                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1995                {
  1996                    //Ch eck system  generated  e-mail
  1997                    if ( email.Subj ect.IndexO f("Telehea lth Notifi cation: PP E Submitte d") != -1)
  1998                    {
  1999                         //Get the  owner of t he workflo w for the  From field
  2000                         email.From  = CvtHelp er.GetWork flowOwner( "Privilegi ng: PPE Su bmitted",  Organizati onService) ;
  2001  
  2002                         Logger.Wri teDebugMes sage("Get  the PPE re lated to t he email") ;
  2003                         cvt_qualit ycheck fpp e = (cvt_q ualitychec k)Organiza tionServic e.Retrieve (cvt_quali tycheck.En tityLogica lName, fpp eID, new C olumnSet(t rue));
  2004  
  2005                         //Find the  Privilege  record as sociated a nd navigat e to that  record
  2006                         if (fppe.c vt_TSSPriv ilegingId  != null)
  2007                         {                
  2008                             cvt_ts sprivilegi ng fppePri v = (cvt_t ssprivileg ing)Organi zationServ ice.Retrie ve(cvt_tss privilegin g.EntityLo gicalName,  fppe.cvt_ TSSPrivile gingId.Id,  new Colum nSet(true) );
  2009                             //Assu ming Home
  2010                             cvt_ts sprivilegi ng homePri v = fppePr iv;
  2011                             Boolea n isRegard ingRelated PrivHome =  true;
  2012                             Guid h omeService Type = fpp ePriv.cvt_ ServiceTyp eId != nul l ? fppePr iv.cvt_Ser viceTypeId .Id : Guid .Empty;
  2013                             List<T eam> homeS CTeams = n ew List<Te am>();
  2014                             List<T eam> proxy SCTeams =  new List<T eam>();
  2015  
  2016                             if (ho mePriv.cvt _TypeofPri vileging.V alue != 91 7290000) / /Overwriti ng since P roxy
  2017                             {
  2018                                 is RegardingR elatedPriv Home = fal se;
  2019                                 ho mePriv = ( cvt_tsspri vileging)O rganizatio nService.R etrieve(cv t_tssprivi leging.Ent ityLogical Name, fppe Priv.cvt_R eferencedP rivilegeId .Id, new C olumnSet(t rue));
  2020                             }
  2021  
  2022                             if (ho meServiceT ype == Gui d.Empty)
  2023                                 ho meServiceT ype = home Priv.cvt_S erviceType Id != null  ? homePri v.cvt_Serv iceTypeId. Id : Guid. Empty;
  2024  
  2025                             //Add  Service Ch ief Team -  should on ly ever be  one
  2026                             homeSC Teams = sr v.TeamSet. Where(t =>  t.cvt_Fac ility.Id = = homePriv .cvt_Privi legedAtId. Id && t.cv t_Type.Val ue == 9172 90001 && t .cvt_Servi ceType.Id  == homeSer viceType). Distinct() .ToList();
  2027  
  2028                             foreac h (var res ult in hom eSCTeams)
  2029                             {
  2030                                 em ail.To = R etrieveFac ilityTeamM embers(ema il, result .Id, email .To);
  2031                             }
  2032                             var fl ag = "Gree n";
  2033                             if (fp pe.cvt_Fla g != null  && fppe.cv t_Flag.Val ue != 9172 90000)
  2034                                 fl ag = "Red" ;
  2035  
  2036                             //Edit  the E-mai l body
  2037                             custom Message =  "A " + fla g + " flag ged FPPE/O PPE has be en submitt ed.";
  2038  
  2039                             //If a ctually fr om Proxy,  set those  team membe rs as Cc
  2040                             if (is RegardingR elatedPriv Home == fa lse)
  2041                             {
  2042                                 if  (fppePriv .cvt_Privi legedAtId  != null)
  2043                                      proxySCT eams = srv .TeamSet.W here(t =>  t.cvt_Faci lity.Id ==  fppePriv. cvt_Privil egedAtId.I d && 
  2044                                          t.cv t_Type.Val ue == 9172 90001 && t .cvt_Servi ceType.Id  == homeSer viceType). Distinct() .ToList();
  2045                                 fo reach (var  proxyTeam  in proxyS CTeams)
  2046                                 {
  2047                                      email.Cc  = Retriev eFacilityT eamMembers (email, pr oxyTeam.Id , email.Cc );
  2048                                 }
  2049                                 cu stomMessag e += "<br/ >This FPPE /OPPE was  submitted  regarding  the Proxy  Privilege. ";
  2050                                 cu stomMessag e += "<br/ >Proxy Pri vilege is  at Facilit y: " + fpp ePriv.cvt_ Privileged AtId.Name;
  2051                                 
  2052                             }
  2053  
  2054                             custom Message +=  "<br/>Hom e Privileg e is at Fa cility: "  + homePriv .cvt_Privi legedAtId. Name;
  2055                             custom Message +=  "<br/>Spe cialty: "  + homePriv .cvt_Servi ceTypeId.N ame;
  2056                             //cust omMessage  += "Date R ange: " +  fppe.cvt_E valuationS tartDate +  " to " +  fppe.cvt_E valuationE ndDate;
  2057                             custom Message +=  "<br/>Rem inder: Not ify all pe rtinent C& P Officers  and Servi ce Chiefs. ";
  2058                             email. Descriptio n = genera teEmailBod y(fppeID,  "cvt_quali tycheck",  customMess age, "Plea se click t his link t o view the  FPPE/OPPE  record.") ;
  2059                             if (em ail.To !=  null)
  2060                                 Cv tHelper.Up dateSendEm ail(email,  Organizat ionService );
  2061                         }
  2062                    }
  2063                }
  2064           }
  2065           #e ndregion
  2066  
  2067           #r egion PPE  Review/Fee dback
  2068           in ternal voi d SendPPER eviewEmail (Email ema il, Guid p peId, stri ng recordT ype)
  2069           {
  2070                Logger.s etMethod =  "SendPPER eviewEmail ";
  2071                Logger.W riteDebugM essage("St arting");
  2072                using (v ar srv = n ew Xrm(Org anizationS ervice))
  2073                {
  2074                    //Ch eck system  generated  e-mail
  2075                    if ( email.Subj ect.IndexO f("PPE fee dback trac king") !=  -1)
  2076                    {
  2077                         //Get the  owner of t he workflo w for the  From field
  2078                         email.From  = CvtHelp er.GetWork flowOwner( "Privilegi ng: PPE Su bmitted",  Organizati onService) ;
  2079  
  2080                         Logger.Wri teDebugMes sage("Get  the PPE re lated to t he email") ;
  2081                         cvt_pperev iew review  = (cvt_pp ereview)Or ganization Service.Re trieve(cvt _ppereview .EntityLog icalName,  ppeId, new  ColumnSet (true));
  2082  
  2083                         //Find the  Privilege  record as sociated a nd navigat e to that  record
  2084                         if (review .cvt_teleh ealthprivi leging !=  null)
  2085                         {
  2086                             cvt_ts sprivilegi ng ppePriv  = (cvt_ts sprivilegi ng)Organiz ationServi ce.Retriev e(cvt_tssp rivileging .EntityLog icalName,  review.cvt _telehealt hprivilegi ng.Id, new  ColumnSet (true));
  2087  
  2088                             Guid h omeService Type = ppe Priv.cvt_S erviceType Id != null  ? ppePriv .cvt_Servi ceTypeId.I d : Guid.E mpty;
  2089                             List<T eam> homeS CTeams = n ew List<Te am>();
  2090  
  2091                             //Add  Service Ch ief Team -  should on ly ever be  one
  2092                             homeSC Teams = sr v.TeamSet. Where(t =>  t.cvt_Fac ility.Id = = ppePriv. cvt_Privil egedAtId.I d && t.cvt _Type.Valu e == 91729 0001 && t. cvt_Servic eType.Id = = homeServ iceType).D istinct(). ToList();
  2093  
  2094                             foreac h (var res ult in hom eSCTeams)
  2095                             {
  2096                                 em ail.To = R etrieveFac ilityTeamM embers(ema il, result .Id, email .To);
  2097                             }
  2098  
  2099                             //Comp leted Feed back porti on
  2100                             if (em ail.Subjec t.IndexOf( "Completed ") != -1)
  2101                             {
  2102                                 cu stomMessag e = String .Format("< br/><br/>P PE Feedbac k collecti on that wa s initiate d for {0}  was comple ted.<br/>< br/>Please  set the n ext PPE Re view Date  on the Tel ehealth Pr ivileging  record. Li nk above." , ppePriv. cvt_Provid erId.Name) ;
  2103                                 em ail.Descri ption = ge nerateEmai lBody(ppeP riv.Id, pp ePriv.Logi calName, c ustomMessa ge, "Pleas e click th is link to  view the  Telehealth  Privilegi ng record. ");
  2104                                 if  (email.To  != null)
  2105                                      CvtHelpe r.UpdateSe ndEmail(em ail, Organ izationSer vice);
  2106                                 re turn;
  2107                             }
  2108                         }
  2109                    }
  2110                }
  2111           }
  2112  
  2113           in ternal voi d SendPPEF eedbackEma il(Email e mail, Guid  feedbackI d, string  recordType )
  2114           {
  2115                Logger.s etMethod =  "SendPPEF eedbackEma il";
  2116                Logger.W riteDebugM essage("St arting");
  2117                using (v ar srv = n ew Xrm(Org anizationS ervice))
  2118                {
  2119                    //Ch eck system  generated  e-mail
  2120                    if ( email.Subj ect.IndexO f("Action  Required:  OPPE/FPPE  Feedback")  != -1)
  2121                    {
  2122                         //Get the  owner of t he workflo w for the  From field
  2123                         email.From  = CvtHelp er.GetWork flowOwner( "Privilegi ng: PPE Su bmitted",  Organizati onService) ;
  2124  
  2125                         Logger.Wri teDebugMes sage("Get  the PPE re lated to t he email") ;
  2126                         cvt_ppefee dback feed back = (cv t_ppefeedb ack)Organi zationServ ice.Retrie ve(cvt_ppe feedback.E ntityLogic alName, fe edbackId,  new Column Set(true)) ;
  2127  
  2128                         //Get the  ppe_review  record fo r the Due  Date
  2129                         cvt_pperev iew ppeRev iew = (cvt _ppereview )Organizat ionService .Retrieve( cvt_pperev iew.Entity LogicalNam e, feedbac k.cvt_pper eview.Id,  new Column Set(true)) ;
  2130                         var dueDat e = (DateT ime)ppeRev iew.cvt_du edate;
  2131                         var initia tedDate =  (DateTime) ppeReview. cvt_initia teddate;
  2132  
  2133                         var daysRe maining =  (dueDate -  DateTime. Today);
  2134                         var daysEl apsed = (D ateTime.To day - init iatedDate) ;
  2135  
  2136                         Boolean is Escalation  = false;
  2137                         if (email. Subject.In dexOf("ove rdue") !=  -1)
  2138                             isEsca lation = t rue;
  2139  
  2140                         //Find the  Privilege  record as sociated a nd navigat e to that  record
  2141                         if (feedba ck.cvt_pro xyprivileg ing != nul l)
  2142                         {
  2143                             cvt_ts sprivilegi ng proxyPr iv = (cvt_ tssprivile ging)Organ izationSer vice.Retri eve(cvt_ts sprivilegi ng.EntityL ogicalName , feedback .cvt_proxy privilegin g.Id, new  ColumnSet( true));
  2144  
  2145                             Guid h omeService Type = pro xyPriv.cvt _ServiceTy peId != nu ll ? proxy Priv.cvt_S erviceType Id.Id : Gu id.Empty;
  2146                             List<T eam> proxy SCTeams =  new List<T eam>();
  2147                             List<T eam> proxy CoSTeams =  new List< Team>();
  2148                             var te am = "";
  2149                             if (is Escalation )
  2150                             {
  2151                                 pr oxyCoSTeam s = srv.Te amSet.Wher e(t => t.c vt_Facilit y.Id == pr oxyPriv.cv t_Privileg edAtId.Id  && t.cvt_T ype.Value  == (int)Te amcvt_Type .ChiefofSt aff).Disti nct().ToLi st();
  2152                                 va r proxyCOS Team = srv .TeamSet.F irstOrDefa ult(t => t .cvt_Facil ity.Id ==  proxyPriv. cvt_Privil egedAtId.I d && t.cvt _Type.Valu e == (int) Teamcvt_Ty pe.Chiefof Staff);
  2153                                 if  (proxyCOS Team != nu ll && feed back.cvt_r esponseesc alated ==  null)
  2154                                 {
  2155                                      //Set th e response  requested  field
  2156                                      cvt_ppef eedback up dateFeedba ck = new c vt_ppefeed back()
  2157                                      {
  2158                                          Id =  feedback. Id,
  2159                                          cvt_ responsees calated =  new Entity Reference( Team.Entit yLogicalNa me, proxyC OSTeam.Id)
  2160  
  2161                                      };
  2162                                      Organiza tionServic e.Update(u pdateFeedb ack);
  2163                                      Logger.W riteDebugM essage("Up dated the  PPE Feedba ck's Escal ation Requ est Team w ith " + pr oxyCOSTeam .Name);
  2164                                 }
  2165                             }
  2166                             //Serv ice Chief  Team
  2167                             proxyS CTeams = s rv.TeamSet .Where(t = > t.cvt_Fa cility.Id  == proxyPr iv.cvt_Pri vilegedAtI d.Id && t. cvt_Type.V alue == 91 7290001 &&  t.cvt_Ser viceType.I d == homeS erviceType ).Distinct ().ToList( );
  2168  
  2169                             //Depe nding if i t is feedb ack or esc alation                        
  2170                             foreac h (var res ult in pro xySCTeams)
  2171                             {
  2172                                 em ail.To = R etrieveFac ilityTeamM embers(ema il, result .Id, email .To);
  2173                             }
  2174                             var pr oxySCTeam  = srv.Team Set.FirstO rDefault(t  => t.cvt_ Facility.I d == proxy Priv.cvt_P rivilegedA tId.Id &&  t.cvt_Type .Value ==  917290001  && t.cvt_S erviceType .Id == hom eServiceTy pe);
  2175                             if (pr oxySCTeam  != null &&  feedback. cvt_respon serequeste d == null)
  2176                             {
  2177                                 // Set the re sponse req uested fie ld
  2178                                 cv t_ppefeedb ack update Feedback =  new cvt_p pefeedback ()
  2179                                 {
  2180                                      Id = fee dback.Id,
  2181                                      cvt_resp onsereques ted = new  EntityRefe rence(Team .EntityLog icalName,  proxySCTea m.Id)
  2182  
  2183                                 };
  2184                                 Or ganization Service.Up date(updat eFeedback) ;
  2185                                 Lo gger.Write DebugMessa ge("Update d the PPE  Feedback's  Request T eam with "  + proxySC Team.Name) ;
  2186                             }
  2187  
  2188                             if (is Escalation )
  2189                             {
  2190                                 // Set the Cc  to the SC  team
  2191                                 em ail.Cc = e mail.To;
  2192                                 em ail.To = n ull;
  2193  
  2194                                 // Set the To  to the Co S team
  2195                                 fo reach (var  result in  proxyCoST eams)
  2196                                 {
  2197                                      email.To  = Retriev eFacilityT eamMembers (email, re sult.Id, e mail.To);
  2198                                 }
  2199                             }
  2200                             var pr ov = srv.S ystemUserS et.FirstOr Default(su  => su.Id  == ppeRevi ew.cvt_pro vider.Id);
  2201                             var pr ovEmail =  (prov != n ull) ? pro v.Internal EMailAddre ss : "";
  2202  
  2203                             string  url = Cvt Helper.get ServerURL( Organizati onService)  + "/userD efined/edi t.aspx?etc =" + CvtHe lper.GetEn tityTypeCo de(Organiz ationServi ce, feedba ck.Logical Name) + "& id=" + fee dback.Id;
  2204  
  2205                             //Cust om email t ext
  2206                             string  link = "< a href=\""  + url + " \">Link</a >";
  2207                             custom Message =  "";
  2208                             //Edit  the E-mai l body
  2209                             if (is Escalation )
  2210                             {
  2211                                 fo reach (Act ivityParty  ap in ema il.Cc)
  2212                                 {                                 
  2213                                      var user  = srv.Sys temUserSet .FirstOrDe fault(u =>  u.Id == a p.PartyId. Id);
  2214                                      if (user  != null)
  2215                                      {
  2216                                          if ( team != "" )
  2217                                               team += ",  ";
  2218                                          team  += user.F irstName +  " " + use r.LastName ;
  2219                                      }
  2220                                 }
  2221                                 cu stomMessag e = String .Format("{ 0} days ag o, a reque st was sen t to these  people: { 1}, for fe edback to  the Servic e Chief at  the Provi der’s Home  Facility  for PPE pu rposes.<br ><br>This  feedback i s overdue.   Please t ake action  to have t he staff a t our faci lity provi der the re quired inf ormation a s soon as  possible.< br/><br/>T hank you.< br/><br/>" , daysElap sed.ToStri ng("%d"),  team);
  2222                             }
  2223                             
  2224                             custom Message +=  "The foll owing Tele health pro vider’s cl inical wor k is being  reviewed  as part of  a focused  or ongoin g professi onal pract ice evalua tion.<br/> ";
  2225                             custom Message +=  "<b>" + p peReview.c vt_provide r.Name + " ;  " + ppe Review.cvt _specialty .Name + "< /b><br/>";
  2226                             custom Message +=  "<b>" + p rovEmail +  "</b><br/ ><br/>";
  2227  
  2228                             custom Message +=  "As part  of this ev aluation,  we must co llect spec ific infor mation fro m each fac ility wher e the prov ider is de livering T elehealth  services.  Unless alr eady repor ted, the s pecific in formation  needed inc ludes:";
  2229                             custom Message +=  "<ul><li> Any advers e outcomes  related t o the prov ider’s per formance o f their pr ivileges < /li>";
  2230                             custom Message +=  "<li>Any  complaints  about the  provider  from patie nts, staff , etc</li> </ul><br/> <br/>";
  2231  
  2232                             custom Message +=  "As part  of the eva luation, w e area als o interest ed in any  positive f eedback no ted about  the provid er’s clini cal care<b r/><br/>";
  2233  
  2234                             custom Message +=  "Instruct ions and N ext Steps< br/>";
  2235                             custom Message +=  "<ol><li> Click the  following  link to en ter the re porting re cord: " +  link + "</ li>";
  2236                             custom Message +=  "<li>If y ou have so mething to  report, p ositive or  negative,  related t o this pro vider’s pe rformance,  please re cord a “Ye s” and cli ck “Save a nd Close.” <br/>If yo u have not hing to re port,  pos itive or n egative, r elated to  this provi der’s perf ormance, p lease reco rd a “No”  and click  “Save and  Close.” </ li>";
  2237                             custom Message +=  "<li>Your  feedback  will be se nt automat ically  to  the provi der’s Serv ice Chief  at the pro vider’s ho me facilit y (AKA Pri vileging F acility)";
  2238                             custom Message +=  "<ul><li> If you rec orded a “Y es” you wi ll be cont acted by s ecure emai l for your  report.</ li><li>If  you record ed a “No”  no further  action is  needed</l i></ul></o l>";
  2239  
  2240                             
  2241                             //Stan dard email  text
  2242                             custom Message +=  "<br/><br />Thank yo u.<br/><br />This is  an automat ed notific ation from  the Teleh ealth Mana gement Pla tform.";
  2243                             email. Descriptio n = custom Message;
  2244                             if (em ail.To !=  null)
  2245                                 Cv tHelper.Up dateSendEm ail(email,  Organizat ionService );
  2246                         }
  2247                    }
  2248                }
  2249           }
  2250  
  2251           in ternal voi d SendTSAP roviderEma il(Email e mail, Guid  recordId,  string En tityName)
  2252           {
  2253                Logger.W riteDebugM essage("st arting Sen dTSAProvid erEmail");
  2254                if (emai l.Subject. Contains(" Changing p rovider(s)  for telem edicine se rvice"))
  2255                {
  2256                    //Ge t the owne r of the w orkflow fo r the From  field
  2257                    Logg er.WriteDe bugMessage ("Adding t he From");
  2258                    emai l.From = C vtHelper.G etWorkflow Owner("Pri vileging:  PPE Submit ted", Orga nizationSe rvice);
  2259                    usin g (var srv  = new Xrm (Organizat ionService ))
  2260                    {
  2261                         if (Entity Name == cv t_provider resourcegr oup.Entity LogicalNam e)
  2262                         {
  2263                             Logger .WriteDebu gMessage(" EntityName  = cvt_pro viderresou rcegroup") ;
  2264                             var pr g = srv.cv t_provider resourcegr oupSet.Fir stOrDefaul t(p => p.I d == recor dId);
  2265                             var ts a = srv.mc s_services Set.FirstO rDefault(t  => t.Id = = prg.cvt_ RelatedTSA id.Id);
  2266  
  2267                             Logger .WriteDebu gMessage(" Retrieved  prg and ts a");
  2268                             email  = addTSATe amstoEmail (email, ts a);
  2269                         }
  2270                         else if (E ntityName  == mcs_gro upresource .EntityLog icalName)
  2271                         {
  2272                             Logger .WriteDebu gMessage(" EntityName  = mcs_gro upresource ");
  2273                             var gr  = srv.mcs _groupreso urceSet.Fi rstOrDefau lt(g => g. Id == reco rdId);
  2274                             var re latedPRGs  = srv.cvt_ providerre sourcegrou pSet.Where (p => p.cv t_RelatedR esourceGro upid.Id ==  gr.mcs_re latedResou rceGroupId .Id);
  2275                             foreac h (cvt_pro viderresou rcegroup i tem in rel atedPRGs)
  2276                             {
  2277                                 va r tsa = sr v.mcs_serv icesSet.Fi rstOrDefau lt(t => t. Id == item .cvt_Relat edTSAid.Id );
  2278                                 em ail = addT SATeamstoE mail(email , tsa);
  2279                             }
  2280                         }
  2281                         if (email. To != null )
  2282                             CvtHel per.Update SendEmail( email, Org anizationS ervice);
  2283                         else
  2284                             Logger .WriteDebu gMessage(" No users l isted in T O of email .");
  2285                    }
  2286                }
  2287           }
  2288  
  2289           in ternal Ema il addTSAT eamstoEmai l(Email em ail, mcs_s ervices ts a)
  2290           {
  2291                Logger.W riteDebugM essage("St arting add TSATeamsto Email");
  2292                if (tsa  != null)
  2293                {
  2294                    usin g (var srv  = new Xrm (Organizat ionService ))
  2295                    {
  2296                         //Provider
  2297                         List<Team>  FTCTeam =  new List< Team>();
  2298                         List<Team>  SCTeam =  new List<T eam>();
  2299                         FTCTeam =  srv.TeamSe t.Where(p  => p.cvt_F acility.Id  == tsa.cv t_Provider Facility.I d && p.cvt _Type.Valu e == (int) Teamcvt_Ty pe.FTC).Di stinct().T oList();
  2300                         Logger.Wri teDebugMes sage("Retr ieved Prov  FTC Teams : " + FTCT eam.Count) ;
  2301                         SCTeam = s rv.TeamSet .Where(p = > p.cvt_Fa cility.Id  == tsa.cvt _ProviderF acility.Id  && p.cvt_ Type.Value  == (int)T eamcvt_Typ e.ServiceC hief && p. cvt_Servic eType.Id = = tsa.cvt_ servicetyp e.Id).Dist inct().ToL ist();
  2302                         Logger.Wri teDebugMes sage("Retr ieved Prov  SC Teams:  " + SCTea m.Count);
  2303                         //Loop the  results i nto the TO  field
  2304                         foreach (v ar result  in FTCTeam )
  2305                         {
  2306                             email. To = Retri eveFacilit yTeamMembe rs(email,  result.Id,  email.To) ;
  2307                         }
  2308                         Logger.Wri teDebugMes sage("Adde d FTC Team  members t o Email TO .");
  2309                         foreach (v ar result  in SCTeam)
  2310                         {
  2311                             email. To = Retri eveFacilit yTeamMembe rs(email,  result.Id,  email.To) ;
  2312                         }
  2313                         Logger.Wri teDebugMes sage("Adde d SC Team  members to  Email TO. ");
  2314                         if (tsa.cv t_ServiceS cope.Value  == (int)m cs_service scvt_Servi ceScope.In terFacilit y)
  2315                         {
  2316                             Logger .WriteDebu gMessage(" TSA is int erfacility .");
  2317  
  2318                             //Pati ent
  2319                             FTCTea m = srv.Te amSet.Wher e(p => p.c vt_Facilit y.Id == ts a.cvt_Pati entFacilit y.Id && p. cvt_Type.V alue == (i nt)Teamcvt _Type.FTC) .Distinct( ).ToList() ;
  2320                             Logger .WriteDebu gMessage(" Retrieved  Pat FTC Te ams: " + F TCTeam.Cou nt);
  2321                             SCTeam  = srv.Tea mSet.Where (p => p.cv t_Facility .Id == tsa .cvt_Patie ntFacility .Id && p.c vt_Type.Va lue == (in t)Teamcvt_ Type.Servi ceChief &&  p.cvt_Ser viceType.I d == tsa.c vt_service type.Id).D istinct(). ToList();
  2322                             Logger .WriteDebu gMessage(" Retrieved  Pat SC Tea ms: " + SC Team.Count );
  2323  
  2324                             //Loop  the resul ts into th e TO field
  2325                             foreac h (var res ult in FTC Team)
  2326                             {
  2327                                 em ail.To = R etrieveFac ilityTeamM embers(ema il, result .Id, email .To);
  2328                             }
  2329                             foreac h (var res ult in SCT eam)
  2330                             {
  2331                                 em ail.To = R etrieveFac ilityTeamM embers(ema il, result .Id, email .To);
  2332                             }
  2333                         }
  2334                         else
  2335                         {
  2336                             Logger .WriteDebu gMessage(" TSA is int rafacility .");
  2337                         }
  2338                    }
  2339                }
  2340                return e mail;
  2341           }
  2342           #e ndregion
  2343  
  2344           #r egion Impl ementing a dditional  interface  methods
  2345           pu blic overr ide string  McsSettin gsDebugFie ld
  2346           {
  2347                get { re turn "cvt_ serviceact ivityplugi n"; }
  2348           }
  2349           #e ndregion
  2350       }
  2351   }