1. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 12/9/2016 1:46:58 PM Eastern Standard 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_CRM.zip\TMP_CRM\Plugins\VA.TMP.CRM.Plugins\Email EMailCreatePostStageRunner.cs Wed Nov 30 21:47:32 2016 UTC
2 TMP_CRM.zip\TMP_CRM\Plugins\VA.TMP.CRM.Plugins\Email EMailCreatePostStageRunner.cs Wed Dec 7 20:32:54 2016 UTC

1.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 3 3610
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.Xrm. Sdk;
  3   using Micr osoft.Xrm. Sdk.Query;
  4   using Syst em;
  5   using Syst em.Collect ions.Gener ic;
  6   using Syst em.Globali zation;
  7   using Syst em.Linq;
  8   using Syst em.Text;
  9   using VA.T MP.DataMod el;
  10   using VA.T MP.OptionS ets;
  11  
  12   namespace  VA.TMP.CRM
  13   {
  14       public  class EMa ilCreatePo stStageRun ner : Plug inRunner
  15       {         
  16           pu blic EMail CreatePost StageRunne r(IService Provider s erviceProv ider) : ba se(service Provider)  { }
  17           // Declare gl obal varia bles
  18           st ring custo mMessage;
  19           // Emergency  Contact In fo
  20           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;
  21           
  22           st ring Patie ntVirtualM eetingSpac e = string .Empty, Pr oviderVirt ualMeeting Space = st ring.Empty ;
  23           Bo olean isCV TTablet =  false;
  24           cv t_componen t VirtualM eetingSpac e = new cv t_componen t();
  25           st ring steth IP = "";
  26  
  27           #r egion Impl ementation
  28           // / <summary >
  29           // / Called b y PluginRu nner - Dec ide which  email to s end out (a ka which b ranch of t he plugin  to run)
  30           // / </summar y>
  31           pu blic overr ide void E xecute()
  32           {
  33  
  34                Email em ail = (Ema il)Organiz ationServi ce.Retriev e(Email.En tityLogica lName.ToSt ring(), Pr imaryEntit y.Id, new  ColumnSet( true));
  35                if (emai l.Subject. StartsWith ("FW:") ||  email.Sub ject.Start sWith("RE: "))
  36                    retu rn;
  37                if (emai l.mcs_Rela tedService Activity ! = null)
  38                {
  39                    Serv iceAppoint ment relat edAppt = ( ServiceApp ointment)O rganizatio nService.R etrieve(
  40                         ServiceApp ointment.E ntityLogic alName.ToS tring(), e mail.mcs_R elatedServ iceActivit y.Id, new  ColumnSet( true));
  41                    
  42                    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)
  43                    {
  44                         if (email. Subject.St artsWith(" TSS Schedu ler Action :"))
  45                         {
  46                             Logger .WriteDebu gMessage(" Beginning  Vista Remi nder Email ");
  47                             SendVi staReminde r(email);
  48                             Logger .WriteDebu gMessage(" Completed  Vista Remi nder Email ");
  49                         }
  50                         else if (e mail.Subje ct.Contain s("Telehea lth Appoin tment Noti fication f or"))
  51                         {
  52                             Logger .WriteDebu gMessage(" Beginning  Service Ac tivity Not ification  Email");
  53                             Notify Participan tsOfAppoin tment(emai l, related Appt);
  54                             Logger .WriteDebu gMessage(" Completed  Service Ac tivity Not ification  Email");
  55                         }
  56                    }
  57                    //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)
  58                    else  if (email .Regarding ObjectId ! = null &&  email.Rega rdingObjec tId.Logica lName == C ontact.Ent ityLogical Name)
  59                    {
  60                         Logger.Wri teDebugMes sage("Begi nning Pati ent Email" );
  61                         CreateCale ndarAppoin tmentAttac hment(emai l, related Appt, rela tedAppt.St atusCode.V alue, "");
  62                         CvtHelper. UpdateSend Email(emai l, Organiz ationServi ce);
  63                         Logger.Wri teDebugMes sage("Comp leted Pati ent Email" );
  64                    }
  65                    else
  66                         return;
  67                }
  68  
  69                if (emai l.Regardin gObjectId  != null)
  70                {
  71                    Logg er.WriteDe bugMessage ("Beginnin g Send Ema il");
  72                    swit ch (email. RegardingO bjectId.Lo gicalName)
  73                    {
  74                         //Regardin g Object:  TSA
  75                         case mcs_s ervices.En tityLogica lName:
  76                             SendTS AEmail(ema il, email. RegardingO bjectId.Id );
  77                             Logger .WriteDebu gMessage(" Completed  Send TSA E mail");
  78                             break;
  79                         //Regardin g Object:  TSS Privil eging
  80                         case cvt_t ssprivileg ing.Entity LogicalNam e:
  81                             SendPr ivilegingE mail(email , email.Re gardingObj ectId.Id,  email.Rega rdingObjec tId.Logica lName);
  82                             Logger .WriteDebu gMessage(" Completed  Send Privi leging Ema il");
  83                             break;
  84                         //Regardin g Object:  Quality Ch eck
  85                         case cvt_q ualitychec k.EntityLo gicalName:
  86                             SendTr iggerEmail (email, em ail.Regard ingObjectI d.Id, emai l.Regardin gObjectId. LogicalNam e);
  87                             Logger .WriteDebu gMessage(" Completed  FPPE/OPPE  Email");
  88                             break;
  89                    }
  90                }
  91           }
  92  
  93   #endregion
  94  
  95           #r egion Comm only Used  Functions
  96  
  97           // / <summary >
  98           // / Overload  for basic  generateE mailBody -  displays  the url as  the messa ge for "Cl ick Here"
  99           // / </summar y>
  100           // / <param n ame="recor d">ID of t he email</ param>
  101           // / <param n ame="entit yStringNam e">string  name of th e entity -  to retrie ve object  type code< /param>
  102           // / <param n ame="custo mMessage"> The messag e</param>
  103           // / <returns ></returns >
  104           in ternal str ing genera teEmailBod y(Guid rec ord, strin g entitySt ringName,  string cus tomMessage ){
  105                return g enerateEma ilBody(rec ord, entit yStringNam e, customM essage, nu ll);
  106           }
  107  
  108           // / <summary >
  109           // / Standard  "boilerpl ate" E-Mai l body
  110           // / </summar y>
  111           // / <param n ame="recor d">ID of t he email r ecord</par am>
  112           // / <param n ame="entit yStringNam e">The str ing name o f the obje ct type co de</param>
  113           // / <param n ame="custo mMessage"> The custom  string th at goes in to the ema il body</p aram>
  114           // / <param n ame="click HereMessag e">The mes sage that  is used as  the displ ay for the  hyperlink </param>
  115           // / <returns >the body  of the ema il</return s>
  116           in ternal str ing genera teEmailBod y(Guid rec ord, strin g entitySt ringName,  string cus tomMessage , string c lickHereMe ssage)
  117           {
  118                string b ody;
  119                var etc  = CvtHelpe r.GetEntit yTypeCode( Organizati onService,  entityStr ingName);
  120                string s ervernameA ndOrgname  = CvtHelpe r.getServe rURL(Organ izationSer vice);
  121                string u rl = serve rnameAndOr gname + "/ userDefine d/edit.asp x?etc=" +  etc + "&id =" + recor d;
  122                clickHer eMessage =  (clickHer eMessage = = null ||  clickHereM essage ==  string.Emp ty) ? url  : clickHer eMessage;
  123                //Custom  email tex t
  124                //body =  CvtHelper .GetTSSLog o(Organiza tionServic e);
  125                body = " <br/><a hr ef=\"" + u rl + "\">"  + clickHe reMessage  + "</a>";
  126                body +=  "<br/><br/ >" + custo mMessage;
  127                //Standa rd email t ext
  128                body +=  "<br/><br/ >This is a n automate d notifica tion from  the Telehe alth Sched uling Syst em.";
  129                //remove d hyperlin k to main  system win dow - per  Jeff's Req uest 6/2/2 015
  130                //body + = "<br/><a  href=\""  + serverna meAndOrgna me + "\">"  + servern ameAndOrgn ame + "</a >";
  131  
  132                return b ody;
  133           }
  134  
  135           #e ndregion
  136  
  137           // 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)
  138           #r egion Send TSAEmails
  139  
  140           // / <summary >
  141           // / Returns  a string v alue repre senting th e body of  the email  for TSA ap proval not ification
  142           // / </summar y>
  143           // / <param n ame="email ">the obje ct represe nting the  email whic h is being  sent</par am>
  144           // / <param n ame="recor d">the Gui d of the T SA which i s causing  this notif ication to  be sent</ param>
  145           // / <param n ame="entit yStringNam e">the ent ity logica l name of  the tsa (i .e. "mcs_s ervices")< /param>
  146           // / <returns ></returns >
  147           in ternal str ing Approv alEmailBod y(Email em ail)
  148           {
  149  
  150                var appr over = Str ing.Empty;
  151                var next Team = Str ing.Empty;
  152                var FTC  = String.E mpty;
  153                var patF acility =  String.Emp ty;
  154                //Get th e Previous  approvers  by queryi ng most re cent note
  155                using (v ar srv = n ew Xrm(Org anizationS ervice))
  156                {
  157                    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"));
  158                    //mo st recent  approver
  159                    appr over = TSA Note.Creat edBy.Name;
  160                    var  tsa = srv. mcs_servic esSet.Firs tOrDefault (t => t.Id  == email. RegardingO bjectId.Id );
  161                    patF acility =  tsa.cvt_Pa tientFacil ity == nul l ? String .Empty : "  To " + ts a.cvt_Pati entFacilit y.Name;
  162                    if ( tsa.cvt_Se rviceScope .Value ==  917290001)
  163                         patFacilit y = " (Int rafacility )";
  164                    //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)
  165                    swit ch (tsa.st atuscode.V alue)
  166                    {
  167                         case 91729 0002: 
  168                             nextTe am = "Prov ider FTC T eam";
  169                             goto c ase 0;
  170                         case 91729 0000: 
  171                             nextTe am = "Prov ider Servi ce Chief T eam";
  172                             goto c ase 0;
  173                         case 91729 0001: 
  174                             nextTe am = "Prov ider Crede ntialing a nd Privile ging Team" ;
  175                             goto c ase 0;
  176                         case 91729 0008: 
  177                             nextTe am = "Prov ider Chief  of Staff  Team";
  178                             goto c ase 0;
  179                         case 91729 0004: 
  180                             nextTe am = "Pati ent Servic e Chief Te am";
  181                             goto c ase -1;
  182                         case 91729 0005: 
  183                             nextTe am = "Pati ent Creden tialing an d Privileg ing Team";
  184                             goto c ase -1;
  185                         case 91729 0006: 
  186                             nextTe am = "Pati ent Chief  of Staff T eam";
  187                             goto c ase -1;
  188                         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
  189                             FTC =  srv.System UserSet.Fi rstOrDefau lt(u => u. Id == tsa. CreatedBy. Id).FullNa me;
  190                             break;
  191                         case -1: / /If patien t side - g et user wh o first ap proved the  TSA - ass umed to be  the Patie nt FTC
  192                             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")) ;
  193                             FTC =  firstAppro ver.Create dBy.Name;
  194                             break;
  195                    }
  196                }
  197  
  198                //TODO:  Add patien t facility , change s pacing
  199                //get th e FTC for  whichever  side the T SA is awai ting appro val
  200                string h yperlink =  GetTSALin k(email);
  201                  string Ops Manual = " http:// DNS . DNS     /sites/tel ehealth/cv tntc/docs/ user_tsa_a ppr.docx";
  202                  string Rol lOut = "ht tp:// DNS . DNS     /sites/tel ehelpdesk/ TSS%20Roll -Out/defau lt.aspx";
  203                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>" +
  204                    "<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);
  205                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> ");
  206           
  207                return e mailBody +  loginNote s;
  208           }
  209  
  210           // 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)
  211           in ternal voi d SendTSAE mail(Email  email, Gu id tsaID)
  212           {
  213                ////Deni al
  214                //if (em ail.Subjec t.ToLower( ).IndexOf( "denied")  != -1)  // Denial
  215                //    em ail.Descri ption = ge nerateEmai lBody(tsaI D, "mcs_se rvices", " The follow ing Telehe alth Servi ce Agreeme nt has bee n Denied.   Please re view the n otes to se e the Deni al Reason  and correc t any mist akes if ap plicable." , "Click H ere to vie w this TSA ");
  216                //else i f (email.S ubject.ToL ower().Ind exOf("revi sion") !=  -1)  //Rev ision
  217                //    cu stomMessag e = "The f ollowing T elehealth  Service Ag reement is  Under Rev ision.";
  218                ////Remi nder
  219                //else i f (email.S ubject.ToL ower().Ind exOf("acti on") != -1 )  //Remin der
  220                //    cu stomMessag e = "This  is a remin der that t he followi ng Telehea lth Servic e Agreemen t is waiti ng for you  to take a ction.";
  221                ////Appr oval - Pri vileging
  222                //else i f (email.S ubject.ToL ower().Ind exOf("priv ileging")  != -1)  // Approval -  Privilegi ng TODO un able to fi nd this su bject anyw here - val idate it i s still in  use
  223                //    cu stomMessag e = "Click  on the li nk above t o view thi s Teleheal th Service  Agreement  and confi rm Privile ging.";
  224                ////Appr oval
  225                //else i f (email.S ubject.ToL ower().Ind exOf("wait ing") != - 1)  //Appr oval
  226                //    em ail.Descri ption = Ap provalEmai lBody(emai l);
  227                //else i f (email.S ubject.ToL ower().Ind exOf("comp leted") !=  -1)  //Pr oduction N otificatio n Team
  228                //    em ail.Descri ption = TS ANotificat ionText(em ail);
  229                //else i f (email.S ubject.Ind exOf("A TS A to your  Facility h as been cr eated") !=  -1) //Not ify patien t site tha t TSA was  created
  230                //    em ail.Descri ption = ge nerateEmai lBody(tsaI D, "mcs_se rvices", " Please coo rdinate wi th the Pro vider Site  FTC to se t up the f ollowing T SA.  Once  all the de tails are  finalized,  it is the  responsib ility of t he Patient  Site FTC  to begin t he Signatu re collect ion proces s.", "Clic k Here to  view this  TSA");
  231                //else
  232                //    re turn;
  233  
  234                //
  235                switch ( email.Subj ect)
  236                {
  237                    case  "A Telehe alth Servi ce Agreeme nt has bee n denied":  //Denial
  238                         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");
  239                         break;
  240                    case  "TSA unde r revision ": //Revis ion
  241                         customMess age = "The  following  Telehealt h Service  Agreement  is Under R evision.";
  242                         break;
  243                    case  "Please T ake Action  on the fo llowing TS A": //Remi nder
  244                         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.";
  245                         break;
  246                    case  "FYI: A T elehealth  Service Ag reement ha s been com pleted": / /Productio n Notifica tion
  247                         email.Desc ription =  TSANotific ationText( email);
  248                         break;
  249                    case  "A TSA to  your Faci lity has b een create d": //Noti fy patient  site that  TSA was c reated
  250                         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");
  251                         break;
  252                    defa ult:
  253                         if (email. Subject.Co ntains("Te lehealth S ervice Agr eement is  awaiting y our approv al")) //Ap proval
  254                             email. Descriptio n = Approv alEmailBod y(email);
  255                         else
  256                         {
  257                             Logger .WriteToFi le("Unable  to match  email subj ect to val id TSA ema il type, e xiting plu gin");
  258                             return ;
  259                         }
  260                         break;
  261                }
  262                //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
  263                //If can t find tea m members,  log the e rror and c ontinue at tempting t o populate  the messa ge descrip tion
  264                try
  265                {
  266                    emai l.To = Get TeamMember s(email, t saID);
  267                    Logg er.WriteDe bugMessage ("Populate d Email Re cipients") ;
  268                }
  269                catch (E xception e x)
  270                {
  271                    Logg er.WriteTo File(ex.Me ssage);
  272                }
  273                if (emai l.Descript ion == nul l)
  274                    emai l.Descript ion = gene rateEmailB ody(tsaID,  "mcs_serv ices", cus tomMessage , "Click H ere to app rove/deny  this TSA") ;
  275                //Get th e owner of  the workf low for th e From fie ld
  276                if (emai l.From.Cou nt() == 0)
  277                    emai l.From = C vtHelper.G etWorkflow Owner("TSA  Approval  Step 1 - A waiting Pr ov FTC", O rganizatio nService);
  278                Logger.W riteDebugM essage("Se nding TSA  Email");
  279                CvtHelpe r.UpdateSe ndEmail(em ail, Organ izationSer vice);
  280                Logger.W riteDebugM essage("TS A Email Se nt");
  281           }
  282  
  283           in ternal str ing GetTSA Link(Email  email)
  284           {
  285                var etc  = CvtHelpe r.GetEntit yTypeCode( Organizati onService,  mcs_servi ces.Entity LogicalNam e);
  286                string s ervernameA ndOrgname  = CvtHelpe r.getServe rURL(Organ izationSer vice);
  287                string u rl = serve rnameAndOr gname + "/ userDefine d/edit.asp x?etc=" +  etc + "&id =" + email .Regarding ObjectId.I d;
  288                return S tring.Form at("<a hre f=\"{0}\"> {1}</a>",  url, url);
  289           }
  290  
  291           in ternal str ing TSANot ificationT ext(Email  email)
  292           {
  293                  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 TSS . 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:// DNS . DNS     /sites/tel ehelpdesk/ TSS%20Roll -Out/defau lt.aspx")) ;
  294           }
  295  
  296           // / <summary >
  297           // / 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.   
  298           // / </summar y>
  299           // / <param n ame="email ">This is  the email  record tha t is being  built and  eventuall y gets sen t out</par am>
  300           // / <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>
  301           // / <returns >Activity  Party List  correspon ding to Sy stem users  that are  members of  the team< /returns>
  302           in ternal Lis t<Activity Party> Get TeamMember s(Email em ail, Guid  tsaID)
  303           {
  304                //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
  305                var memb ers = new  List<Activ ityParty>( );
  306                var team Members =  new List<T eamMembers hip>();
  307                using (v ar srv = n ew Xrm(Org anizationS ervice))
  308                {
  309                    //Ge t both the  Patient a nd Provide r Facility  to check  for the te ams on bot h sides
  310                    var  tsa = srv. mcs_servic esSet.Firs t(t => t.I d == tsaID );
  311                    var  proFacilit yId = tsa. cvt_Provid erFacility .Id;
  312                    var  patFacilit yId = tsa. cvt_Patien tFacility  != null ?  tsa.cvt_Pa tientFacil ity.Id : G uid.Empty;
  313                    var  team = new  Team();
  314                    swit ch (tsa.st atuscode.V alue)
  315                    {
  316                         case 1: // For Draft  TSAs, send  notificat ion that T SA has bee n created  for their  site. 
  317                             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);
  318                             break;
  319                         case 91729 0002://App roved by P atient Sit e FTC (get  Provider  Site FTC T eam) - Wor kflow Step  1
  320                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == 9172900 00);
  321                             break;
  322                         case 91729 0000://App roved by P rovider Si te FTC (ge t Provider  Service C hief Team)  - Workflo w Step 2
  323                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&
  324                                 t. cvt_Type ! = null &&  t.cvt_Type .Value ==  917290001  && t.cvt_S erviceType .Id == tsa .cvt_servi cetype.Id) ;
  325                             break;
  326                         case 91729 0001://App roved by P rovider Se rvice Chie f (get Pro v C&P Team ) - Workfl ow Step 3
  327                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == 9172900 03);
  328                             break;
  329                         case 91729 0008://App roved by P rovider C& P Team (ge t Prov Chi ef of Staf f Team) -  Workflow S tep 4
  330                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == 9172900 02);
  331                             break;
  332                         case 91729 0004://App roved by P rovider Si te Chief o f Staff (G et Patient  Site Serv ice Chief)  - Workflo w Step 5
  333                             if (pa tFacilityI d != Guid. Empty)
  334                                 te am = srv.T eamSet.Fir stOrDefaul t(t => t.c vt_Facilit y.Id == pa tFacilityI d &&
  335                                      t.cvt_Ty pe != null  && t.cvt_ Type.Value  == 917290 001 && t.c vt_Service Type.Id ==  tsa.cvt_s ervicetype .Id);
  336                             break;
  337                         case 91729 0005://App roved by P atient Sit e Service  Chief (Get  Patient S ite Chief  of Staff)  - Workflow  Step 6
  338                             if (pa tFacilityI d != Guid. Empty)
  339                                 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 == 917 290003);
  340                             break;
  341                         case 91729 0006://App roved by C &P (Get Ch ief of Sta ff Team) -  Workflow  Step 7
  342                             if (pa tFacilityI d != Guid. Empty)
  343                                 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 == 917 290002);
  344                             break;
  345                         case 91729 0007://Get  both side  FTCs whet her it is  in Denied  status or  in Under R evision
  346                         case 91729 0003:
  347                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == 9172900 00);
  348                             if (te am != null )
  349                                 te amMembers  = (List<Te amMembersh ip>)(srv.T eamMembers hipSet.Whe re(t => t. TeamId ==  team.Id).T oList());
  350  
  351                             //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
  352                             if (pa tFacilityI d != Guid. Empty)
  353                             {
  354                                 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 == 917 290000);
  355                                 if  (team !=  null)
  356                                 {
  357                                      if (team Members.Co unt == 0)
  358                                          team Members =  (List<Team Membership >)(srv.Tea mMembershi pSet.Where (t => t.Te amId == te am.Id).ToL ist());
  359                                      else
  360                                          team Members.Ad dRange((Li st<TeamMem bership>)( srv.TeamMe mbershipSe t.Where(t  => t.TeamI d == team. Id).ToList ()));
  361                                 }
  362                             }
  363                             break;
  364                         case 25192 0000: //PR OD - Get B oth sides  notificati on team fo r TSA Noti fication e mail
  365                             team =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == proFac ilityId &&  t.cvt_Typ e != null  && t.cvt_T ype.Value  == 9172900 04);
  366                             if (te am != null )
  367                                 te amMembers  = (List<Te amMembersh ip>)(srv.T eamMembers hipSet.Whe re(t => t. TeamId ==  team.Id).T oList());
  368  
  369                             //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)
  370                             if (pa tFacilityI d != Guid. Empty && p atFacility Id != proF acilityId)
  371                             {
  372                                 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 == 917 290004);
  373                                 if  (team !=  null)
  374                                 {
  375                                      if (team Members.Co unt == 0)
  376                                          team Members =  (List<Team Membership >)(srv.Tea mMembershi pSet.Where (t => t.Te amId == te am.Id).ToL ist());
  377                                      else
  378                                          team Members.Ad dRange((Li st<TeamMem bership>)( srv.TeamMe mbershipSe t.Where(t  => t.TeamI d == team. Id).ToList ()));
  379                                 }
  380                             }
  381                             break;  
  382                    }
  383                    if ( team == nu ll)
  384                         throw new  InvalidPlu ginExecuti onExceptio n("No Team  was found  to receiv e this ema il, please  verify th e team is  set up");
  385                    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
  386                         teamMember s = (List< TeamMember ship>)(srv .TeamMembe rshipSet.W here(t =>  t.TeamId = = team.Id) .ToList()) ;
  387                    fore ach (var m ember in t eamMembers )
  388                    {
  389                         var party  = new Acti vityParty( ){
  390                             Activi tyId = new  EntityRef erence(ema il.Logical Name, emai l.Id),
  391                             PartyI d = new En tityRefere nce(System User.Entit yLogicalNa me, member .SystemUse rId.Value)
  392                         };
  393                         members.Ad d(party);
  394                    }
  395                }
  396                if (memb ers.Count  == 0)
  397                    memb ers.AddRan ge(email.T o);
  398                return m embers;
  399           }
  400  
  401           #e ndregion
  402  
  403           #r egion Send serviceapp ointmentNo tification s
  404  
  405           // / <summary >
  406           // / Primary  function w hich gener ates the S ervice Act ivity noti fication ( including  ical)
  407           // / </summar y>
  408           // / <param n ame="email ">The emai l object c orrespondi ng to the  email reco rd created  which tri ggered thi s plugin</ param>
  409           // / <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 >
  410           in ternal voi d NotifyPa rticipants OfAppointm ent(Email  email, Ser viceAppoin tment rela tedAppt)
  411           {
  412                List<Sys temUser> p roTCTuser  = new List <SystemUse r>();
  413                List<Sys temUser> p atTCTuser  = new List <SystemUse r>();
  414  
  415                //Get th e TSA so y ou can fig ure out wh ether the  resource i s provider  or patien t side
  416                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));
  417  
  418                //Get th e Pro/Pat  Emergency  Info from  TSA
  419                TSAProvE mergency =  tsa.cvt_P roviderSta ffEmergenc yResponsib ilities;
  420                TSAPatEm ergency =  tsa.cvt_Pa tientStaff EmergencyR esponsibil ities;
  421  
  422                if (tsa. cvt_Patien tSiteClini calPOC !=  null)
  423                {
  424                    Guid  TCTonTSA  = tsa.cvt_ PatientSit eClinicalP OC.Id;
  425                    //Ge t the TCTs  Mobile or  Office ph one 
  426                    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") );
  427                    PatT CTPhone =  tct.Mobile Phone;  // Use the TC T number
  428                    PatT CTName = t ct.FirstNa me + " " +  tct.LastN ame;
  429                    PatT CTEmail =  tct.Intern alEMailAdd ress;
  430                    patT CTuser.Add (tct);
  431                    if ( PatTCTPhon e == null)
  432                         PatTCTPhon e = tct.cv t_officeph one;  //Us e the TCT  number
  433                }
  434  
  435                //Get th e Pro TCT
  436                if (tsa. cvt_Provid erSiteClin icalPOC !=  null)
  437                {
  438                    Guid  TCTonTSA  = tsa.cvt_ ProviderSi teClinical POC.Id;
  439                    //Ge t the TCTs  Mobile or  Office ph one 
  440                    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") );
  441                    ProT CTPhone =  tct.Mobile Phone;  // Use the TC T number
  442                    ProT CTName = t ct.FirstNa me + " " +  tct.LastN ame;
  443                    ProT CTEmail =  tct.Intern alEMailAdd ress;
  444                    proT CTuser.Add (tct);
  445                    if ( ProTCTPhon e == null)
  446                         ProTCTPhon e = tct.cv t_officeph one;  //Us e the TCT  number
  447                }
  448                //Pro Le ad TCT
  449                if (ProT CTPhone ==  null) //N o Phone fr om TCT fro m TSA, loo k at Site  specified  one.
  450                {
  451                    if ( tsa.cvt_re latedprovi dersiteid. Id != null ) //Check  for TSA Pr ovider Sit e
  452                    {
  453                         //Get Prov ider Site
  454                         //get the  TSA's rela ted patien t site
  455                         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));
  456  
  457                         if (relate dprosite.c vt_LeadTCT  != null)
  458                         {
  459                             //Get  the Lead T CTs Mobile  or Office  phone 
  460                             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")) ;
  461                             ProTCT Phone = tc t.MobilePh one;  //Us e the TCT  number
  462                             ProTCT Name = tct .FirstName  + " " + t ct.LastNam e;
  463                             ProTCT Email = tc t.Internal EMailAddre ss;
  464                             proTCT user.Clear ();
  465                             proTCT user.Add(t ct);
  466                             if (Pr oTCTPhone  == null)
  467                                 Pr oTCTPhone  = tct.cvt_ officephon e;  //Use  the TCT nu mber
  468                         }
  469                    }
  470                }
  471                //If CVT  to Home,  there is n o patient  site
  472                if ((tsa .cvt_Type  != true) & & (tsa.cvt _groupappo intment !=  true))
  473                {
  474                    //ge t the TSA' s related  patient si te
  475                    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 ));
  476                    //Ge t the Site 's Emergen cy Contact  Info
  477                    if ( relatedpat site.cvt_L ocal911 !=  null)
  478                         SiteLocal9 11Phone =  relatedpat site.cvt_L ocal911; / /Use the L ocal 911
  479                    if ( relatedpat site.cvt_p hone != nu ll)
  480                         SiteMainPh one = rela tedpatsite .cvt_phone ; //Use th e Site Pho ne
  481  
  482                    //Pa t Lead TCT
  483                    if ( PatTCTPhon e == null)  //No Phon e from TCT  from TSA,  look at P at Site sp ecified on e.
  484                    {
  485                         if (relate dpatsite.c vt_LeadTCT  != null)
  486                         {
  487                             //Get  the Lead T CTs Mobile  or Office  phone 
  488                             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")) ;
  489                             PatTCT Phone = tc t.MobilePh one;  //Us e the TCT  number
  490                             PatTCT Name = tct .FirstName  + " " + t ct.LastNam e;
  491                             PatTCT Email = tc t.Internal EMailAddre ss;
  492                             patTCT user.Clear ();
  493                             patTCT user.Add(t ct);
  494                             if (Pa tTCTPhone  == null)
  495                                 Pa tTCTPhone  = tct.cvt_ officephon e;  //Use  the TCT nu mber
  496                         }
  497                    }
  498                }
  499  
  500                //Get th e Pat TCT
  501                //Get th e resource s listed o n the serv ice activi ty
  502                var reso urces = re latedAppt. GetAttribu teValue<En tityCollec tion>("res ources");
  503                EntityCo llection u sers = new  EntityCol lection();
  504                EntityCo llection e quipmentRe sources =  new Entity Collection ();
  505                resource s.Entities .AddRange( GetApptRes ources(rel atedAppt,  string.Emp ty));
  506  
  507                //Get th e users fr om the res ource list  (filter o ut equipme nt)
  508                foreach  (var res i n resource s.Entities )
  509                {
  510                    var  party = re s.ToEntity <ActivityP arty>();
  511                    if ( party.Part yId.Logica lName == S ystemUser. EntityLogi calName)
  512                    {
  513                         ActivityPa rty p = ne w Activity Party()
  514                         {
  515                             PartyI d = new En tityRefere nce(System User.Entit yLogicalNa me, party. PartyId.Id )
  516                         };
  517                         users.Enti ties.Add(p );
  518                    }
  519                    else
  520                    {
  521                         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 "));
  522                         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 ));
  523                         equipmentR esources.E ntities.Ad d(equip);
  524                    }
  525                }
  526  
  527                //Get th e rooms an d techs an d segment  them by pa tient/prov ider site
  528                var tsaP roResource s = getPRG s(tsa.Id,  "provider" );
  529                var tsaP atResource s = getPRG s(tsa.Id,  "patient") ;
  530                var prov iderTechs  = Classify Resources( equipmentR esources,  tsaProReso urces, (in t)mcs_reso urcetype.T echnology) ;
  531                var pati entTechs =  ClassifyR esources(e quipmentRe sources, t saPatResou rces, (int )mcs_resou rcetype.Te chnology);
  532                var prov iderRooms  = Classify Resources( equipmentR esources,  tsaProReso urces, (in t)mcs_reso urcetype.R oom);
  533                var pati entRooms =  ClassifyR esources(e quipmentRe sources, t saPatResou rces, (int )mcs_resou rcetype.Ro om);
  534  
  535                //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 )
  536                var prov iderResour ces = GetR ecipients( users, tsa ProResourc es);
  537                var pati entResourc es = GetRe cipients(u sers, tsaP atResource s);
  538  
  539                //Get pr oviders so  we can pa ss in stri ng for lis t of clini cians to p atient ema il
  540                var clin icians = p roviderRes ources;
  541  
  542                //format  body of t he email ( telepresen ters can b e duplicat ed)
  543                var date  = string. Empty;
  544                var patS ite = tsa. cvt_relate dpatientsi teid;
  545                var patS iteString  = patSite  != null ?  patSite.Na me : strin g.Empty;
  546                patSiteS tring += t sa.cvt_gro upappointm ent.Value  == true ?  tsa.cvt_Pa tientFacil ity.Name :  "Home/Mob ile";
  547                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);
  548                email.Su bject = em ail.Subjec t.Trim() +  " " + pat SiteString  + " " + d ate;
  549                //Combin e the list s and then  add them  as the ema il recipie nts
  550                provider Resources. AddRange(p atientReso urces);
  551  
  552                //Add th e Pro and  Pat TCT to  the .To
  553                provider Resources. AddRange(p roTCTuser) ;
  554                provider Resources. AddRange(p atTCTuser) ;
  555  
  556                email.To  = CvtHelp er.SetPart yList(prov iderResour ces);
  557  
  558                //Get th e owner of  the workf low for th e From fie ld    
  559                if (emai l.From.Cou nt() == 0)
  560                    emai l.From = C vtHelper.G etWorkflow Owner("Ser vice Activ ity Notifi cation", O rganizatio nService);
  561                //Organi zationServ ice.Update (email);
  562  
  563                //Send a  Calendar  Appointmen t if the a ppointment  is schedu led (if ca nceled, se nd cancell ation upda te)
  564                CreateCa lendarAppo intmentAtt achment(em ail, relat edAppt, re latedAppt. StatusCode .Value, st ethIP);
  565                CvtHelpe r.UpdateSe ndEmail(em ail, Organ izationSer vice);
  566  
  567                if (tsa. cvt_Type.V alue == tr ue) // Onl y send pat ient email  for Home/ Mobile TSA s
  568                {
  569                    //Cr eate and S end Email  to Patient /Veteran ( copy sende r from Pro vider Emai l)
  570                    var  providerEm ailSender  = new Enti tyCollecti on();
  571                    prov iderEmailS ender.Enti ties.AddRa nge(email. From);
  572                    Send PatientEma il(related Appt, prov iderEmailS ender, cli nicians);
  573                }
  574           }
  575  
  576           in ternal str ing getPat ientVirtua lMeetingSp ace(Servic eAppointme nt sa, out  bool? pat ientSpace)
  577           {
  578                Logger.W riteDebugM essage("Ge tting Virt ual Meetin g Space");
  579                patientS pace = nul l;
  580                if (sa.m cs_Patient Url != nul l && sa.mc s_provider url != nul l)
  581                {
  582                    Pati entVirtual MeetingSpa ce = sa.mc s_PatientU rl;
  583                    Prov iderVirtua lMeetingSp ace = sa.m cs_provide rurl;
  584                    Logg er.WriteDe bugMessage ("Virtual  Meeting Sp ace is fro m Service  Activity R ecord: " +  PatientVi rtualMeeti ngSpace +  ", " + Pro viderVirtu alMeetingS pace);
  585                }
  586                else
  587                {
  588                    var  patientAP  = sa.Custo mers.First OrDefault( );
  589                    if ( patientAP  == null ||  patientAP .PartyId = = null)
  590                         return str ing.Empty;
  591                    Logg er.WriteDe bugMessage (sa.Custom ers.ToList ().Count() .ToString( ) + " pati ents " + p atientAP.P artyId.Nam e.ToString ());
  592                    var  patient =  (Contact)O rganizatio nService.R etrieve(Co ntact.Enti tyLogicalN ame, patie ntAP.Party Id.Id, new  ColumnSet (true));
  593                    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);
  594                    if ( patient !=  null && p atient.cvt _PatientVi rtualMeeti ngSpace !=  null)
  595                    {
  596                         patientSpa ce = true;
  597                         PatientVir tualMeetin gSpace = p atient.cvt _PatientVi rtualMeeti ngSpace;
  598                         ProviderVi rtualMeeti ngSpace =  patient.cv t_Provider VirtualMee tingSpace;
  599                    }
  600                    else  if (patie nt != null  && patien t.cvt_BLTa blet != nu ll)
  601                    {
  602                         patientSpa ce = false ;
  603                         PatientVir tualMeetin gSpace = p atient.cvt _BLTablet;
  604                         isCVTTable t = true;
  605                    }
  606                    else  if (Virtu alMeetingS pace.Id !=  new Guid( ))
  607                         PatientVir tualMeetin gSpace = V irtualMeet ingSpace.c vt_webinte rfaceurl;
  608                    else
  609                         PatientVir tualMeetin gSpace = " Please Con tact Your  TCT for We b Meeting  Details";
  610                    Logg er.WriteDe bugMessage (PatientVi rtualMeeti ngSpace +  ": Virtual  Meeting S pace is fr om Patient  record =  " + patien tSpace.ToS tring());
  611                }
  612                return P atientVirt ualMeeting Space;
  613           }
  614  
  615           in ternal voi d SendPati entEmail(S erviceAppo intment sa , EntityCo llection F rom, List< SystemUser > provs)
  616           {
  617                if (Virt ualMeeting Space != n ull && Vir tualMeetin gSpace.Id  != Guid.Em pty || Pat ientVirtua lMeetingSp ace.IndexO f("Please  Contact Yo ur") == -1
  618                    // 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
  619                {
  620                    //Ge t the Pati ent and th eir timezo ne
  621                    var  patientAP  = sa.Custo mers.First OrDefault( );
  622                    if ( patientAP  == null)
  623                         Logger.Wri teToFile(" No Patient  was found  to receiv e the emai l for foll owing Serv ice Activi ty: " + sa .Id);
  624                    else
  625                    {
  626                         var recipi ent = new  ActivityPa rty()
  627                         {
  628                             PartyI d = new En tityRefere nce(Contac t.EntityLo gicalName,  patientAP .PartyId.I d)
  629                         };
  630                         Logger.Wri teDebugMes sage("Send ing Patien t Email to  " + patie ntAP.Party Id.Name);
  631                         var patien t = (Conta ct)Organiz ationServi ce.Retriev e(Contact. EntityLogi calName, r ecipient.P artyId.Id,  new Colum nSet(true) );
  632  
  633                         //Setup va riables to  get timeZ one conver sion prope rly
  634                         DateTime t imeConvers ion = sa.S cheduledSt art.Value;
  635                         string ful lDate = st ring.Empty , timeZone sString =  string.Emp ty;
  636                         bool conve rtSuccess  = false, i sCancelled  = (sa.Sta tusCode.Va lue == 9 | | sa.Statu sCode.Valu e == 91729 0000) ? tr ue : false ; //Cancel lation
  637                         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
  638                         timeConver sion = Con vertTimeZo ne(sa.Sche duledStart .Value, ti meZone, ou t timeZone sString, o ut convert Success);
  639                         Logger.Wri teDebugMes sage("Time  converted  to " + ti meZonesStr ing);
  640                         fullDate =  convertSu ccess ? ti meConversi on.ToStrin g("ddd dd  MMM yyyy H H:mm") + "  " + timeZ onesString  : timeCon version.To String("dd d dd MMM y yyy HH:mm" ) + " GMT" ;
  641  
  642                         //Creating  the Subje ct text
  643                         var subjec t = "Your  VA Video V isit has b een ";
  644                         subject +=  (isCancel led) ? "ca nceled" :  "scheduled ";
  645                         subject +=  " for " +  fullDate. Trim();
  646                         Logger.Wri teDebugMes sage("Loca l Time: "  + fullDate );
  647  
  648                         //Getting  the Subjec t Specialt y, Special ty Sub Typ e
  649                         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));
  650                         var servic eText = (t sa.cvt_ser vicetype ! = null) ?  "<b>Specia lty:</b> "  + tsa.cvt _servicety pe.Name +  "<br />" :  "";
  651                         serviceTex t += (tsa. cvt_servic esubtype ! = null) ?  "<b>Specia lty Sub Ty pe:</b> "  + tsa.cvt_ servicesub type.Name  + "<br />"  : "";
  652  
  653  
  654                         var clinic ians = str ing.Empty;
  655                         foreach (S ystemUser  user in pr ovs)
  656                         {
  657                             clinic ians += us er.FullNam e + "; ";
  658                         }
  659                         if (clinic ians != st ring.Empty )
  660                             clinic ians = "<b >Clinician :</b> " +  clinicians .Remove(cl inicians.L ength - 2)  + "<br /> ";
  661  
  662                         //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
  663                         var meetin gSpace = P atientVirt ualMeeting Space.Inde xOf("Pleas e Contact  Your") ==  -1 ?
  664                             CvtHel per.buildH TMLUrl(Pat ientVirtua lMeetingSp ace, "Clic k Here to  Join the V irtual Mee ting")
  665                             : "<b> Your virtu al meeting  room was  not found,  " + Patie ntVirtualM eetingSpac e + "</b>" ;
  666  
  667                         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 meeting.   This wil l take you  into the  virtual wa iting room  until you r provider  joins.<br  />";
  668  
  669                         //Set up d ifference  in Schedul ed vs Canc elation te xt
  670                         var descrS tatus = "r eminder of  your";
  671                         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 .";
  672                         if (isCanc elled) //C anceled
  673                         {
  674                             descrS tatus = "c ancelation  notice fo r your pre viously sc heduled";
  675                             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." ;
  676                             dynami cBody = "" ;
  677                             meetin gSpace = " ";
  678                         }
  679  
  680                         var descri ption = St ring.Forma t("This is  a {0} Vid eo Visit w ith a VA c linician o n <b>{1}</ b>. {2}{3} <br /><br  />{4}{5}<b r />If you  have any  questions  or concern s, please  contact yo ur clinic.  <br />{6} ",
  681                             descrS tatus,
  682                             fullDa te,
  683                             dynami cBody,
  684                             (!isCV TTablet ?  meetingSpa ce : ""),
  685                             servic eText,
  686                             clinic ians,
  687                             attach mentText);
  688                         Email pati entEmail =  new Email ()
  689                         {
  690                             Subjec t = subjec t,
  691                             Descri ption = de scription,
  692                             mcs_Re latedServi ceActivity  = new Ent ityReferen ce(Service Appointmen t.EntityLo gicalName,  sa.Id),
  693                             Regard ingObjectI d = new En tityRefere nce(Contac t.EntityLo gicalName,  patientAP .PartyId.I d),
  694                             From =  CvtHelper .GetWorkfl owOwner("S ervice Act ivity Noti fication",  Organizat ionService )
  695                         };
  696                         patientEma il.To = Cv tHelper.Se tPartyList (recipient );
  697  
  698                         Organizati onService. Create(pat ientEmail) ;
  699                         Logger.Wri teDebugMes sage("Pati ent Email  Created Su ccessfully ");
  700                    }
  701                }
  702                else
  703                    Logg er.WriteTo File("No V MR informa tion could  be found" );
  704           }
  705  
  706           pu blic DateT ime Conver tTimeZone( DateTime d ate, int C RMTimeZone Code, out  string tim eZonesStri ng, out bo ol success )
  707           {
  708                success  = false;
  709                timeZone sString =  string.Emp ty;
  710                try
  711                {
  712                    Logg er.WriteDe bugMessage ("Converti ng Time to  Appropria te Time Zo ne");
  713                    usin g (var srv  = new Xrm (Organizat ionService ))
  714                    {
  715                         var timeZo nerecord =  srv.TimeZ oneDefinit ionSet.Fir stOrDefaul t(t => t.T imeZoneCod e != null  && t.TimeZ oneCode.Va lue == CRM TimeZoneCo de);
  716                         timeZonesS tring = ti meZonereco rd.Standar dName;
  717                    }
  718                    var  timeZoneCo de = TimeZ oneInfo.Fi ndSystemTi meZoneById (timeZones String);
  719                    var  localTime  = TimeZone Info.Conve rtTimeFrom Utc(date,  timeZoneCo de);
  720                    succ ess = true ;
  721                    retu rn localTi me;
  722                }
  723                catch (T imeZoneNot FoundExcep tion ex)
  724                {
  725                    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" );
  726                }
  727                catch (E xception e x)
  728                {
  729                    Logg er.WriteTo File("Time  Zone conv ersion iss ue" + ex.M essage + "  ; using U TC instead ");
  730                }
  731                return d ate;
  732           }
  733  
  734           // / <summary >
  735           // / This met hod create s the .ics  attachmen t and appe nds it to  the email
  736           // / </summar y>
  737           // / <param n ame="email ">This is  the email  that the a ttachment  is attachi ng to</par am>
  738           // / <param n ame="sa">T he service  appointme nt which < /param>
  739           // / <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>
  740           in ternal voi d CreateCa lendarAppo intmentAtt achment(Em ail email,  ServiceAp pointment  sa, int st atusCode,  string ste thIP)
  741           {
  742                bool gro up = false ;
  743                if (sa.m cs_groupap pointment  != null)
  744                {
  745                    grou p = sa.mcs _groupappo intment.Va lue;
  746                }
  747                Logger.W riteTxnTim ingMessage ("Begin Cr eating Cal endar Appo intment");
  748                string s chLocation  = "See De scription" ;
  749                string s chSubject  = group ==  true ? "T elehealth  Visit-Grou p Appointm ent: Do No t Reply" :  
  750                    "Tel ehealth Vi sit-Single  Appointme nt: Do Not  Reply";
  751                string s chDescript ion = emai l.Descript ion;
  752                System.D ateTime sc hBeginDate  = (System .DateTime) sa.Schedul edStart;
  753                System.D ateTime sc hEndDate =  (System.D ateTime)sa .Scheduled End;
  754                string s equence =  "";
  755                string s tatus = "C ONFIRMED";
  756                string m ethod = "" ;
  757                //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
  758                if (stat usCode ==  9 || statu sCode == 9 17290000)
  759                {
  760                    meth od = "METH OD:CANCEL\ n";
  761                    sequ ence = "SE QUENCE:1\n ";
  762                    stat us = "CANC ELLED";
  763                    schS ubject = " Canceled:  Telehealth  Visit: Do  Not Reply ";
  764                }
  765  
  766                //attach  a ClearSt eth CVL fi le if a st eth is in  the compon ents
  767                string c vlAtttachm ent = stri ng.IsNullO rEmpty(ste thIP) ? ""  :
  768                    "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";
  769    
  770                string a tt =  "BEG IN:VCALEND AR\n"+
  771                                    "PRODID:-/ /VA//Veter ans Affair s//EN\n"+
  772                                    method +
  773                                    "BEGIN:VEV ENT\n"+
  774                                    cvlAtttach ment +
  775                                    "UID:" + s a.Id + "\n " + sequen ce + 
  776                                    "DTSTART:"  + schBegi nDate.ToUn iversalTim e().ToStri ng("yyyyMM dd\\THHmms s\\Z")+"\n "+
  777                                    "DTEND:" +  schEndDat e.ToUniver salTime(). ToString(" yyyyMMdd\\ THHmmss\\Z ")+"\n"+
  778                                    "LOCATION: " + schLoc ation +
  779                                    //Use Desc ription ta g for emai l clients  that cant  handle x-a lt-desc ta g with HTM L
  780                                    "\nDESCRIP TION;ENCOD ING=QUOTED -PRINTABLE :" + schDe scription. Replace("< br/>", "") .Replace(" <b>", ""). Replace("< /b>", ""). Replace("< u>", "").R eplace("</ u>", "") +
  781                                    "\nSUMMARY :" + schSu bject + "\ nPRIORITY: 3\n" +
  782                                    "STATUS:"  + status +  "\n" +
  783                                    //Include  alternate  descriptio n if the c alendar cl ient can h andle html  x-alt-des c tag
  784                                    "X-ALT-DES C;FMTTYPE= text/html: <html>"+ s chDescript ion.Replac e("\n","<b r/>") +"</ html>" + " \n" +
  785                                    //"ATTACH: invitation .cvl\n" +
  786                               "END :VEVENT\n"  + "END:VC ALENDAR\n" ;
  787  
  788                Activity MimeAttach ment calen darAttachm ent = new  ActivityMi meAttachme nt()
  789                {
  790                    Obje ctId = new  EntityRef erence(Ema il.EntityL ogicalName , email.Id ),
  791                    Obje ctTypeCode  = Email.E ntityLogic alName,
  792                    Subj ect = stri ng.Format( "Telehealt h Visit"),
  793                    Body  = Convert .ToBase64S tring(
  794                             new AS CIIEncodin g().GetByt es(att)),
  795                    File Name = str ing.Format (CultureIn fo.Current Culture, " Telehealth -Appointme nt.ics"),
  796                    
  797                };
  798                Organiza tionServic e.Create(c alendarAtt achment);
  799                Logger.W riteTxnTim ingMessage ("Finished  Creating  Calendar A ppointment ");
  800                return;
  801           }
  802  
  803           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,
  804                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)
  805           {
  806                Logger.W riteDebugM essage("St arting For matting Em ail Body") ;
  807                converte dDate = st ring.Empty ;
  808                string e mailBody =  "";
  809                string p roviderTec hsString =  "";
  810                string p atientTech sString =  null;
  811                string p roviderRoo msString =  null;
  812                string p atientRoom sString =  null;
  813                string t elepresent ersString  = null;
  814                string p rovidersSt ring = nul l;
  815                string D EALicensed  = "";
  816  
  817                //DEA Li censed
  818                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." :  "";
  819  
  820                foreach  (mcs_resou rce r in p roviderTec hs)
  821                {
  822                    prov iderTechsS tring += r .mcs_name;
  823                    if ( r.cvt_rela teduser !=  null)
  824                    {
  825                         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") );
  826                         providerTe chsString  += "; POC  Name: " +  poc.FullNa me + "; ";
  827                         var phone  = poc.Mobi lePhone ==  null ? po c.cvt_offi cephone :  poc.Mobile Phone;
  828  
  829                         //If TSA i s telework  (true), t hen add th at number  here as we ll.
  830                         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 +  ";" : "";
  831                         providerTe chsString  += (phone  != null) ?  "POC Phon e #: " + p hone : "";                 
  832                    }
  833                    prov iderTechsS tring += " <br/>";
  834                    prov iderTechsS tring += g etComponen ts(r, sa);
  835                }
  836  
  837                foreach  (mcs_resou rce r in p atientTech s)
  838                {
  839                    pati entTechsSt ring += r. mcs_name;
  840                    if ( r.cvt_rela teduser !=  null)
  841                    {
  842                         SystemUser  poc = (Sy stemUser)O rganizatio nService.R etrieve(
  843                             System User.Entit yLogicalNa me, r.cvt_ relateduse r.Id, new  ColumnSet( "fullname" , "mobilep hone", "cv t_officeph one"));
  844                         patientTec hsString + = "; POC N ame: " + p oc.FullNam e + "; ";
  845                         var phone  = poc.Mobi lePhone ==  null ? po c.cvt_offi cephone :  poc.Mobile Phone;
  846                         patientTec hsString + = "POC Pho ne #: " +  phone;
  847                    }
  848                    pati entTechsSt ring += "< br/>";
  849                    pati entTechsSt ring += ge tComponent s(r, sa);
  850                }
  851  
  852                foreach  (mcs_resou rce r in p roviderRoo ms)
  853                {
  854                    prov iderRoomsS tring += " <b><u>Room :</u></b>  " + r.mcs_ name;
  855                    if ( r.cvt_phon e != null)
  856                         ProRoom +=  (ProRoom  == null) ?  r.cvt_pho ne : ", "  + r.cvt_ph one;
  857                             
  858                    prov iderRoomsS tring += " <br/>";
  859                }
  860  
  861                foreach  (mcs_resou rce r in p atientRoom s)
  862                {
  863                    pati entRoomsSt ring += "< b><u>Room: </u></b> "  + r.mcs_n ame;
  864                    if ( r.cvt_phon e != null)
  865                    {
  866                         PatRoom +=  (PatRoom  == null) ?  r.cvt_pho ne : ", "  + r.cvt_ph one;
  867                    }
  868                    if ( DEALicense d == "" &&  r.mcs_Rel atedSiteId  != null)  {                      
  869                         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)) ;
  870  
  871                         if (resour ceSite.cvt _DEALicens ed != null  && resour ceSite.cvt _DEALicens ed.Value = = true)
  872                             patien tRoomsStri ng += ";   <u><b>Note : The pati ent care s ite is DEA  registere d.</u></b> ";
  873                         else
  874                             patien tRoomsStri ng += ";   <u><b>Note : The pati ent care s ite is NOT  DEA regis tered.</u> </b>";
  875                    }
  876                    pati entRoomsSt ring += "< br/>";
  877                }
  878  
  879                foreach  (SystemUse r t in tel epresenter s)
  880                {
  881                    var  phone = t. cvt_office phone != n ull ? t.cv t_officeph one : t.Mo bilePhone;
  882                    tele presenters String +=  "<b><u>Tel epresenter :</u></b>  " + t.Full Name + ":  " + phone  + "<br/>";
  883                }
  884                foreach  (SystemUse r t in pro viders)
  885                {
  886                    var  phone = t. cvt_office phone != n ull ? t.cv t_officeph one : t.Mo bilePhone;
  887                    prov idersStrin g += "<b>< u>Provider :</u></b>  " + t.Full Name;
  888                    prov idersStrin g += (phon e != null)  ? "; Phon e: " + pho ne : "";
  889                    
  890                    //If  TSA is te lework (tr ue), then  add that n umber here  as well.
  891                    if ( (tsa.cvt_P roviderLoc ationType  != null) & & (tsa.cvt _ProviderL ocationTyp e.Value ==  true))
  892                    {
  893                         //Check us er for tel ework numb er                   
  894                         providersS tring += ( t.cvt_Tele workPhone  != null) ?  "; Telewo rk Phone:  " + t.cvt_ TeleworkPh one + ";"  : "";
  895                        
  896                    }
  897                    prov idersStrin g += "<br/ >";
  898                }
  899  
  900               
  901  
  902                Logger.W riteDebugM essage("Ge tting Time  Zone to c onvert Str ing");
  903                var proS iteId = sa .mcs_relat edprovider site;
  904                int proS iteTimeZon e = 35;
  905                if (proS iteId != n ull)
  906                {
  907                    usin g (var srv  = new Xrm (Organizat ionService ))
  908                    {
  909                         var site =  srv.mcs_s iteSet.Fir stOrDefaul t(s => s.I d == proSi teId.Id);
  910                         if (site ! = null)
  911                             proSit eTimeZone  = site.mcs _TimeZone  != null ?  site.mcs_T imeZone.Va lue : proS iteTimeZon e;
  912                    }
  913                }
  914                var conv ersionSucc ess = fals e;
  915                var time ZoneString  = string. Empty; //t his will b e retrieve d in Conve rtTimeZone
  916                var conv ertedTime  = ConvertT imeZone(sa .Scheduled Start.Valu e, proSite TimeZone,  out timeZo neString,  out conver sionSucces s);
  917                var full Date = con versionSuc cess ? con vertedTime .ToString( "ddd dd MM M yyyy HH: mm") + " "  + timeZon eString :  convertedT ime.ToStri ng("ddd dd  MMM yyyy  HH:mm") +  " GMT";
  918                converte dDate = fu llDate;
  919                Logger.W riteDebugM essage(str ing.Format ("Converte d Time Zon e to {0}",  timeZoneS tring));
  920  
  921                if (sa.S tatusCode. Value == 9  || sa.Sta tusCode.Va lue == 917 290000)
  922                {
  923                    emai lBody += " This is an  automated  Message t o notify y ou that a  Telehealth  Appointme nt previou sly schedu led for "  + fullDate  +
  924                    "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 .  " +
  925                    "The  Details a re listed  below: <br /><br/>";
  926                }
  927                else if  (sa.Status Code.Value  == 4)
  928                {
  929                    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> " +
  930                         "for " + f ullDate +  ".  " + 
  931                         "Please op en the att achment an d click \" Save and C lose\" to  add this e vent to yo ur calenda r.  " +
  932                         "The Detai ls are lis ted below:  <br/><br/ >";
  933                }
  934  
  935                //Provid er Info
  936                emailBod y += "<br/ ><font siz e='5' colo r='blue'>P rovider Si te Informa tion:</fon t><br/>";
  937                emailBod y += provi derRoomsSt ring;
  938                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
  939                emailBod y += (!Str ing.IsNull OrEmpty(pr oviderTech sString))  ? "<br/><b ><u>Techno logies: </ u></b><br/ > " + prov iderTechsS tring + "< br/>" : "" ;
  940                emailBod y += provi dersString ;
  941                emailBod y += (TSAP rovEmergen cy != "")  ? "<u><b>P rovider Si te Emergen cy Respons ibilities: </u></b><b r/> " + TS AProvEmerg ency + "<b r/>" : "";
  942  
  943                if ((Pro Room != nu ll) || (Pr oTCTPhone  != null &&  ProTCTNam e != null) )
  944                {
  945                    emai lBody += " <u><b>Tele phone Cont act Inform ation:</u> </b><br/>  <ul>";
  946                    emai lBody += ( ProRoom !=  null) ? " <li>To dir ect dial t he room: "  + ProRoom  + "</li>"  : "";
  947                    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/>" : "";
  948                    emai lBody += " </ul>";
  949                }
  950  
  951                //Patien t Info
  952                if (tsa. cvt_Type ! = true)
  953                {
  954                    emai lBody += " <br/><font  size='5'  color='blu e'>Patient  Site Info rmation:</ font><br/> ";
  955                    emai lBody += p atientRoom sString;
  956                    emai lBody += ( tsa.cvt_pa tsitevista clinics !=  null) ? " <b><u>Vist a Clinic:< /u></b> "  + tsa.cvt_ patsitevis taclinics. ToString()  + "<br/>"  : "";
  957                    emai lBody += ( !String.Is NullOrEmpt y(patientT echsString )) ? "<b>< u>Technolo gies: </u> </b><br/>"  + patient TechsStrin g + "<br/> " : "";
  958                    emai lBody += t elepresent ersString;
  959                    emai lBody += ( TSAPatEmer gency != " ") ? "<b>< u>Patient  Site Emerg ency Respo nsibilitie s:</u></b> <br/> " +  TSAPatEmer gency + "< br/>" : "" ;
  960                    
  961                    if ( (PatRoom ! = null) ||  (SiteMain Phone != n ull) || (S iteLocal91 1Phone !=  null) || ( PatTCTPhon e != null  && PatTCTN ame != nul l))
  962                    {
  963                         emailBody  += "<u><b> Telephone  Contact In formation: </u></b><b r/> <ul>";
  964                         emailBody  += (PatRoo m != null)  ? "<li>To  direct di al the roo m: " + Pat Room + "</ li>" : "";
  965                         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> " : "";
  966                         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> " : "";
  967                         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>" :  "";
  968                         emailBody  += "</ul>" ;
  969                    }
  970                }
  971                else  // Condition  for CVT to  Home
  972                {            
  973                    bool ? patient  = null;
  974                    var  meetingSpa ce = getPa tientVirtu alMeetingS pace(sa, o ut patient );
  975  
  976                    emai lBody += " <br/><br/> <font size ='5' color ='blue'>Ho me/Mobile  Informatio n:</font>< br/>";
  977                    emai lBody += ( DEALicense d != "") ?  "<u><b>Si te DEA Lic ensed:</u> </b><br/>  " + DEALic ensed + "< br/>" : "" ;
  978                    emai lBody += ( patient ==  false) ?  "<br/> Pat ient CVT T ablet: <br />" : "<br /> Virtual  Meeting S pace: <br/ >";
  979  
  980                    if ( meetingSpa ce == stri ng.Empty)
  981                         meetingSpa ce = "Plea se Contact  Your Clin ician for  Web Meetin g Details" ;
  982  
  983                    //Ch ange to re ad the Pro viderVirtu alMeetingS pace on th e patient  record.
  984                    // 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  
  985                    if ( patient ==  true || P roviderVir tualMeetin gSpace !=  string.Emp ty)
  986                    {
  987                         emailBody  += "From y our Web br owser: " +  CvtHelper .buildHTML Url(Provid erVirtualM eetingSpac e, Provide rVirtualMe etingSpace ) + "<br/> ";
  988  
  989                         var conf =  getParamV alue(Provi derVirtual MeetingSpa ce, "confe rence=");
  990                         var cid =  getParamVa lue(Provid erVirtualM eetingSpac e, "pin=") ;
  991  
  992                         if (!strin g.IsNullOr Empty(conf ) && !stri ng.IsNullO rEmpty(cid ) )
  993                             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);
  994                    }
  995                    else
  996                         emailBody  += meeting Space + "< br/>";
  997                }
  998                emailBod y += "<br/ ><br/>Plea se Do Not  Reply to t his messag e.  It com es from an  unmonitor ed mailbox .";
  999  
  1000                Logger.W riteDebugM essage("Fi nishing Fo rmatting E mail Body" );
  1001                return e mailBody;
  1002           }
  1003  
  1004           in ternal str ing getPar amValue(st ring url,  string key )
  1005           {
  1006                var resu lt = strin g.Empty;
  1007                var para meter = ur l.Split('& ').LastOrD efault(s = > s.ToLowe r().Contai ns(key));
  1008                var para meterKeyVa lue = para meter != n ull ? para meter.Spli t('=') : n ull;
  1009                if (para meterKeyVa lue != nul l && param eterKeyVal ue.Count()  == 2)
  1010                    resu lt = param eterKeyVal ue[1];
  1011                return r esult;
  1012           }
  1013  
  1014           in ternal str ing getCom ponents(mc s_resource  technolog y, Service Appointmen t SA)
  1015           {
  1016                //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
  1017                //virtua lMeetingSp ace = null ;
  1018                string c omponents  = null; 
  1019                using (v ar context  = new Xrm (Organizat ionService ))
  1020                {
  1021                    var  compList =  context.c vt_compone ntSet.Wher e(c => c.c vt_related resourceid .Id == tec hnology.Id );
  1022                    fore ach (cvt_c omponent c  in compLi st)
  1023                    {
  1024                         if (compon ents == nu ll)
  1025                             compon ents += "< ul>";
  1026                         components  += "<li>"  + c.cvt_n ame;
  1027                         switch (c. cvt_name)
  1028                         {
  1029                             case " Codec, Har dware":
  1030                                 if  (c.cvt_ce vnalias !=  null)
  1031                                      componen ts += "; C EVN Alias:  " + c.cvt _cevnalias ;
  1032                                 br eak;
  1033                             case " Telemedici ne Encount er Managem ent":
  1034                             case " Telemed En counter Ma nagement":
  1035                             case " TEMS (Tele medicine E ncounter M anagement  Software)" :
  1036                             case " TEMS (Tele med Encoun ter Manage ment Softw are)":
  1037                                 if  (c.cvt_ip address !=  null)
  1038                                      componen ts += "; I P Address:  " + CvtHe lper.build HTMLUrl(c. cvt_ipaddr ess);
  1039                                 br eak;
  1040                             case " CVT Patien t Tablet":
  1041                                 if  (c.cvt_se rialnumber  != null)
  1042                                      componen ts += "; S erial Numb er: " + c. cvt_serial number;
  1043                                 br eak;
  1044                             case " Virtual Me eting Spac e":
  1045                                 Vi rtualMeeti ngSpace =  c;
  1046                                 br eak;
  1047                             case " Digital St ethoscope  Peripheral ":
  1048                                 st ethIP = c. cvt_ipaddr ess;
  1049                                 br eak;
  1050                         }
  1051                         //Send URL
  1052                         var url =  "";
  1053                         var contac t = getDum myContact( );
  1054                         var second aryEntitie s = new Li st<Entity> ();
  1055                         secondaryE ntities.Ad d(SA);
  1056                         secondaryE ntities.Ad d(contact) ;
  1057                         if (UrlBui lder.TryGe tUrl(Organ izationSer vice, this .GetType() .ToString( ), c, seco ndaryEntit ies, out u rl))
  1058                             compon ents += ";  <a href="  + url + " >" + url +  "</a>";
  1059                         components  += "</li> ";                      
  1060                    }
  1061                    if ( components  != null)
  1062                         components  += "</ul> ";
  1063                }
  1064                return c omponents;         
  1065           }
  1066  
  1067           in ternal Con tact getDu mmyContact ()
  1068           {
  1069                Contact  c = new Co ntact();
  1070                using (v ar srv = n ew Xrm(Org anizationS ervice)){
  1071                    c =  srv.Contac tSet.First OrDefault( );
  1072                }
  1073                return c ;
  1074           }
  1075  
  1076           in ternal Lis t<Entity>  getPRGs(Gu id tsaId,  string loc ation)
  1077           {
  1078                QueryByA ttribute q a = new Qu eryByAttri bute("cvt_ "+location +"resource group");
  1079                qa.Colum nSet = new  ColumnSet ("cvt_tsar esourcetyp e", "cvt_r elateduser id", "cvt_ relatedres ourcegroup id", "cvt_ relatedres ourceid");
  1080                qa.AddAt tributeVal ue("cvt_re latedtsaid ", tsaId);
  1081                var resu lts = Orga nizationSe rvice.Retr ieveMultip le(qa);
  1082                return r esults.Ent ities.ToLi st();
  1083           }
  1084  
  1085           // if patient OrProvider  == 1, the n get prov ider resou rces, othe rwise get  patient re sources
  1086           in ternal Ent ityCollect ion getPRG s(mcs_serv ices tsa,  int? patie ntOrProvid er)
  1087           {
  1088                EntityCo llection P RGCollecti on = new E ntityColle ction();
  1089                using (v ar context  = new Xrm (Organizat ionService )){
  1090                    if ( patientOrP rovider ==  1)
  1091                    {
  1092                         var ProvRG s = contex t.cvt_prov iderresour cegroupSet .Where(prg  => prg.cv t_RelatedT SAid.Id ==  tsa.Id);
  1093                         foreach (v ar res in  ProvRGs)
  1094                             PRGCol lection.En tities.Add (res);
  1095                    }
  1096                    else
  1097                    {
  1098                         var PatRGs  = context .cvt_patie ntresource groupSet.W here(prg = > prg.cvt_ RelatedTSA id.Id == t sa.Id);
  1099                         foreach (v ar res in  PatRGs)
  1100                             PRGCol lection.En tities.Add (res);
  1101                    }
  1102                }
  1103                return P RGCollecti on;
  1104           }
  1105  
  1106           // / <summary >
  1107           // / looks to  find a gr oup resour ce record  for the gr oup and us er listed
  1108           // / </summar y>
  1109           // / <param n ame="user" >user Id o f the grou p resource </param>
  1110           // / <param n ame="group ">group id  of the gr oup resour ce</param>
  1111           // / <returns >true if a  record ex ists for t he group p assed in a nd the use r passed i t</returns >
  1112           in ternal boo l MatchRes ourceToGro up(Guid us erId, Guid  groupId)
  1113           {
  1114                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1115                    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;
  1116           }
  1117  
  1118           // / <summary >
  1119           // / looks to  find a gr oup resour ce record  for the gr oup and re source lis ted
  1120           // / </summar y>
  1121           // / <param n ame="resou rce">resou rce record  of the gr oup resour ce</param>
  1122           // / <param n ame="group ">resource  record of  the group  resource< /param>
  1123           // / <returns >true if a  record ex ists for t he group p assed in a nd the res ource pass ed it</ret urns>
  1124  
  1125           in ternal boo l MatchRes ourceToGro up(mcs_res ource reso urce, mcs_ resourcegr oup group)
  1126           {
  1127                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1128                    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;
  1129           }
  1130  
  1131           // / <summary >
  1132           // / returns  the list o f users ba sed on the  location  (provider  or patient ) and 
  1133           // / </summar y>
  1134           // / <param n ame="users ">list of  user activ ity partie s in the S A.Resource s field</p aram>
  1135           // / <param n ame="locat ion">"pati ent" or "p rovider"</ param>
  1136           // / <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>
  1137           // / <returns ></returns >
  1138           in ternal Lis t<SystemUs er> GetRec ipients(En tityCollec tion users , List<Ent ity> prgs)
  1139           {
  1140                List<Sys temUser> r ecipients  = new List <SystemUse r>();
  1141                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 ();
  1142                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() ;
  1143  
  1144                foreach  (var singl ePRG in si ngles)
  1145                {
  1146                    if ( singlePRG. Attributes .Contains( "cvt_relat eduserid")  && single PRG.Attrib utes["cvt_ relateduse rid"] != n ull)
  1147                    {
  1148                         SystemUser  singleUse r = (Syste mUser)Orga nizationSe rvice.Retr ieve(Syste mUser.Enti tyLogicalN ame,
  1149                             ((Enti tyReferenc e)singlePR G.Attribut es["cvt_re lateduseri d"]).Id, n ew ColumnS et(true));
  1150                         if (single User != nu ll && sing leUser.Id  != Guid.Em pty)
  1151                         {
  1152                             foreac h (Activit yParty u i n users.En tities)
  1153                             {
  1154                                 if  (singleUs er.Id == u .PartyId.I d)
  1155                                 {
  1156                                      recipien ts.Add(sin gleUser);
  1157                                      break;
  1158                                 }
  1159                             }
  1160                         }
  1161                    }
  1162                }
  1163                foreach  (var group PRG in gro ups)
  1164                {
  1165                    if ( groupPRG.A ttributes. Contains(" cvt_relate dresourceg roupid") & & groupPRG .Attribute s["cvt_rel atedresour cegroupid" ] != null)
  1166                    {
  1167                         mcs_resour cegroup gr oup = (mcs _resourceg roup)Organ izationSer vice.Retri eve(
  1168                                 mc s_resource group.Enti tyLogicalN ame, ((Ent ityReferen ce)groupPR G.Attribut es["cvt_re latedresou rcegroupid "]).Id, ne w ColumnSe t(true));
  1169                         //if group  type valu e is any o f the "use r-type" gr oups (prov ider or al l required  or telepr esenter)
  1170                         if ((group .mcs_Type. Value == ( int)mcs_re sourcetype .Provider)  || (group .mcs_Type. Value == ( int)mcs_re sourcetype .AllRequir ed) || 
  1171                             (group .mcs_Type. Value == ( int)mcs_re sourcetype .Teleprese nterImager ))
  1172                         {
  1173                             //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
  1174                             foreac h (Activit yParty u i n users.En tities)
  1175                             {
  1176                                 va r user = ( SystemUser )Organizat ionService .Retrieve( SystemUser .EntityLog icalName,  u.PartyId. Id, new Co lumnSet(tr ue));
  1177                                 if  (MatchRes ourceToGro up(user.Id , group.Id ))
  1178                                      recipien ts.Add(use r);
  1179                             }
  1180                         }
  1181                    }
  1182                }
  1183                return r ecipients;
  1184           }
  1185  
  1186           // 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
  1187           in ternal Ent ityCollect ion GetRec ipients(En tityCollec tion users , int? use rType, mcs _services  tsa)
  1188           {
  1189                EntityCo llection p roviders =  new Entit yCollectio n();
  1190  
  1191                foreach  (ActivityP arty u in  users.Enti ties)
  1192                {
  1193                    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));
  1194  
  1195                    //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
  1196                    //ot herwise lo ok for a r esource gr oup that c ontains th e user
  1197                    //if  userType  is null, r eturn prov iders, if  0 - return  both (pat ients adde d below)
  1198                    if ( userType = = null ||  userType = = 0)
  1199                    {
  1200                         //get prov iderResour ceGroups f or the giv en TSA
  1201                         var queryR esult = ge tPRGs(tsa,  1).Entiti es;
  1202  
  1203                         var single Providers  = queryRes ult.Where( p => ((cvt _providerr esourcegro up)p).cvt_ TSAResourc eType.Valu e == 2);
  1204                         var resour ceGroups =  queryResu lt.Where(p  => ((cvt_ providerre sourcegrou p)p).cvt_T SAResource Type.Value  == 0);
  1205                         if (single Providers. Count() >  0)
  1206                         {
  1207                             foreac h (cvt_pro viderresou rcegroup p  in single Providers)
  1208                             {
  1209                                 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));
  1210                                 if  (singlePr oviderUser  != null & & singlePr oviderUser .Id == use r.Id)
  1211                                     providers .Entities. Add(user);
  1212                             }
  1213                         }
  1214                         if (resour ceGroups.C ount() > 0 )
  1215                         {
  1216                             //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 
  1217                             //the  list of re sources in  the group  to the re source on  the Servic e Activity
  1218                             foreac h (cvt_pro viderresou rcegroup r g in resou rceGroups)
  1219                             {
  1220                                 mc s_resource group grou p = (mcs_r esourcegro up)Organiz ationServi ce.Retriev e(
  1221                                      mcs_reso urcegroup. EntityLogi calName, r g.cvt_Rela tedResourc eGroupid.I d, new Col umnSet(tru e));
  1222                                 // if group t ype value  is provide r or all r equired
  1223                                 if  ((group.m cs_Type.Va lue == 999 99999) ||  (group.mcs _Type.Valu e == 91729 0000))
  1224                                 {
  1225                                      //if the  user sele cted is in  the resou rce group,  return tr ue and add  the user  to the ent itycollect ion
  1226                                      if (Matc hResourceT oGroup(use r.Id, grou p.Id))
  1227                                          prov iders.Enti ties.Add(u ser);
  1228                                 }
  1229                             }
  1230                         }                
  1231                    }
  1232                    //if  userType  is 1, retu rn patient s only, if  0 - retur n both (pr oviders ad ded above)
  1233                    if ( userType = = 0 || use rType == 1 )
  1234                    {
  1235                         //get pati entresourc egroup rec ords for t he TSA
  1236                         var queryR esult = ge tPRGs(tsa,  0).Entiti es;
  1237                         var single Patients =  queryResu lt.Where(p sr => ((cv t_patientr esourcegro up)psr).cv t_TSAResou rceType.Va lue == 3);
  1238                         var resour ceGroups =  queryResu lt.Where(p sr => ((cv t_patientr esourcegro up)psr).cv t_TSAResou rceType.Va lue == 0);
  1239                         if (single Patients.C ount() > 0 )
  1240                         {
  1241                             foreac h (cvt_pat ientresour cegroup p  in singleP atients)
  1242                             {
  1243                                 Sy stemUser s inglePatie ntUser = ( SystemUser )Organizat ionService .Retrieve(
  1244                                      SystemUs er.EntityL ogicalName , p.cvt_Re latedUserI d.Id, new  ColumnSet( true));
  1245                                 if  (singlePa tientUser  != null &&  singlePat ientUser.I d == user. Id)
  1246                                 pr oviders.En tities.Add (user);
  1247                             }
  1248                         }
  1249                         if (resour ceGroups.C ount() > 0 )
  1250                         {
  1251                             foreac h (cvt_pat ientresour cegroup rg  in resour ceGroups)
  1252                             {
  1253                                 mc s_resource group grou p = (mcs_r esourcegro up)Organiz ationServi ce.Retriev e(
  1254                                      mcs_reso urcegroup. EntityLogi calName, r g.cvt_Rela tedResourc eGroupid.I d, new Col umnSet(tru e));
  1255                                 if  (group.mc s_Type.Val ue == 1000 00000)
  1256                                 {
  1257                                      if (Matc hResourceT oGroup(use r.Id, grou p.Id))
  1258                                          prov iders.Enti ties.Add(u ser);
  1259                                 }
  1260                             }
  1261                         }
  1262                    }
  1263                }
  1264                return p roviders;
  1265           }
  1266  
  1267           // / <summary >
  1268           // / filters  down the l ist of all  equipment  on SA bas ed on crit eria provi ded
  1269           // / </summar y>
  1270           // / <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>
  1271           // / <param n ame="tsa"> tsa for th e Service  Activity</ param>
  1272           // / <param n ame="prgs" >cvt_patie ntresource group or c vt_provide rresourceg roup for a ll resourc es on the  tsa</param >
  1273           // / <param n ame="equip Type">type  of mcs_re source (ro om, tech,  vista clin ic, etc.)< /param>
  1274           // / <returns >the list  of mcs_res ources bas ed on the  filters li sted (pro  or pat loc ation and  equipment  type)</ret urns>
  1275           in ternal Lis t<mcs_reso urce> Clas sifyResour ces(Entity Collection  equipment , List<Ent ity> prgs,  int? equi pType)
  1276           {
  1277                List<mcs _resource>  relevantR esources =  new List< mcs_resour ce>();
  1278  
  1279                var sing les = prgs .Where(prg  => ((Opti onSetValue )(prg.Attr ibutes["cv t_tsaresou rcetype"]) ).Value ==  (int)cvt_ tsaresourc etype.Sing leResource ).ToList() ;
  1280                var grou ps = prgs. Where(prg  => ((Optio nSetValue) (prg.Attri butes["cvt _tsaresour cetype"])) .Value ==  (int)cvt_t saresource type.Resou rceGroup). ToList();
  1281  
  1282                foreach  (Entity si nglePRG in  singles)
  1283                {
  1284                    if ( singlePRG. Attributes .Contains( "cvt_relat edresource id") && si nglePRG.At tributes[" cvt_relate dresourcei d"] != nul l)
  1285                    {
  1286                         foreach (m cs_resourc e r in equ ipment.Ent ities)
  1287                         {
  1288                             if (r. mcs_Type.V alue != eq uipType &&  equipType  != null)
  1289                                 co ntinue;
  1290  
  1291                             mcs_re source res ource = (m cs_resourc e)Organiza tionServic e.Retrieve (mcs_resou rce.Entity LogicalNam e,
  1292                                      ((Entity Reference) singlePRG. Attributes ["cvt_rela tedresourc eid"]).Id,  new Colum nSet(true) );
  1293                             if (re source !=  null && re source.Id  == r.Id)
  1294                                 re levantReso urces.Add( r);
  1295                         }
  1296                    }
  1297                }
  1298                foreach  (Entity gr oupPRG in  groups)
  1299                {
  1300                    if ( groupPRG.A ttributes. Contains(" cvt_relate dresourceg roupid") & & groupPRG .Attribute s["cvt_rel atedresour cegroupid" ] != null)
  1301                    {
  1302                         mcs_resour cegroup gr oup = (mcs _resourceg roup)Organ izationSer vice.Retri eve(mcs_re sourcegrou p.EntityLo gicalName,  
  1303                                      ((Entity Reference) groupPRG.A ttributes[ "cvt_relat edresource groupid"]) .Id, new C olumnSet(t rue));
  1304                         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)
  1305                         {
  1306                             foreac h (mcs_res ource r in  equipment .Entities)
  1307                             {
  1308                                 if  (r.mcs_Ty pe.Value ! = equipTyp e && equip Type != nu ll)
  1309                                      continue ;
  1310  
  1311                                 if  (MatchRes ourceToGro up(r, grou p))
  1312                                 {
  1313                                      relevant Resources. Add(r);
  1314                                      break;
  1315                                 }
  1316                             }
  1317                         }
  1318                    }
  1319                }
  1320                
  1321                return r elevantRes ources;
  1322           }
  1323           #e ndregion
  1324  
  1325           #r egion Vist a Reminder  Email
  1326           in ternal voi d SendVist aReminder( Email emai l)
  1327           {
  1328                Logger.W riteDebugM essage("Be ginning Vi sta Remind er");
  1329                var prov TeamMember s = new Li st<TeamMem bership>() ;
  1330                var patT eamMembers  = new Lis t<TeamMemb ership>();
  1331                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)) ;
  1332                var crea tor = sa.C reatedBy;
  1333                //Either  get the P rov/Pat Fa cility fro m TSA or f rom the SA .
  1334                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));
  1335  
  1336                Logger.W riteDebugM essage("Re trieved Se rvice Acti vity and T SA associa ted with t his Email" );
  1337  
  1338                //if (ts a.cvt_Type  != null & & tsa.cvt_ Type.Value )
  1339                //{
  1340                //    De leteVistaR eminder(em ail, "Home /Mobile em ail does n ot require  a VistA R eminder, d eleting em ail");
  1341                //    re turn;
  1342                //}
  1343  
  1344                var prov FacilityId  = tsa.cvt _ProviderF acility.Id ;
  1345                var patF acilityId  = tsa.cvt_ PatientFac ility != n ull ? tsa. cvt_Patien tFacility. Id : Guid. Empty;
  1346                var intr aFacility  = (provFac ilityId ==  patFacili tyId) ? tr ue : false ;
  1347  
  1348                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1349                {
  1350                    var  provTeam =  srv.TeamS et.FirstOr Default(t  => t.cvt_F acility.Id  == provFa cilityId & & t.cvt_Ty pe.Value = = 91729000 5);
  1351                    if ( provTeam ! = null)
  1352                    prov TeamMember s = srv.Te amMembersh ipSet.Wher e(TM => TM .TeamId ==  provTeam. Id).ToList ();
  1353                    else
  1354                         Logger.Wri teToFile(" The provid er side Sc heduler Te am was una ble to be  found for  Service Ac tivity: "  + sa.Id);
  1355  
  1356                    var  patTeam =  srv.TeamSe t.FirstOrD efault(t = > t.cvt_Fa cility.Id  == patFaci lityId &&  t.cvt_Type .Value ==  917290005) ;
  1357                    if ( patTeam !=  null)
  1358                    patT eamMembers  = srv.Tea mMembershi pSet.Where (TM => TM. TeamId ==  patTeam.Id ).ToList() ;
  1359                    else
  1360                         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);
  1361                }
  1362  
  1363                bool pro vCheck = f alse;
  1364                bool pat Check = fa lse;
  1365                EntityCo llection p rovMembers  = new Ent ityCollect ion();
  1366                EntityCo llection p atMembers  = new Enti tyCollecti on();
  1367                if (prov TeamMember s.Count ==  0)
  1368                    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.");
  1369                else
  1370                {
  1371                foreach  (TeamMembe rship tm i n provTeam Members)
  1372                {
  1373                    Acti vityParty  p = new Ac tivityPart y()
  1374                    {
  1375                         PartyId =  new Entity Reference( SystemUser .EntityLog icalName,  tm.SystemU serId.Valu e)
  1376                    };
  1377                    prov Members.En tities.Add (p);
  1378                    if ( creator.Id  == tm.Sys temUserId. Value)
  1379                         provCheck  = true;
  1380                    }
  1381                }
  1382                if (patT eamMembers .Count ==  0 && !tsa. cvt_Type.V alue)
  1383                    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\""));
  1384                else
  1385                {
  1386                foreach  (TeamMembe rship tm i n patTeamM embers)
  1387                {
  1388                    Acti vityParty  p = new Ac tivityPart y()
  1389                    {
  1390                         PartyId =  new Entity Reference( SystemUser .EntityLog icalName,  tm.SystemU serId.Valu e)
  1391                    };
  1392                    patM embers.Ent ities.Add( p);
  1393                    if ( creator.Id  == tm.Sys temUserId. Value)
  1394                         patCheck =  true;
  1395                    }
  1396                }
  1397                //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
  1398                if ((tsa .cvt_Avail ableTelehe althModali ties != nu ll && tsa. cvt_Availa bleTelehea lthModalit ies.Value  == 9172900 01 && patC heck)
  1399                    || ( patCheck & & provChec k))
  1400                {
  1401                    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");
  1402                    try
  1403                    {
  1404                         Organizati onService. Delete(ema il.Logical Name, emai l.Id);
  1405                         Logger.Wri teDebugMes sage("Emai l Deleted" );
  1406                    }
  1407                    catc h (Excepti on ex)
  1408                    {
  1409                         Logger.Wri teToFile(" Unable to  Delete Ema il " + ex. Message +  ".  Leavin g email as  is.");
  1410                    }
  1411                    retu rn;
  1412                }
  1413                else
  1414                {
  1415                    Setu pVistaRemi nderEmail( email, pro vMembers,  patMembers , tsa, pro vCheck, pa tCheck, sa );
  1416                }
  1417           }
  1418  
  1419           in ternal voi d DeleteVi staReminde r(Email em ail, strin g debugMes sage)
  1420           {
  1421                Logger.W riteDebugM essage(deb ugMessage) ;
  1422                try
  1423                {
  1424                    Orga nizationSe rvice.Dele te(email.L ogicalName , email.Id );
  1425                    Logg er.WriteDe bugMessage ("Email De leted");
  1426                }
  1427                catch (E xception e x)
  1428                {
  1429                    Logg er.WriteTo File("Unab le to Dele te Email "  + ex.Mess age + ".   Leaving em ail as is. ");
  1430                }
  1431           }
  1432  
  1433           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)
  1434           {
  1435                Logger.W riteDebugM essage("Be ginning Se tupVistaRe minderEmai l");
  1436                mcs_faci lity patFa cility = n ull;
  1437                if (tsa. cvt_Patien tFacility  != null)
  1438                    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"));
  1439                var patS tation = p atFacility  == null ?  string.Em pty : " ("  + patFaci lity.mcs_S tationNumb er + ")";
  1440                mcs_faci lity proFa cility = n ull;
  1441                if (tsa. cvt_Provid erFacility  != null)
  1442                    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"));
  1443                var proS tation = p roFacility  == null ?  string.Em pty : " ("  + proFaci lity.mcs_S tationNumb er + ")";
  1444                email.Fr om = CvtHe lper.SetPa rtyList(sa .CreatedBy );
  1445                int time Zone = 0;
  1446                List<Act ivityParty > To = new  List<Acti vityParty> ();
  1447                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()) );
  1448                if (prov Check == f alse)
  1449                {
  1450                    //Ad d Prov Sch eduler Tea m Members  to To Line
  1451                    fore ach (Activ ityParty a p in provM embers.Ent ities)
  1452                    {
  1453                         To.Add(ap) ;
  1454                    }
  1455                    //To  = provMem bers.Entit ies.ToList <ActivityP arty>();
  1456                    Enti ty proSite ; //Either  the site  or facilit y of the p rovider
  1457                    if ( tsa.cvt_re latedprovi dersiteid  != null)
  1458                         proSite =  (mcs_site) Organizati onService. Retrieve(m cs_site.En tityLogica lName, tsa .cvt_relat edprovider siteid.Id,  new Colum nSet(true) );
  1459                    else
  1460                         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));
  1461                    time Zone = (in t)proSite. Attributes ["mcs_time zone"];
  1462                }
  1463                if (patC heck == fa lse)
  1464                {
  1465                    //Ad d Pat Sche duler Team  Members t o To Line
  1466                    fore ach (Activ ityParty a p in patMe mbers.Enti ties)
  1467                    {
  1468                         To.Add(ap) ;
  1469                    }
  1470                    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)
  1471                    Enti ty patSite ;
  1472                    if ( tsa.cvt_re latedprovi dersiteid  != null)
  1473                         patSite =  (mcs_site) Organizati onService. Retrieve(m cs_site.En tityLogica lName, tsa .cvt_relat edprovider siteid.Id,  new Colum nSet(true) );
  1474                    else
  1475                         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));
  1476                    time Zone = (in t)patSite. Attributes ["mcs_time zone"];
  1477                }
  1478                email.To  = To;
  1479                string t imeZonesSt ring = str ing.Empty;
  1480                bool con vertSucces s = false;
  1481                var time Conversion  = Convert TimeZone(s a.Schedule dStart.Val ue, timeZo ne, out ti meZonesStr ing, out c onvertSucc ess);
  1482                Logger.W riteDebugM essage("Vi sta Remind er (for sc heduler ac tion) Time  converted  to " + ti meZonesStr ing);
  1483                var equi ps = sa.Re sources.Wh ere(ap =>  ap.PartyId .LogicalNa me == Equi pment.Enti tyLogicalN ame).ToLis t();
  1484  
  1485                //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
  1486                var chil dEquips =  GetApptRes ources(sa,  Equipment .EntityLog icalName);  
  1487                equips.A ddRange(ch ildEquips) ;
  1488                var vist aClinics =  "Vista Cl inic(s): " ;
  1489                foreach  (var equip ment in eq uips)
  1490                {
  1491                    var  e = (Equip ment)Organ izationSer vice.Retri eve(Equipm ent.Entity LogicalNam e, equipme nt.PartyId .Id, new C olumnSet(" mcs_relate dresource" ));
  1492                    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"));
  1493                    if ( resource.m cs_Type.Va lue == 251 920000)
  1494                         vistaClini cs += reso urce.mcs_n ame + "; " ;
  1495                }
  1496                Logger.W riteDebugM essage("Ad ded vista  clinics to  Scheduler  Action em ail: " + v istaClinic s);
  1497                var disp layTime =  "Appointme nt Start T ime: " + t imeConvers ion + " "  + timeZone sString +  "; <br/>";
  1498                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 TS S");
  1499                var serv iceType =  tsa.cvt_se rvicetype. Name;
  1500                if (tsa. cvt_servic esubtype ! = null)
  1501                    serv iceType +=  " : " + t sa.cvt_ser vicesubtyp e.Name;
  1502                var stat us = sa.St atusCode.V alue == 4  ? "schedul ed" : "can celed";
  1503                var proF acName = t sa.cvt_Pro viderFacil ity == nul l ? string .Empty : t sa.cvt_Pro viderFacil ity.Name +  proStatio n;
  1504                var patF acName = t sa.cvt_Pat ientFacili ty == null   ? string .Empty : t sa.cvt_Pat ientFacili ty.Name +  patStation ;
  1505  
  1506                if (tsa. cvt_Type ! = null &&  tsa.cvt_Ty pe.Value)
  1507                    patF acName = " Home/Mobil e";
  1508  
  1509                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}" ,
  1510                    serv iceType,
  1511                    stat us,
  1512                    stat us == "sch eduled" ?  "schedule"  : "cancel ",
  1513                    proF acName, 
  1514                    patF acName, 
  1515                    body );
  1516  
  1517                if (tsa. cvt_relate dpatientsi teid == nu ll)
  1518                    emai l.Subject  += patFacN ame;
  1519  
  1520                CvtHelpe r.UpdateSe ndEmail(em ail, Organ izationSer vice);
  1521           }
  1522  
  1523           in ternal Lis t<Activity Party> Get ApptResour ces(Servic eAppointme nt sa, str ing filter  = "")
  1524           {
  1525                var chil dResources  = new Lis t<Activity Party>();
  1526                var chil dAppts = n ew List<Ap pointment> ();
  1527                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1528                {
  1529                    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();
  1530                }
  1531                foreach  (var appt  in childAp pts)
  1532                {
  1533                    //If  there is  no entityT ype filter  listed, t hen just a dd all mem bers of ap pointment  requiredAt tendees
  1534                    if ( string.IsN ullOrEmpty (filter))
  1535                         childResou rces.AddRa nge(appt.R equiredAtt endees);
  1536                    else
  1537                    {
  1538                         foreach (v ar resourc e in appt. RequiredAt tendees)
  1539                         {
  1540                             //Part yID should  never be  null, but  added null  check jus t in case.   
  1541                             if (re source.Par tyId != nu ll && reso urce.Party Id.Logical Name == fi lter) 
  1542                                 ch ildResourc es.Add(res ource);
  1543                         }
  1544                    }
  1545                }
  1546                Logger.W riteDebugM essage("Ap pointment  Resources  retrieved  for Servic e Activity : " + sa.I d);
  1547                return c hildResour ces;
  1548           }
  1549           #e ndregion
  1550  
  1551           #r egion TSS  Privilege  e-mails
  1552           in ternal Lis t<Activity Party> Ret rieveFacil ityTeamMem bers(Email  email, Gu id TeamId,  IEnumerab le<Activit yParty> or iginalPart y)
  1553           {
  1554                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1555                {
  1556                    var  teamMember s = (List< TeamMember ship>)(srv .TeamMembe rshipSet.W here(t =>  t.TeamId = = TeamId). ToList());
  1557                    var  recipientL ist = new  List<Activ ityParty>( );
  1558  
  1559                    if ( originalPa rty != nul l)
  1560                         recipientL ist.AddRan ge(origina lParty);
  1561                    fore ach (var m ember in t eamMembers )
  1562                    {
  1563                         var party  = new Acti vityParty( )
  1564                         {
  1565                             Activi tyId = new  EntityRef erence(ema il.Logical Name, emai l.Id),
  1566                             PartyI d = new En tityRefere nce(System User.Entit yLogicalNa me, member .SystemUse rId.Value)
  1567                         };
  1568                         recipientL ist.Add(pa rty);
  1569                    }
  1570                    retu rn recipie ntList;
  1571                }   
  1572           }
  1573  
  1574           in ternal voi d SendPriv ilegingEma il(Email e mail, Guid  tssprivil egeId, str ing record Type)
  1575           {
  1576                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1577                {               
  1578                    //Ge t the rela ted TSS Pr ivileging  record
  1579                    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));
  1580                    if ( tssprivile ging.cvt_P rivilegedA tId != nul l) //Alway s filled
  1581                    {
  1582                         //Establis h paramete rs to clea n up queri es
  1583                         List<Activ ityParty>  recipient  = new List <ActivityP arty>();
  1584                         Boolean is RegardingP rivHome =  true;
  1585                         cvt_tsspri vileging h omePrivRec ord = tssp rivileging ;
  1586                         List<Team>  homeCPTea m = new Li st<Team>() ;
  1587                         cvt_tsspri vileging p roxyPrivRe cord = new  cvt_tsspr ivileging( );
  1588                         List<Team>  proxyCPTe am = new L ist<Team>( );
  1589  
  1590                         //Regardin g is Proxy , overwrit e homeProv Record and  isRegardi ngPrivHome
  1591                         if ((tsspr ivileging. cvt_Typeof Privilegin g != null)  && (tsspr ivileging. cvt_Typeof Privilegin g.Value ==  917290001 ) && (tssp rivileging .cvt_Refer encedPrivi legeId !=  null))
  1592                         {
  1593                             isRega rdingPrivH ome = fals e;
  1594                             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));
  1595                             proxyP rivRecord  = tssprivi leging;
  1596                             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();
  1597                         }
  1598  
  1599                         //Home CPT eam is alw ays set
  1600                         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();
  1601  
  1602                         //Get the  owner of t he workflo w for the  From field
  1603                         email.From  = CvtHelp er.GetWork flowOwner( "Privilegi ng: PPE Su bmitted",  Organizati onService) ;
  1604  
  1605                         //Initial  Privilegin g
  1606                         if (email. Subject.In dexOf("Tel ehealth No tification : A Provid er is now  privileged ") != -1)
  1607                         {
  1608                             if (is RegardingP rivHome) / /Home
  1609                             {
  1610                                 fo reach (var  cp in hom eCPTeam)
  1611                                 {
  1612                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1613                                 }
  1614                                 cu stomMessag e = "A Hom e Privileg e has been  granted a t Facility : " + home PrivRecord .cvt_Privi legedAtId. Name;
  1615                             }
  1616                             else / /Proxy
  1617                             {
  1618                                 fo reach (var  cp in pro xyCPTeam)
  1619                                 {
  1620                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1621                                 }
  1622                                 fo reach (var  cp in hom eCPTeam)
  1623                                 {
  1624                                      email.Cc  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1625                                 }
  1626                                 cu stomMessag e = "A Pro xy Privile ge has bee n granted  at Facilit y: " + pro xyPrivReco rd.cvt_Pri vilegedAtI d.Name;
  1627                                 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;
  1628                                 cu stomMessag e += "<br/ >Reminder:  Please en ter the pr ovider int o your loc al PPE pro cess.";
  1629                             }
  1630                         }
  1631                         //Check if  E-mail su bject = "R enewal"
  1632                         else if (e mail.Subje ct.IndexOf ("Teleheal th Notific ation: Upc oming Rene wal for a  Provider")  != -1)
  1633                         {
  1634                             if (is RegardingP rivHome ==  true)
  1635                             {
  1636                                 // Update Hom e/Primary  TSS Privil ege //If S tatus Reas on = Privi leged; set  to In Ren ewal
  1637                                 if  (homePriv Record.sta tuscode.Va lue == 917 290001)
  1638                                 {
  1639                                      //Declar e new obje ct
  1640                                      cvt_tssp rivileging  homeRecor d = new cv t_tssprivi leging()
  1641                                      {
  1642                                          Id =  homePrivR ecord.Id,
  1643                                          stat uscode = n ew OptionS etValue(91 7290002)
  1644                                      };
  1645                                      //homePr ivRecord.s tatuscode. Value = 91 7290002;
  1646                                      Organiza tionServic e.Update(h omeRecord) ;
  1647                                 }
  1648                                 // //Get Prox y TSS Priv ileging re cords
  1649                                 // var proxyP rivs = srv .cvt_tsspr ivilegingS et.Where(p  => p.cvt_ Referenced PrivilegeI d.Id == ho mePrivReco rd.Id).Dis tinct().To List();
  1650                                 // foreach (v ar result  in proxyPr ivs)
  1651                                 // {
  1652                                 //     //If s tatus reas on == priv ileged, se t to Renew al
  1653                                 //     if (re sult.statu scode.Valu e == 91729 0001)
  1654                                 //     {
  1655                                 //         // Declare ne w object
  1656                                 //         cv t_tssprivi leging chi ldRecord =  new cvt_t ssprivileg ing()
  1657                                 //         {
  1658                                 //              Id = res ult.Id,
  1659                                 //              statusco de = new O ptionSetVa lue(917290 002)
  1660                                 //         };
  1661                                 //         // result.sta tuscode.Va lue = 9172 90002;
  1662                                 //         Or ganization Service.Up date(child Record);
  1663                                 //     }
  1664                                 // }
  1665                                 fo reach (var  cp in hom eCPTeam)
  1666                                 {
  1667                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1668                                 }
  1669                                 // Edit the E -mail body
  1670                                 cu stomMessag e = "Provi der's Home  Privilege  is up for  renewal a t Facility : " + home PrivRecord .cvt_Privi legedAtId. Name;
  1671                                 // customMess age += "<b r/>Note: H ome and an y Proxy Pr ivileges h ave been s et to 'In  Renewal' s tatus.";
  1672                                 cu stomMessag e += "<br/ >Note: Hom e Privileg e has been  set to 'I n Renewal'  status.";
  1673                             }
  1674                         }
  1675                         //Else if  Suspended
  1676                         else if (e mail.Subje ct.IndexOf ("Teleheal th Notific ation: A P rovider's  Privilegin g has been  Suspended ") != -1)
  1677                         {
  1678                             if (is RegardingP rivHome ==  true)
  1679                             {
  1680                                 fo reach (var  cp in hom eCPTeam)
  1681                                 {
  1682                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1683                                 }
  1684                                 // Update the  provider' s record
  1685                                 Sy stemUser p rovider =  (SystemUse r)Organiza tionServic e.Retrieve (SystemUse r.EntityLo gicalName,  tssprivil eging.cvt_ ProviderId .Id, new C olumnSet(t rue));
  1686                                 pr ovider.cvt _disable =  true;
  1687                                 Or ganization Service.Up date(provi der);
  1688  
  1689                                 // Edit the E -mail body
  1690                                 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;
  1691                                 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." ;
  1692                                 cu stomMessag e += "<br/ >Suspensio n: The sus pension oc curred at  Facility:  " + homePr ivRecord.c vt_Privile gedAtId.Na me;
  1693                             }
  1694                             else
  1695                             {
  1696                                 fo reach (var  cp in hom eCPTeam)
  1697                                 {
  1698                                      email.To  = Retriev eFacilityT eamMembers (email, cp .Id, email .To);
  1699                                 }
  1700                                 fo reach (var  cp in pro xyCPTeam)
  1701                                 {
  1702                                      email.Cc  = Retriev eFacilityT eamMembers (email, cp .Id, email .Cc);
  1703                                 }
  1704  
  1705                                 // Edit the E -mail body
  1706                                 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;
  1707                                 cu stomMessag e += "<br/ >Note: Thi s Provider  is still  schedulabl e in the s ystem.";
  1708                                 cu stomMessag e += "<br/ >Suspensio n: The sus pension oc curred at  Facility:"  + proxyPr ivRecord.c vt_Privile gedAtId.Na me;
  1709                                 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;                                         
  1710                             }                          
  1711                         }
  1712                         //Generate  body and  then send
  1713                         customMess age += "<b r/>Reminde r: Notify  all pertin ent C&P Of ficers and  Service C hiefs.";
  1714                         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.");
  1715                         if (email. To != null )
  1716                             CvtHel per.Update SendEmail( email, Org anizationS ervice);
  1717                    }
  1718                }
  1719           }
  1720           #e ndregion 
  1721  
  1722           #r egion FPPE /OPPE Chec k e-mail
  1723           // Add SC Tea m to TO/CC  7/24/15
  1724           in ternal voi d SendTrig gerEmail(E mail email , Guid fpp eID, strin g recordTy pe)
  1725           {
  1726                Logger.s etMethod =  "SendTrig gerEmail";
  1727                Logger.W riteDebugM essage("St arting");
  1728                using (v ar srv = n ew Xrm(Org anizationS ervice))
  1729                {
  1730                    //Ch eck system  generated  e-mail
  1731                    if ( email.Subj ect.IndexO f("Telehea lth Notifi cation: PP E Submitte d") != -1)
  1732                    {
  1733                         //Get the  owner of t he workflo w for the  From field
  1734                         email.From  = CvtHelp er.GetWork flowOwner( "Privilegi ng: PPE Su bmitted",  Organizati onService) ;
  1735  
  1736                         Logger.Wri teDebugMes sage("Get  the PPE re lated to t he email") ;
  1737                         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));
  1738  
  1739                         //Find the  Privilege  record as sociated a nd navigat e to that  record
  1740                         if (fppe.c vt_TSSPriv ilegingId  != null)
  1741                         {                
  1742                             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) );
  1743                             //Assu ming Home
  1744                             cvt_ts sprivilegi ng homePri v = fppePr iv;
  1745                             Boolea n isRegard ingRelated PrivHome =  true;
  1746                             Guid h omeService Type = fpp ePriv.cvt_ ServiceTyp eId != nul l ? fppePr iv.cvt_Ser viceTypeId .Id : Guid .Empty;
  1747                             List<T eam> homeS CTeams = n ew List<Te am>();
  1748                             List<T eam> proxy SCTeams =  new List<T eam>();
  1749  
  1750                             if (ho mePriv.cvt _TypeofPri vileging.V alue != 91 7290000) / /Overwriti ng since P roxy
  1751                             {
  1752                                 is RegardingR elatedPriv Home = fal se;
  1753                                 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));
  1754                             }
  1755  
  1756                             if (ho meServiceT ype == Gui d.Empty)
  1757                                 ho meServiceT ype = home Priv.cvt_S erviceType Id != null  ? homePri v.cvt_Serv iceTypeId. Id : Guid. Empty;
  1758  
  1759                             //Add  Service Ch ief Team -  should on ly ever be  one
  1760                             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();
  1761  
  1762                             foreac h (var res ult in hom eSCTeams)
  1763                             {
  1764                                 em ail.To = R etrieveFac ilityTeamM embers(ema il, result .Id, email .To);
  1765                             }
  1766                             var fl ag = "Gree n";
  1767                             if (fp pe.cvt_Fla g != null  && fppe.cv t_Flag.Val ue != 9172 90000)
  1768                                 fl ag = "Red" ;
  1769  
  1770                             //Edit  the E-mai l body
  1771                             custom Message =  "A " + fla g + " flag ged FPPE/O PPE has be en submitt ed.";
  1772  
  1773                             //If a ctually fr om Proxy,  set those  team membe rs as Cc
  1774                             if (is RegardingR elatedPriv Home == fa lse)
  1775                             {
  1776                                 if  (fppePriv .cvt_Privi legedAtId  != null)
  1777                                      proxySCT eams = srv .TeamSet.W here(t =>  t.cvt_Faci lity.Id ==  fppePriv. cvt_Privil egedAtId.I d && 
  1778                                          t.cv t_Type.Val ue == 9172 90001 && t .cvt_Servi ceType.Id  == homeSer viceType). Distinct() .ToList();
  1779                                 fo reach (var  proxyTeam  in proxyS CTeams)
  1780                                 {
  1781                                      email.Cc  = Retriev eFacilityT eamMembers (email, pr oxyTeam.Id , email.Cc );
  1782                                 }
  1783                                 cu stomMessag e += "<br/ >This FPPE /OPPE was  submitted  regarding  the Proxy  Privilege. ";
  1784                                 cu stomMessag e += "<br/ >Proxy Pri vilege is  at Facilit y: " + fpp ePriv.cvt_ Privileged AtId.Name;
  1785                                 
  1786                             }
  1787  
  1788                             custom Message +=  "<br/>Hom e Privileg e is at Fa cility: "  + homePriv .cvt_Privi legedAtId. Name;
  1789                             custom Message +=  "<br/>Spe cialty: "  + homePriv .cvt_Servi ceTypeId.N ame;
  1790                             //cust omMessage  += "Date R ange: " +  fppe.cvt_E valuationS tartDate +  " to " +  fppe.cvt_E valuationE ndDate;
  1791                             custom Message +=  "<br/>Rem inder: Not ify all pe rtinent C& P Officers  and Servi ce Chiefs. ";
  1792                             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.") ;
  1793                             if (em ail.To !=  null)
  1794                                 Cv tHelper.Up dateSendEm ail(email,  Organizat ionService );
  1795                         }
  1796                    }
  1797                }
  1798           }
  1799           #e ndregion
  1800  
  1801           #r egion Impl ementing a dditional  interface  methods
  1802           pu blic overr ide string  McsSettin gsDebugFie ld
  1803           {
  1804                get { re turn "cvt_ serviceact ivityplugi n"; }
  1805           }
  1806           #e ndregion
  1807       }
  1808   }