private void butAddTo_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.RefAttachAdd)) { return; } FormReferralSelect FormRS = new FormReferralSelect(); FormRS.IsSelectionMode = true; FormRS.ShowDialog(); if (FormRS.DialogResult != DialogResult.OK) { return; } RefAttach refattach = new RefAttach(); refattach.ReferralNum = FormRS.SelectedReferral.ReferralNum; refattach.PatNum = PatNum; refattach.RefType = ReferralType.RefTo; refattach.RefDate = DateTimeOD.Today; refattach.IsTransitionOfCare = FormRS.SelectedReferral.IsDoctor; refattach.ItemOrder = RefAttachList.Select(x => x.ItemOrder + 1).OrderByDescending(x => x).FirstOrDefault();//Max+1 or 0 refattach.ProcNum = ProcNum; //We want to help EHR users meet their measures. Therefore, we are going to make an educated guess as to who is making this referral. //We are doing this for non-EHR users as well because we think it might be nice automation. long provNumLastAppt = Appointments.GetProvNumFromLastApptForPat(PatNum); if (Security.CurUser.ProvNum != 0) { refattach.ProvNum = Security.CurUser.ProvNum; } else if (provNumLastAppt != 0) { refattach.ProvNum = provNumLastAppt; } else { refattach.ProvNum = Patients.GetProvNum(PatNum); } RefAttaches.Insert(refattach); SecurityLogs.MakeLogEntry(Permissions.RefAttachAdd, PatNum, "Referred To " + Referrals.GetNameFL(refattach.ReferralNum)); if (PrefC.GetBool(PrefName.AutomaticSummaryOfCareWebmail)) { FormRefAttachEdit FormRAE = new FormRefAttachEdit(); FormRAE.RefAttachCur = refattach; FormRAE.ShowDialog(); //In order to help offices meet EHR Summary of Care measure 1 of Core Measure 15 of 17, we are going to send a summary of care to the patient portal behind the scenes. //We can send the summary of care to the patient instead of to the Dr. because of the following point in the Additional Information section of the Core Measure: //"The EP can send an electronic or paper copy of the summary care record directly to the next provider or can provide it to the patient to deliver to the next provider, if the patient can reasonably expected to do so and meet Measure 1." //We will only send the summary of care if the ref attach is a TO referral and is a transition of care. if (FormRAE.DialogResult == DialogResult.OK && refattach.RefType == ReferralType.RefTo && refattach.IsTransitionOfCare) { try { //This is like FormEhrClinicalSummary.butSendToPortal_Click such that the email gets treated like a web mail. Patient PatCur = Patients.GetPat(PatNum); string strCcdValidationErrors = EhrCCD.ValidateSettings(); if (strCcdValidationErrors != "") { throw new Exception(); } strCcdValidationErrors = EhrCCD.ValidatePatient(PatCur); if (strCcdValidationErrors != "") { throw new Exception(); } Provider prov = null; if (Security.CurUser.ProvNum != 0) { prov = Providers.GetProv(Security.CurUser.ProvNum); } else { prov = Providers.GetProv(PatCur.PriProv); } EmailMessage msgWebMail = new EmailMessage(); //New mail object msgWebMail.FromAddress = prov.GetFormalName(); //Adding from address msgWebMail.ToAddress = PatCur.GetNameFL(); //Adding to address msgWebMail.PatNum = PatCur.PatNum; //Adding patient number msgWebMail.SentOrReceived = EmailSentOrReceived.WebMailSent; //Setting to sent msgWebMail.ProvNumWebMail = prov.ProvNum; //Adding provider number msgWebMail.Subject = "Referral To " + FormRS.SelectedReferral.GetNameFL(); msgWebMail.BodyText = "You have been referred to another provider. Your summary of care is attached.\r\n" + "You may give a copy of this summary of care to the referred provider if desired.\r\n" + "The contact information for the doctor you are being referred to is as follows:\r\n" + "\r\n"; //Here we provide the same information that would go out on a Referral Slip. //When the user prints a Referral Slip, the doctor referred to information is included and contains the doctor's name, address, and phone. msgWebMail.BodyText += "Name: " + FormRS.SelectedReferral.GetNameFL() + "\r\n"; if (FormRS.SelectedReferral.Address.Trim() != "") { msgWebMail.BodyText += "Address: " + FormRS.SelectedReferral.Address.Trim() + "\r\n"; if (FormRS.SelectedReferral.Address2.Trim() != "") { msgWebMail.BodyText += "\t" + FormRS.SelectedReferral.Address2.Trim() + "\r\n"; } msgWebMail.BodyText += "\t" + FormRS.SelectedReferral.City + " " + FormRS.SelectedReferral.ST + " " + FormRS.SelectedReferral.Zip + "\r\n"; } if (FormRS.SelectedReferral.Telephone != "") { msgWebMail.BodyText += "Phone: (" + FormRS.SelectedReferral.Telephone.Substring(0, 3) + ")" + FormRS.SelectedReferral.Telephone.Substring(3, 3) + "-" + FormRS.SelectedReferral.Telephone.Substring(6) + "\r\n"; } msgWebMail.BodyText += "\r\n" + "To view the Summary of Care for the referral to this provider:\r\n" + "1) Download all attachments to the same folder. Do not rename the files.\r\n" + "2) Open the ccd.xml file in an internet browser."; msgWebMail.MsgDateTime = DateTime.Now; //Message time is now msgWebMail.PatNumSubj = PatCur.PatNum; //Subject of the message is current patient string ccd = ""; Cursor = Cursors.WaitCursor; ccd = EhrCCD.GenerateSummaryOfCare(Patients.GetPat(PatNum)); //Create summary of care, can throw exceptions but they're caught below msgWebMail.Attachments.Add(EmailAttaches.CreateAttach("ccd.xml", Encoding.UTF8.GetBytes(ccd))); //Create summary of care attachment, can throw exceptions but caught below msgWebMail.Attachments.Add(EmailAttaches.CreateAttach("ccd.xsl", Encoding.UTF8.GetBytes(FormEHR.GetEhrResource("CCD")))); //Create xsl attachment, can throw exceptions EmailMessages.Insert(msgWebMail); //Insert mail into DB for patient portal EhrMeasureEvent newMeasureEvent = new EhrMeasureEvent(); newMeasureEvent.DateTEvent = DateTime.Now; newMeasureEvent.EventType = EhrMeasureEventType.SummaryOfCareProvidedToDr; newMeasureEvent.PatNum = PatCur.PatNum; newMeasureEvent.FKey = FormRAE.RefAttachCur.RefAttachNum; //Can be 0 if user didn't pick a referral for some reason. EhrMeasureEvents.Insert(newMeasureEvent); } catch { //We are just trying to be helpful so it doesn't really matter if something failed above. //They can simply go to the EHR dashboard and send the summary of care manually like they always have. They will get detailed validation errors there. MsgBox.Show(this, "There was a problem automatically sending a summary of care. Please go to the EHR dashboard to send a summary of care to meet the summary of care core measure."); } } } Cursor = Cursors.Default; FillGrid(); for (int i = 0; i < RefAttachList.Count; i++) { if (RefAttachList[i].ReferralNum == refattach.ReferralNum) { gridMain.SetSelected(i, true); } } }
private void butExport_Click(object sender, EventArgs e) { string strCcdValidationErrors = EhrCCD.ValidateSettings(); if (strCcdValidationErrors != "") //Do not even try to export if global settings are invalid. { MessageBox.Show(strCcdValidationErrors); //We do not want to use translations here, because the text is dynamic. The errors are generated in the business layer, and Lan.g() is not available there. return; } FolderBrowserDialog dlg = new FolderBrowserDialog(); DialogResult result = dlg.ShowDialog(); if (result != DialogResult.OK) { return; } DateTime dateNow = DateTime.Now; string folderPath = ODFileUtils.CombinePaths(dlg.SelectedPath, (dateNow.Year + "_" + dateNow.Month + "_" + dateNow.Day)); if (Directory.Exists(folderPath)) { int loopCount = 1; while (Directory.Exists(folderPath + "_" + loopCount)) { loopCount++; } folderPath = folderPath + "_" + loopCount; } try { Directory.CreateDirectory(folderPath); } catch { MessageBox.Show("Error, Could not create folder"); return; } this.Cursor = Cursors.WaitCursor; Patient patCur; string fileName; int numSkipped = 0; //Number of patients skipped. Set to -1 if only one patient was selected and had CcdValidationErrors. string patientsSkipped = ""; //Names of the patients that were skipped, so we can tell the user which ones didn't export correctly. for (int i = 0; i < gridMain.SelectedIndices.Length; i++) { patCur = Patients.GetPat((long)gridMain.Rows[gridMain.SelectedIndices[i]].Tag); //Cannot use GetLim because more information is needed in the CCD message generation below. strCcdValidationErrors = EhrCCD.ValidatePatient(patCur); if (strCcdValidationErrors != "") { if (gridMain.SelectedIndices.Length == 1) { numSkipped = -1; //Set to -1 so we know below to not show the "exported" message. MessageBox.Show(Lan.g(this, "Patient not exported due to the following errors") + ":\r\n" + strCcdValidationErrors); continue; } //If one patient is missing the required information for export, then simply skip the patient. We do not want to popup a message, //because it would be hard to get through the export if many patients were missing required information. numSkipped++; patientsSkipped += "\r\n" + patCur.LName + ", " + patCur.FName; continue; } fileName = ""; string lName = patCur.LName; for (int j = 0; j < lName.Length; j++) //Strip all non-letters from FName { if (Char.IsLetter(lName, j)) { fileName += lName.Substring(j, 1); } } fileName += "_"; string fName = patCur.FName; for (int k = 0; k < fName.Length; k++) //Strip all non-letters from LName { if (Char.IsLetter(fName, k)) { fileName += fName.Substring(k, 1); } } fileName += "_" + patCur.PatNum; //LName_FName_PatNum string ccd = EhrCCD.GeneratePatientExport(patCur); try { File.WriteAllText(ODFileUtils.CombinePaths(folderPath, fileName + ".xml"), ccd); } catch { MessageBox.Show("Error, Could not create xml file"); this.Cursor = Cursors.Default; return; } } if (numSkipped == -1) //Will be -1 if only one patient was selected, and it did not export correctly. { this.Cursor = Cursors.Default; return; //Don't display "Exported" to the user because the CCD was not exported. } try { File.WriteAllText(ODFileUtils.CombinePaths(folderPath, "CCD.xsl"), FormEHR.GetEhrResource("CCD")); } catch { MessageBox.Show("Error, Could not create stylesheet file"); } string strMsg = Lan.g(this, "Exported"); if (numSkipped > 0) { strMsg += ". " + Lan.g(this, "Patients skipped due to missing information") + ": " + numSkipped + patientsSkipped; MsgBoxCopyPaste msgCP = new MsgBoxCopyPaste(strMsg); msgCP.Show(); } else { MessageBox.Show(strMsg); } this.Cursor = Cursors.Default; }
private void butSendToPortal_Click(object sender, EventArgs e) { //Validate string strCcdValidationErrors = EhrCCD.ValidateSettings(); if (strCcdValidationErrors != "") //Do not even try to export if global settings are invalid. { MessageBox.Show(strCcdValidationErrors); //We do not want to use translations here, because the text is dynamic. The errors are generated in the business layer, and Lan.g() is not available there. return; } strCcdValidationErrors = EhrCCD.ValidatePatient(PatCur); //Patient cannot be null, because a patient must be selected before the EHR dashboard will open. if (strCcdValidationErrors != "") { MessageBox.Show(strCcdValidationErrors); //We do not want to use translations here, because the text is dynamic. The errors are generated in the business layer, and Lan.g() is not available there. return; } Provider prov = null; if (Security.CurUser.ProvNum != 0) //If the current user is a provider. { prov = Providers.GetProv(Security.CurUser.ProvNum); } else { prov = Providers.GetProv(PatCur.PriProv); //PriProv is not 0, because EhrCCD.ValidatePatient() will block if PriProv is 0. } try { //Create the Clinical Summary. FormEhrExportCCD FormEEC = new FormEhrExportCCD(PatCur); FormEEC.ShowDialog(); if (FormEEC.DialogResult != DialogResult.OK) //Canceled { return; } //Save the clinical summary (ccd.xml) and style sheet (ccd.xsl) as webmail message attachments. //TODO: It would be more patient friendly if we instead generated a PDF file containing the Clinical Summary printout, or if we simply displayed the Clinical Summary in the portal. //The CMS definition does not prohibit sending human readable files, and sending a PDF to the portal mimics printing the Clinical Summary and handing to patient. Random rnd = new Random(); string attachPath = EmailAttaches.GetAttachPath(); List <EmailAttach> listAttachments = new List <EmailAttach>(); EmailAttach attachCcd = new EmailAttach(); //Save Clinical Summary to file in the email attachments folder. attachCcd.DisplayedFileName = "ccd.xml"; attachCcd.ActualFileName = DateTime.Now.ToString("yyyyMMdd") + "_" + DateTime.Now.TimeOfDay.Ticks.ToString() + rnd.Next(1000).ToString() + ".xml"; listAttachments.Add(attachCcd); FileAtoZ.WriteAllText(FileAtoZ.CombinePaths(attachPath, attachCcd.ActualFileName), FormEEC.CCD, "Uploading Attachment for Clinical Summary..."); EmailAttach attachSs = new EmailAttach(); //Style sheet attachment. attachSs.DisplayedFileName = "ccd.xsl"; attachSs.ActualFileName = attachCcd.ActualFileName.Substring(0, attachCcd.ActualFileName.Length - 4) + ".xsl"; //Same base name as the CCD. The base names must match or the file will not display properly in internet browsers. listAttachments.Add(attachSs); FileAtoZ.WriteAllText(FileAtoZ.CombinePaths(attachPath, attachSs.ActualFileName), FormEHR.GetEhrResource("CCD"), "Uploading Attachment for Clinical Summary..."); //Create and save the webmail message containing the attachments. EmailMessage msgWebMail = new EmailMessage(); msgWebMail.FromAddress = prov.GetFormalName(); msgWebMail.ToAddress = PatCur.GetNameFL(); msgWebMail.PatNum = PatCur.PatNum; msgWebMail.SentOrReceived = EmailSentOrReceived.WebMailSent; msgWebMail.ProvNumWebMail = prov.ProvNum; msgWebMail.Subject = "Clinical Summary"; msgWebMail.BodyText = "To view the clinical summary:\r\n1) Download all attachments to the same folder. Do not rename the files.\r\n2) Open the ccd.xml file in an internet browser."; msgWebMail.MsgDateTime = DateTime.Now; msgWebMail.PatNumSubj = PatCur.PatNum; msgWebMail.Attachments = listAttachments; EmailMessages.Insert(msgWebMail); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } EhrMeasureEvent newMeasureEvent = new EhrMeasureEvent(); newMeasureEvent.DateTEvent = DateTime.Now; newMeasureEvent.EventType = EhrMeasureEventType.ClinicalSummaryProvidedToPt; newMeasureEvent.PatNum = PatCur.PatNum; EhrMeasureEvents.Insert(newMeasureEvent); FillGridEHRMeasureEvents(); //This will cause the measure event to show in the grid below the popup message on the next line. Reassures the user that the event was immediately recorded. MsgBox.Show(this, "Clinical Summary Sent"); }