///<summary>Only called from FormEHR to load the patient specific MU data and tell the user what action to take to get closer to meeting MU.</summary> public static List<EhrMu> GetMu(Patient pat) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { return Meth.GetObject<List<EhrMu>>(MethodBase.GetCurrentMethod(),pat); } List<EhrMu> list=new List<EhrMu>(); //add one of each type EhrMu mu; string explanation; List<EhrMeasure> retVal=GetMUList(); List<MedicationPat> medList=MedicationPats.Refresh(pat.PatNum,true); List<EhrMeasureEvent> listMeasureEvents=EhrMeasureEvents.Refresh(pat.PatNum); List<RefAttach> listRefAttach=RefAttaches.Refresh(pat.PatNum); for(int i=0;i<retVal.Count;i++) { mu=new EhrMu(); mu.Met=MuMet.False; mu.MeasureType=retVal[i].MeasureType; switch(mu.MeasureType) { #region ProblemList case EhrMeasureType.ProblemList: List<Disease> listDisease=Diseases.Refresh(pat.PatNum); int validDiseaseCount=0; if(listDisease.Count==0){ mu.Details="No problems entered."; } else{ bool diseasesNone=false; if(listDisease.Count==1 && listDisease[0].DiseaseDefNum==PrefC.GetLong(PrefName.ProblemsIndicateNone)){ diseasesNone=true; } if(diseasesNone){ mu.Met=MuMet.True; mu.Details="Problems marked 'none'."; } else{ for(int m=0;m<listDisease.Count;m++) { DiseaseDef diseaseCur=DiseaseDefs.GetItem(listDisease[m].DiseaseDefNum); if(diseaseCur.ICD9Code=="" && diseaseCur.SnomedCode=="") { continue; } validDiseaseCount++; } if(validDiseaseCount==0) { mu.Details="No problems with ICD-9 or Snomed code entered."; } else { mu.Met=MuMet.True; mu.Details="Problems with ICD-9 or Snomed code entered: "+validDiseaseCount.ToString(); } } } mu.Action="Enter problems"; break; #endregion #region MedicationList case EhrMeasureType.MedicationList: if(medList.Count==0) { mu.Details="No medications entered."; } else{ mu.Met=MuMet.True; bool medsNone=false; if(medList.Count==1 && medList[0].MedicationNum==PrefC.GetLong(PrefName.MedicationsIndicateNone)) { medsNone=true; } if(medsNone) { mu.Details="Medications marked 'none'."; } else{ mu.Details="Medications entered: "+medList.Count.ToString(); } } mu.Action="Enter medications"; break; #endregion #region AllergyList case EhrMeasureType.AllergyList: List<Allergy> listAllergies=Allergies.Refresh(pat.PatNum); if(listAllergies.Count==0) { mu.Details="No allergies entered."; } else{ mu.Met=MuMet.True; bool allergiesNone=false; if(listAllergies.Count==1 && listAllergies[0].AllergyDefNum==PrefC.GetLong(PrefName.AllergiesIndicateNone)) { allergiesNone=true; } if(allergiesNone) { mu.Details="Allergies marked 'none'."; } else{ mu.Details="Allergies entered: "+listAllergies.Count.ToString(); } } mu.Action="Enter allergies"; break; #endregion #region Demographics case EhrMeasureType.Demographics: explanation=""; if(pat.Birthdate.Year<1880) { explanation+="birthdate";//missing } if(pat.Language=="") { if(explanation!="") { explanation+=", "; } explanation+="language"; } if(pat.Gender==PatientGender.Unknown) { if(explanation!="") { explanation+=", "; } explanation+="gender"; } if(PatientRaces.GetForPatient(pat.PatNum).Count==0) { if(explanation!="") { explanation+=", "; } explanation+="race, ethnicity"; } if(explanation=="") { mu.Details="All demographic elements recorded"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } mu.Action="Enter demographics"; break; #endregion #region Education case EhrMeasureType.Education: List<EhrMeasureEvent> listEd=EhrMeasureEvents.RefreshByType(pat.PatNum,EhrMeasureEventType.EducationProvided); if(listEd.Count==0) { mu.Details="No education resources provided."; } else { mu.Details="Education resources provided: "+listEd.Count.ToString(); mu.Met=MuMet.True; } mu.Action="Provide education resources"; break; #endregion #region TimelyAccess case EhrMeasureType.TimelyAccess: List<EhrMeasureEvent> listOnline=EhrMeasureEvents.RefreshByType(pat.PatNum,EhrMeasureEventType.OnlineAccessProvided); if(listOnline.Count==0) { mu.Details="No online access provided."; } else { mu.Details="Online access provided: "+listOnline[listOnline.Count-1].DateTEvent.ToShortDateString();//most recent mu.Met=MuMet.True; } mu.Action="Provide online Access"; break; #endregion #region ProvOrderEntry case EhrMeasureType.ProvOrderEntry: //int medOrderCount=0; int medOrderCpoeCount=0; for(int mo=0;mo<medList.Count;mo++){ //if(medList[mo].DateStart.Year>1880 && medList[mo].PatNote!=""){ if(medList[mo].IsCpoe){ medOrderCpoeCount++; } } if(medList.Count==0) { mu.Met=MuMet.NA; mu.Details="No meds."; } else if(medOrderCpoeCount==0) { mu.Details="No medication order in CPOE."; } else { mu.Details="Medications entered in CPOE: "+medOrderCpoeCount.ToString(); mu.Met=MuMet.True; } mu.Action="(edit Rxs from Chart)"; break; #endregion #region CPOE_MedOrdersOnly case EhrMeasureType.CPOE_MedOrdersOnly: int medOrderCount=0; medOrderCpoeCount=0; for(int m=0;m<medList.Count;m++) { //Using the last year as the reporting period, following pattern in ElectronicCopy, ClinicalSummaries, Reminders... if(medList[m].DateStart<DateTime.Now.AddYears(-1)) {//either no start date so not an order, or not within the last year so not during the reporting period continue; } else if(medList[m].PatNote!="" && medList[m].ProvNum==pat.PriProv) {//if there's a note and it was created by the patient's PriProv, then count as order created by this provider and would count toward the denominator for MU medOrderCount++; if(medList[m].IsCpoe) {//if also marked as CPOE, then this would count in the numerator of the calculation MU medOrderCpoeCount++; } } } if(medOrderCount==0) { mu.Details="No medication order in CPOE."; } else { mu.Details="Medications entered in CPOE: "+medOrderCount.ToString(); mu.Met=MuMet.True; } mu.Action="(edit Rxs from Chart)"; break; #endregion #region CPOE_PreviouslyOrdered case EhrMeasureType.CPOE_PreviouslyOrdered: //first determine if this patient has ever had a medication ordered by this Provider bool prevOrderExists=false; for(int m=0;m<medList.Count;m++) { //if this is an order (defined as having instructions and a start date) and was entered by this provider, then this pat will be counted in the denominator if(medList[m].PatNote!="" && medList[m].DateStart.Year>1880 && medList[m].ProvNum==pat.PriProv) { prevOrderExists=true; break; } } medOrderCpoeCount=0; for(int mo=0;mo<medList.Count;mo++){ if(medList[mo].IsCpoe){ medOrderCpoeCount++; } } if(medList.Count==0) { mu.Met=MuMet.NA; mu.Details="No meds."; } else if(!prevOrderExists) { mu.Met=MuMet.NA; mu.Details="No previous medication orders by this Provider."; } else if(medOrderCpoeCount==0) { mu.Details="No medication order in CPOE."; } else { mu.Details="Medications entered in CPOE: "+medOrderCpoeCount.ToString(); mu.Met=MuMet.True; } mu.Action="(edit Rxs from Chart)"; break; #endregion #region Rx case EhrMeasureType.Rx: List<RxPat> listRx=RxPats.GetPermissableForDateRange(pat.PatNum,DateTime.Today.AddYears(-1),DateTime.Today); if(listRx.Count==0){ mu.Met=MuMet.NA; mu.Details="No Rxs entered."; } else{ explanation=""; for(int rx=0;rx<listRx.Count;rx++) { if(listRx[rx].SendStatus==RxSendStatus.SentElect){ continue; } if(explanation!="") { explanation+=", "; } explanation+=listRx[rx].RxDate.ToShortDateString(); } if(explanation=="") { mu.Met=MuMet.True; mu.Details="All Rxs sent electronically."; } else { mu.Met=MuMet.False; mu.Details="Rxs not sent electronically: "+explanation; } } mu.Action="(edit Rxs from Chart)";//no action break; #endregion #region VitalSigns case EhrMeasureType.VitalSigns: List<Vitalsign> vitalsignList=Vitalsigns.Refresh(pat.PatNum); if(vitalsignList.Count==0) { mu.Details="No vital signs entered."; } else { bool hFound=false; bool wFound=false; bool bpFound=false; for(int v=0;v<vitalsignList.Count;v++) { if(vitalsignList[v].Height>0) { hFound=true; } if(vitalsignList[v].Weight>0) { wFound=true; } if(pat.Birthdate>DateTime.Today.AddYears(-3) //3 and older for BP || (vitalsignList[v].BpDiastolic>0 && vitalsignList[v].BpSystolic>0)) { bpFound=true; } } explanation=""; if(!hFound) { explanation+="height";//missing } if(!wFound) { if(explanation!="") { explanation+=", "; } explanation+="weight"; } if(!bpFound) { if(explanation!="") { explanation+=", "; } explanation+="blood pressure"; } if(explanation=="") { mu.Details="Vital signs entered"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } } mu.Action="Enter vital signs"; break; #endregion #region VitalSigns2014 case EhrMeasureType.VitalSigns2014: List<Vitalsign> vitalsignList2014=Vitalsigns.Refresh(pat.PatNum); if(vitalsignList2014.Count==0) { mu.Details="No vital signs entered."; } else { bool hFound=false; bool wFound=false; bool bpFound=false; for(int v=0;v<vitalsignList2014.Count;v++) { if(vitalsignList2014[v].Height>0) { hFound=true; } if(vitalsignList2014[v].Weight>0) { wFound=true; } if(pat.Birthdate>DateTime.Today.AddYears(-3) //3 and older for BP || (vitalsignList2014[v].BpDiastolic>0 && vitalsignList2014[v].BpSystolic>0)) { bpFound=true; } } explanation=""; if(!hFound) { explanation+="height";//missing } if(!wFound) { if(explanation!="") { explanation+=", "; } explanation+="weight"; } if(!bpFound) { if(explanation!="") { explanation+=", "; } explanation+="blood pressure"; } if(explanation=="") { mu.Details="Vital signs entered"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } } mu.Action="Enter vital signs"; break; #endregion #region VitalSignsBMIOnly case EhrMeasureType.VitalSignsBMIOnly: vitalsignList=Vitalsigns.Refresh(pat.PatNum); if(vitalsignList.Count==0) { mu.Details="No vital signs entered."; } else { bool hFound=false; bool wFound=false; for(int v=0;v<vitalsignList.Count;v++) { if(vitalsignList[v].Height>0) { hFound=true; } if(vitalsignList[v].Weight>0) { wFound=true; } } explanation=""; if(!hFound) { explanation+="height";//missing } if(!wFound) { if(explanation!="") { explanation+=", "; } explanation+="weight"; } if(explanation=="") { mu.Details="Vital signs entered"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } } mu.Action="Enter vital signs"; break; #endregion #region VitalSignsBPOnly case EhrMeasureType.VitalSignsBPOnly: vitalsignList=Vitalsigns.Refresh(pat.PatNum); if(pat.Birthdate>DateTime.Today.AddYears(-3)) {//3 and older for BP mu.Details="Age 3 and older for BP."; mu.Met=MuMet.NA; } else if(vitalsignList.Count==0) { mu.Details="No vital signs entered."; } else { for(int v=0;v<vitalsignList.Count;v++) { if(vitalsignList[v].BpDiastolic>0 && vitalsignList[v].BpSystolic>0) { mu.Details="Vital signs entered"; mu.Met=MuMet.True; } else { mu.Details="Missing: blood pressure"; } } } mu.Action="Enter vital signs"; break; #endregion #region Smoking case EhrMeasureType.Smoking: if(pat.SmokingSnoMed=="") {//None mu.Details="Smoking status not entered"; } else { mu.Details="Smoking status entered"; mu.Met=MuMet.True; } mu.Action="Edit smoking status"; break; #endregion #region Lab case EhrMeasureType.Lab: List<EhrLab> listLabOrders=EhrLabs.GetAllForPatInDateRange(pat.PatNum,DateTime.Today.AddYears(-1),DateTime.Today); if(listLabOrders.Count==0) { mu.Details="No lab orders"; mu.Met=MuMet.NA; } else { int labResultCount=0; for(int lo=0;lo<listLabOrders.Count;lo++) { List<EhrLabResult> listLabResults=EhrLabResults.GetForLab(listLabOrders[lo].EhrLabNum); if(listLabResults.Count>0) { labResultCount++; continue;//Only need one per lab order } } if(labResultCount<listLabOrders.Count) { mu.Met=MuMet.False; mu.Details="Lab orders missing results: "+(listLabOrders.Count-labResultCount).ToString(); } else { mu.Details="Lab results entered for each lab order."; mu.Met=MuMet.True; } } mu.Action="Edit labs"; break; #endregion #region ElectronicCopy case EhrMeasureType.ElectronicCopy: List<EhrMeasureEvent> listRequests=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ElectronicCopyRequested); List<EhrMeasureEvent> listRequestsPeriod=new List<EhrMeasureEvent>(); for(int r=0;r<listRequests.Count;r++) { if(listRequests[r].DateTEvent < DateTime.Now.AddYears(-1)) {//not within the last year continue; } listRequestsPeriod.Add(listRequests[r]); } if(listRequestsPeriod.Count==0) { mu.Met=MuMet.NA; mu.Details="No requests within the last year."; } else { int countMissingCopies=0; bool copyProvidedinTime; List<EhrMeasureEvent> listCopiesProvided=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ElectronicCopyProvidedToPt); for(int rp=0;rp<listRequestsPeriod.Count;rp++) { copyProvidedinTime=false; DateTime deadlineDateCopy=listRequestsPeriod[rp].DateTEvent.Date.AddDays(3); if(listRequestsPeriod[rp].DateTEvent.DayOfWeek==DayOfWeek.Wednesday || listRequestsPeriod[rp].DateTEvent.DayOfWeek==DayOfWeek.Thursday || listRequestsPeriod[rp].DateTEvent.DayOfWeek==DayOfWeek.Friday) { deadlineDateCopy.AddDays(2);//add two days for the weekend } for(int cp=0;cp<listCopiesProvided.Count;cp++) { if(listCopiesProvided[cp].DateTEvent.Date > deadlineDateCopy) { continue; } if(listCopiesProvided[cp].DateTEvent.Date < listRequestsPeriod[rp].DateTEvent.Date) { continue; } copyProvidedinTime=true; } if(!copyProvidedinTime) { countMissingCopies++; } } if(countMissingCopies==0) { mu.Met=MuMet.True; mu.Details="Electronic copy provided to Pt within 3 business days of each request."; } else { mu.Met=MuMet.False; mu.Details="Electronic copies not provided to Pt within 3 business days of a request:"+countMissingCopies.ToString(); } } mu.Action="Provide elect copy to Pt";//If this text ever changes then FormEHR grid will need to change for MU1 break; #endregion #region ClinicalSummaries case EhrMeasureType.ClinicalSummaries: List<DateTime> listVisits=new List<DateTime>();//for this year List<Procedure> listProcs=Procedures.Refresh(pat.PatNum); for(int p=0;p<listProcs.Count;p++) { if(listProcs[p].ProcDate < DateTime.Now.AddYears(-1) || listProcs[p].ProcStatus!=ProcStat.C) {//not within the last year or not a completed procedure continue; } if(!listVisits.Contains(listProcs[p].ProcDate)) { listVisits.Add(listProcs[p].ProcDate); } } if(listVisits.Count==0){ mu.Met=MuMet.NA; mu.Details="No visits within the last year."; } else{ int countMissing=0; bool summaryProvidedinTime; List<EhrMeasureEvent> listClinSum=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ClinicalSummaryProvidedToPt); for(int p=0;p<listVisits.Count;p++) { summaryProvidedinTime=false; DateTime deadlineDate=listVisits[p].AddDays(3); if(listVisits[p].DayOfWeek==DayOfWeek.Wednesday || listVisits[p].DayOfWeek==DayOfWeek.Thursday || listVisits[p].DayOfWeek==DayOfWeek.Friday){ deadlineDate=deadlineDate.AddDays(2);//add two days for the weekend } for(int r=0;r<listClinSum.Count;r++) { if(listClinSum[r].DateTEvent.Date > deadlineDate) { continue; } if(listClinSum[r].DateTEvent.Date < listVisits[p]) { continue; } summaryProvidedinTime=true; } if(!summaryProvidedinTime) { countMissing++; } } if(countMissing==0) { mu.Met=MuMet.True; mu.Details="Clinical summary provided to Pt within 3 business days of each visit."; } else { mu.Met=MuMet.False; mu.Details="Clinical summaries not provided to Pt within 3 business days of a visit:"+countMissing.ToString(); } } mu.Action="Send clinical summary to Pt"; break; #endregion #region Reminders case EhrMeasureType.Reminders: if(pat.PatStatus!=PatientStatus.Patient) { mu.Met=MuMet.NA; mu.Details="Status not patient."; } else if(pat.Age==0) { mu.Met=MuMet.NA; mu.Details="Age not entered."; } else if(pat.Age>5 && pat.Age<65) { mu.Met=MuMet.NA; mu.Details="Patient age not 65+ or 5-."; } else { List<EhrMeasureEvent> listReminders=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ReminderSent); //during reporting period. bool withinLastYear=false; for(int r=0;r<listReminders.Count;r++) { if(listReminders[r].DateTEvent > DateTime.Now.AddYears(-1)) { withinLastYear=true; } } if(withinLastYear) { mu.Details="Reminder sent within the last year."; mu.Met=MuMet.True; } else { mu.Details="No reminders sent within the last year for patient age 65+ or 5-."; } } mu.Action="Send reminders"; break; #endregion #region MedReconcile case EhrMeasureType.MedReconcile: int countFromRef=0; int countFromRefPeriod=0; for(int c=0;c<listRefAttach.Count;c++) { if(listRefAttach[c].IsFrom && listRefAttach[c].IsTransitionOfCare) { countFromRef++; if(listRefAttach[c].RefDate > DateTime.Now.AddYears(-1)) {//within the last year countFromRefPeriod++; } } } if(countFromRef==0) { mu.Met=MuMet.NA; mu.Details="Referral 'from' not entered."; } else if(countFromRefPeriod==0) { mu.Met=MuMet.NA; mu.Details="Referral 'from' not entered within the last year."; } else if(countFromRefPeriod > 0) { List<EhrMeasureEvent> listReconciles=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.MedicationReconcile); int countReconciles=0;//during reporting period. for(int r=0;r<listReconciles.Count;r++) { if(listReconciles[r].DateTEvent > DateTime.Now.AddYears(-1)) {//within the same period as the count for referrals. countReconciles++; } } mu.Details="Referrals:"+countFromRefPeriod.ToString()+", Reconciles:"+countReconciles.ToString(); if(countReconciles>=countFromRefPeriod) { mu.Met=MuMet.True; } } mu.Action="Reconcile from received CCD"; mu.Action2="Enter Referrals"; break; #endregion #region SummaryOfCare case EhrMeasureType.SummaryOfCare: int countToRefPeriod=0; for(int c=0;c<listRefAttach.Count;c++) { if(!listRefAttach[c].IsFrom && listRefAttach[c].IsTransitionOfCare) { if(listRefAttach[c].RefDate > DateTime.Now.AddYears(-1)) {//within the last year countToRefPeriod++; } } } if(countToRefPeriod==0) { mu.Met=MuMet.NA; mu.Details="No outgoing transitions of care within the last year."; } else{// > 0 List<EhrMeasureEvent> listCcds=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.SummaryOfCareProvidedToDr); int countCcds=0;//during reporting period. for(int r=0;r<listCcds.Count;r++) { if(listCcds[r].DateTEvent > DateTime.Now.AddYears(-1)) {//within the same period as the count for referrals. countCcds++; } } mu.Details="Referrals:"+countToRefPeriod.ToString()+", Summaries:"+countCcds.ToString(); if(countCcds>=countToRefPeriod) { mu.Met=MuMet.True; } } mu.Action="Send/Receive summary of care"; mu.Action2="Enter Referrals"; break; #endregion } list.Add(mu); } return list; }
///<summary>Only called from FormEHR to load the patient specific MU data and tell the user what action to take to get closer to meeting MU.</summary> public static List<EhrMu> GetMu2(Patient pat) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { return Meth.GetObject<List<EhrMu>>(MethodBase.GetCurrentMethod(),pat); } List<EhrMu> list=new List<EhrMu>(); //add one of each type EhrMu mu; string explanation; List<EhrMeasure> retVal=GetMU2List(); List<MedicationPat> medList=MedicationPats.Refresh(pat.PatNum,true); List<EhrLab> ehrLabList=EhrLabs.GetAllForPat(pat.PatNum); List<EhrMeasureEvent> listMeasureEvents=EhrMeasureEvents.Refresh(pat.PatNum); List<RefAttach> listRefAttach=RefAttaches.Refresh(pat.PatNum); for(int i=0;i<retVal.Count;i++) { mu=new EhrMu(); mu.Met=MuMet.False; mu.MeasureType=retVal[i].MeasureType; switch(mu.MeasureType) { #region Demographics case EhrMeasureType.Demographics: explanation=""; if(pat.Birthdate.Year<1880) { explanation+="birthdate";//missing } if(pat.Language=="") { if(explanation!="") { explanation+=", "; } explanation+="language"; } if(pat.Gender==PatientGender.Unknown) { if(explanation!="") { explanation+=", "; } explanation+="gender"; } if(PatientRaces.GetForPatient(pat.PatNum).Count==0) { if(explanation!="") { explanation+=", "; } explanation+="race, ethnicity"; } if(explanation=="") { mu.Details="All demographic elements recorded"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } mu.Action="Enter demographics"; break; #endregion #region Education case EhrMeasureType.Education: List<EhrMeasureEvent> listEd=EhrMeasureEvents.RefreshByType(pat.PatNum,EhrMeasureEventType.EducationProvided); if(listEd.Count==0) { mu.Details="No education resources provided."; } else { mu.Details="Education resources provided: "+listEd.Count.ToString(); mu.Met=MuMet.True; } mu.Action="Provide education resources"; break; #endregion #region ElectronicCopyAccess case EhrMeasureType.ElectronicCopyAccess: List<EhrMeasureEvent> listOnline=EhrMeasureEvents.RefreshByType(pat.PatNum,EhrMeasureEventType.OnlineAccessProvided); if(listOnline.Count==0) { mu.Details="No online access provided."; } else { mu.Details="Online access provided: "+listOnline[listOnline.Count-1].DateTEvent.ToShortDateString();//most recent mu.Met=MuMet.True; } mu.Action="Provide online Access"; break; #endregion #region CPOE_MedOrdersOnly case EhrMeasureType.CPOE_MedOrdersOnly: int medOrderCount=0; int medOrderCpoeCount=0; for(int m=0;m<medList.Count;m++) { //Using the last year as the reporting period, following pattern in ElectronicCopy, ClinicalSummaries, Reminders... if(medList[m].DateStart<DateTime.Now.AddYears(-1)) {//either no start date so not an order, or not within the last year so not during the reporting period continue; } else if(medList[m].PatNote!="" && medList[m].ProvNum==pat.PriProv) {//if there's a note and it was created by the patient's PriProv, then count as order created by this provider and would count toward the denominator for MU medOrderCount++; if(medList[m].IsCpoe) {//if also marked as CPOE, then this would count in the numerator of the calculation MU medOrderCpoeCount++; } } } if(medOrderCount==0) { mu.Details="No medication order in CPOE."; } else { mu.Details="Medications entered in CPOE: "+medOrderCount.ToString(); mu.Met=MuMet.True; } mu.Action="(edit Rxs from Chart)"; break; #endregion #region CPOE_LabOrdersOnly case EhrMeasureType.CPOE_LabOrdersOnly: int labOrderCount=0; int labOrderCpoeCount=0; for(int m=0;m<ehrLabList.Count;m++) { //Using the last year as the reporting period, following pattern in ElectronicCopy, ClinicalSummaries, Reminders... Loinc loinc=Loincs.GetByCode(ehrLabList[m].UsiID); string dateSt=ehrLabList[m].ObservationDateTimeStart.PadRight(8,'0').Substring(0,8);//stored in DB as yyyyMMddhhmmss-zzzz DateTime dateT=PIn.Date(dateSt.Substring(4,2)+"/"+dateSt.Substring(6,2)+"/"+dateSt.Substring(0,4)); if(dateT<DateTime.Now.AddYears(-1)) {//either no start date so not an order, or not within the last year so not during the reporting period continue; } else if((ehrLabList[m].OrderingProviderID==pat.PriProv.ToString() || ehrLabList[m].OrderingProviderID==Providers.GetProv(pat.PriProv).NationalProvID) && (loinc==null || !loinc.ClassType.Contains("%rad%"))) {//if there's a note and it was created by the patient's PriProv, then count as order created by this provider and would count toward the denominator for MU labOrderCount++; labOrderCpoeCount++; } } if(labOrderCount==0) { mu.Details="No Lab order in CPOE."; } else { mu.Details="Labs entered in CPOE: "+labOrderCount.ToString(); mu.Met=MuMet.True; } mu.Action="Edit labs"; break; #endregion #region CPOE_RadiologyOrdersOnly case EhrMeasureType.CPOE_RadiologyOrdersOnly: int radOrderCount=0; int radOrderCpoeCount=0; for(int m=0;m<ehrLabList.Count;m++) { //Using the last year as the reporting period, following pattern in ElectronicCopy, ClinicalSummaries, Reminders... Loinc loinc=Loincs.GetByCode(ehrLabList[m].UsiID); if(loinc==null) { continue; } string dateSt=ehrLabList[m].ObservationDateTimeStart.PadRight(8,'0').Substring(0,8);//stored in DB as yyyyMMddhhmmss-zzzz DateTime dateT=PIn.Date(dateSt.Substring(4,2)+"/"+dateSt.Substring(6,2)+"/"+dateSt.Substring(0,4)); if(dateT<DateTime.Now.AddYears(-1)) {//either no start date so not an order, or not within the last year so not during the reporting period continue; } else if((ehrLabList[m].OrderingProviderID==pat.PriProv.ToString() || ehrLabList[m].OrderingProviderID==Providers.GetProv(pat.PriProv).NationalProvID) && loinc.ClassType.Contains("%rad%")) {//if there's a note and it was created by the patient's PriProv, then count as order created by this provider and would count toward the denominator for MU radOrderCount++; radOrderCpoeCount++; } } if(radOrderCount==0) { mu.Details="No Rad order in CPOE."; } else { mu.Details="Rads entered in CPOE: "+radOrderCount.ToString(); mu.Met=MuMet.True; } mu.Action="Edit labs"; break; #endregion #region Rx case EhrMeasureType.Rx: List<RxPat> listRx=RxPats.GetPermissableForDateRange(pat.PatNum,DateTime.Today.AddYears(-1),DateTime.Today); if(listRx.Count==0) { mu.Met=MuMet.NA; mu.Details="No Rxs entered."; } else { explanation=""; for(int rx=0;rx<listRx.Count;rx++) { if(listRx[rx].SendStatus==RxSendStatus.SentElect) { continue; } if(explanation!="") { explanation+=", "; } explanation+=listRx[rx].RxDate.ToShortDateString(); } if(explanation=="") { mu.Met=MuMet.True; mu.Details="All Rxs sent electronically."; } else { mu.Met=MuMet.False; mu.Details="Rxs not sent electronically: "+explanation; } } mu.Action="(edit Rxs from Chart)";//no action break; #endregion #region VitalSigns case EhrMeasureType.VitalSigns: List<Vitalsign> vitalsignList=Vitalsigns.Refresh(pat.PatNum); if(vitalsignList.Count==0) { mu.Details="No vital signs entered."; } else { bool hFound=false; bool wFound=false; bool bpFound=false; for(int v=0;v<vitalsignList.Count;v++) { if(vitalsignList[v].Height>0) { hFound=true; } if(vitalsignList[v].Weight>0) { wFound=true; } if(pat.Birthdate>DateTime.Today.AddYears(-3) //3 and older for BP || (vitalsignList[v].BpDiastolic>0 && vitalsignList[v].BpSystolic>0)) { bpFound=true; } } explanation=""; if(!hFound) { explanation+="height";//missing } if(!wFound) { if(explanation!="") { explanation+=", "; } explanation+="weight"; } if(!bpFound) { if(explanation!="") { explanation+=", "; } explanation+="blood pressure"; } if(explanation=="") { mu.Details="Vital signs entered"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } } mu.Action="Enter vital signs"; break; #endregion #region VitalSignsBMIOnly case EhrMeasureType.VitalSignsBMIOnly: vitalsignList=Vitalsigns.Refresh(pat.PatNum); if(vitalsignList.Count==0) { mu.Details="No vital signs entered."; } else { bool hFound=false; bool wFound=false; for(int v=0;v<vitalsignList.Count;v++) { if(vitalsignList[v].Height>0) { hFound=true; } if(vitalsignList[v].Weight>0) { wFound=true; } } explanation=""; if(!hFound) { explanation+="height";//missing } if(!wFound) { if(explanation!="") { explanation+=", "; } explanation+="weight"; } if(explanation=="") { mu.Details="Vital signs entered"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } } mu.Action="Enter vital signs"; break; #endregion #region VitalSignsBPOnly case EhrMeasureType.VitalSignsBPOnly: vitalsignList=Vitalsigns.Refresh(pat.PatNum); if(pat.Birthdate>DateTime.Today.AddYears(-3)) {//3 and older for BP mu.Details="Age 3 and older for BP."; mu.Met=MuMet.NA; } else if(vitalsignList.Count==0) { mu.Details="No vital signs entered."; } else { for(int v=0;v<vitalsignList.Count;v++) { if(vitalsignList[v].BpDiastolic>0 && vitalsignList[v].BpSystolic>0) { mu.Details="Vital signs entered"; mu.Met=MuMet.True; } else { mu.Details="Missing: blood pressure"; } } } mu.Action="Enter vital signs"; break; #endregion #region Smoking case EhrMeasureType.Smoking: if(pat.SmokingSnoMed=="") {//None mu.Details="Smoking status not entered"; } else { mu.Details="Smoking status entered"; mu.Met=MuMet.True; } mu.Action="Edit smoking status"; break; #endregion #region Lab case EhrMeasureType.Lab: if(ehrLabList.Count==0) { mu.Details="No lab orders"; mu.Met=MuMet.NA; } else { int labResultCount=0; for(int lo=0;lo<ehrLabList.Count;lo++) { List<EhrLabResult> ehrLabResults=EhrLabResults.GetForLab(ehrLabList[lo].EhrLabNum); if(ehrLabResults.Count>0) { labResultCount++; } } if(labResultCount<ehrLabList.Count) { mu.Details="Lab orders missing results: "+(ehrLabList.Count-labResultCount).ToString(); } else { mu.Details="Lab results entered for each lab order."; mu.Met=MuMet.True; } } mu.Action="Edit labs"; break; #endregion #region ElectronicCopy case EhrMeasureType.ElectronicCopy: List<EhrMeasureEvent> listRequests=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ElectronicCopyRequested); List<EhrMeasureEvent> listRequestsPeriod=new List<EhrMeasureEvent>(); for(int r=0;r<listRequests.Count;r++) { if(listRequests[r].DateTEvent<DateTime.Now.AddYears(-1) || listRequests[r].PatNum!=pat.PatNum) {//not within the last year continue; } listRequestsPeriod.Add(listRequests[r]); } if(listRequestsPeriod.Count==0) { mu.Met=MuMet.False; mu.Details="Patient has not viewed/downloaded/transmitted their health info"; } else { mu.Met=MuMet.True; mu.Details="Patient has viewed/downloaded/transmitted their health info"; } mu.Action="Patient must use the Patient Portal"; break; #endregion #region ClinicalSummaries case EhrMeasureType.ClinicalSummaries: List<DateTime> listVisits=new List<DateTime>();//for this year List<Procedure> listProcs=Procedures.Refresh(pat.PatNum); for(int p=0;p<listProcs.Count;p++) { if(listProcs[p].ProcDate < DateTime.Now.AddYears(-1) || listProcs[p].ProcStatus!=ProcStat.C) {//not within the last year or not a completed procedure continue; } if(!listVisits.Contains(listProcs[p].ProcDate)) { listVisits.Add(listProcs[p].ProcDate); } } if(listVisits.Count==0) { mu.Met=MuMet.NA; mu.Details="No visits within the last year."; } else { int countMissing=0; bool summaryProvidedinTime; List<EhrMeasureEvent> listClinSum=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ClinicalSummaryProvidedToPt); for(int p=0;p<listVisits.Count;p++) { summaryProvidedinTime=false; DateTime deadlineDate=listVisits[p].AddDays(1); if(listVisits[p].DayOfWeek==DayOfWeek.Friday) { deadlineDate=deadlineDate.AddDays(2);//add two days for the weekend } for(int r=0;r<listClinSum.Count;r++) { if(listClinSum[r].DateTEvent.Date > deadlineDate) { continue; } if(listClinSum[r].DateTEvent.Date < listVisits[p]) { continue; } summaryProvidedinTime=true; } if(!summaryProvidedinTime) { countMissing++; } } if(countMissing==0) { mu.Met=MuMet.True; mu.Details="Clinical summary provided to Pt within 1 business day of each visit."; } else { mu.Met=MuMet.False; mu.Details="Clinical summaries not provided to Pt within 1 business day of a visit:"+countMissing.ToString(); } } mu.Action="Send clinical summary to Pt"; break; #endregion #region Reminders case EhrMeasureType.Reminders: List<DateTime> listVisitsRem=new List<DateTime>();//for this year List<Procedure> listProcsRem=Procedures.Refresh(pat.PatNum); for(int p=0;p<listProcsRem.Count;p++) { if(listProcsRem[p].ProcDate < DateTime.Now.AddYears(-2) || listProcsRem[p].ProcStatus!=ProcStat.C) {//not within the last year or not a completed procedure continue; } if(!listVisitsRem.Contains(listProcsRem[p].ProcDate)) { listVisitsRem.Add(listProcsRem[p].ProcDate); } } if(listVisitsRem.Count<=1) { mu.Met=MuMet.NA; mu.Details="No two visits within the last two years."; } else if(pat.PatStatus!=PatientStatus.Patient) { mu.Met=MuMet.NA; mu.Details="Status not patient."; } else { List<EhrMeasureEvent> listReminders=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ReminderSent); //during reporting period. bool withinLastYear=false; for(int r=0;r<listReminders.Count;r++) { if(listReminders[r].DateTEvent > DateTime.Now.AddYears(-1)) { withinLastYear=true; } } if(withinLastYear) { mu.Details="Reminder sent within the last year."; mu.Met=MuMet.True; } else { mu.Details="No reminders sent within the last year."; } } mu.Action="Send reminders"; break; #endregion #region MedReconcile case EhrMeasureType.MedReconcile: int countFromRef=0; int countFromRefPeriod=0; for(int c=0;c<listRefAttach.Count;c++) { if(listRefAttach[c].IsFrom && listRefAttach[c].IsTransitionOfCare) { countFromRef++; if(listRefAttach[c].RefDate > DateTime.Now.AddYears(-1)) {//within the last year countFromRefPeriod++; } } } if(countFromRef==0) { mu.Met=MuMet.NA; mu.Details="Referral 'from' not entered."; } else if(countFromRefPeriod==0) { mu.Met=MuMet.NA; mu.Details="Referral 'from' not entered within the last year."; } else if(countFromRefPeriod > 0) { List<EhrMeasureEvent> listReconciles=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.MedicationReconcile); int countReconciles=0;//during reporting period. for(int r=0;r<listReconciles.Count;r++) { if(listReconciles[r].DateTEvent > DateTime.Now.AddYears(-1)) {//within the same period as the count for referrals. countReconciles++; } } mu.Details="Referrals:"+countFromRefPeriod.ToString()+", Reconciles:"+countReconciles.ToString(); if(countReconciles>=countFromRefPeriod) { mu.Met=MuMet.True; } } mu.Action="Reconcile from received CCD"; mu.Action2="Enter Referrals"; break; #endregion #region SummaryOfCare case EhrMeasureType.SummaryOfCare: int countToRefPeriod=0; for(int c=0;c<listRefAttach.Count;c++) { if(!listRefAttach[c].IsFrom && listRefAttach[c].IsTransitionOfCare) { if(listRefAttach[c].RefDate > DateTime.Now.AddYears(-1)) {//within the last year countToRefPeriod++; } } } if(countToRefPeriod==0) { mu.Met=MuMet.NA; mu.Details="No outgoing transitions of care within the last year."; } else {// > 0 List<EhrMeasureEvent> listCcds=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.SummaryOfCareProvidedToDr); int countCcds=0;//during reporting period. for(int r=0;r<listCcds.Count;r++) { if(listCcds[r].DateTEvent > DateTime.Now.AddYears(-1)) {//within the same period as the count for referrals. countCcds++; } } mu.Details="Referrals:"+countToRefPeriod.ToString()+", Summaries:"+countCcds.ToString(); if(countCcds>=countToRefPeriod) { mu.Met=MuMet.True; } } mu.Action="Send/Receive summary of care"; mu.Action2="Enter Referrals"; break; #endregion #region SummaryOfCareElectronic case EhrMeasureType.SummaryOfCareElectronic: countToRefPeriod=0; for(int c=0;c<listRefAttach.Count;c++) { if(!listRefAttach[c].IsFrom && listRefAttach[c].IsTransitionOfCare) { if(listRefAttach[c].RefDate > DateTime.Now.AddYears(-1)) {//within the last year countToRefPeriod++; } } } if(countToRefPeriod==0) { mu.Met=MuMet.NA; mu.Details="No outgoing transitions of care within the last year."; } else {// > 0 List<EhrMeasureEvent> listCcds=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.SummaryOfCareProvidedToDrElectronic); int countCcds=0;//during reporting period. for(int r=0;r<listCcds.Count;r++) { if(listCcds[r].DateTEvent > DateTime.Now.AddYears(-1)) {//within the same period as the count for referrals. countCcds++; } } mu.Details="Referrals:"+countToRefPeriod.ToString()+", Summaries:"+countCcds.ToString(); if(countCcds>=countToRefPeriod) { mu.Met=MuMet.True; } } mu.Action="Send/Receive summary of care via email"; mu.Action2="Enter Referrals"; break; #endregion #region SecureMessaging case EhrMeasureType.SecureMessaging: List<EhrMeasureEvent> listMsg=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.SecureMessageFromPat); List<DateTime> listVisitsMsg=new List<DateTime>();//for this year List<Procedure> listProcsMsg=Procedures.Refresh(pat.PatNum); int msgCount=0; for(int p=0;p<listProcsMsg.Count;p++) { if(listProcsMsg[p].ProcDate < DateTime.Now.AddYears(-1) || listProcsMsg[p].ProcStatus!=ProcStat.C) {//not within the last year or not a completed procedure continue; } if(!listVisitsMsg.Contains(listProcsMsg[p].ProcDate)) { listVisitsMsg.Add(listProcsMsg[p].ProcDate); } } for(int p=0;p<listMsg.Count;p++) { if(listMsg[p].PatNum==pat.PatNum) { msgCount++; } } if(listVisitsMsg.Count==0) { mu.Met=MuMet.NA; mu.Details="No visits within the last year."; } else if(msgCount==0) { mu.Met=MuMet.False; mu.Details="No patient web mail messages."; } else {// > 0 mu.Met=MuMet.True; mu.Details="Web mail message has been received."; } mu.Action="Patient must send a web mail message via the Patient Portal."; break; #endregion #region FamilyHistory case EhrMeasureType.FamilyHistory: List<FamilyHealth> listFamilyHealth=FamilyHealths.GetFamilyHealthForPat(pat.PatNum); if(listFamilyHealth.Count==0) { mu.Met=MuMet.False; mu.Details="No family members entered"; } else {// > 0 mu.Met=MuMet.True; mu.Details="Family Members: "+listFamilyHealth.Count; } mu.Action="Enter family history"; break; #endregion #region ElectronicNote case EhrMeasureType.ElectronicNote: ProcNote procNote=ProcNotes.GetProcNotesForPat(pat.PatNum, DateTime.Now.AddYears(-1), DateTime.Now.AddDays(1)); int notesSigned=0; if(procNote==null) { mu.Met=MuMet.NA; mu.Details="No procedure notes"; } else if(procNote.Signature!="" && procNote.Note!="") { notesSigned++; } if(notesSigned==0) { mu.Met=MuMet.False; mu.Details="Unsigned procedure notes"; } else {// > 0 mu.Met=MuMet.True; mu.Details="Signed procedure note is present"; } mu.Action="Sign all procedure notes"; break; #endregion #region LabImages case EhrMeasureType.LabImages: int labCount=0; int labCountImages=0; List<EhrLab> listEhrLabs=EhrLabs.GetAllForPatInDateRange(pat.PatNum,DateTime.Now.AddYears(-1),DateTime.Now.AddDays(1)); for(int img=0;img<listEhrLabs.Count;img++) { if(EhrLabImages.IsWaitingForImages(listEhrLabs[img].EhrLabNum)) { labCount++; } else if(EhrLabImages.Refresh(listEhrLabs[img].EhrLabNum).Count>0) { labCount++; labCountImages++; } } if(labCount==0) { mu.Met=MuMet.NA; mu.Details="No labs are waiting for images"; } else if(labCount>labCountImages) { mu.Met=MuMet.False; mu.Details="Labs currently waiting on images"; } else if(labCount==labCountImages) { mu.Met=MuMet.True; mu.Details="All labs have images attached"; } mu.Action="Manage Lab Images"; break; #endregion } list.Add(mu); } return list; }
///<summary></summary> public static List<EhrMu> GetMu(Patient pat) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { return Meth.GetObject<List<EhrMu>>(MethodBase.GetCurrentMethod(),pat); } List<EhrMu> list=new List<EhrMu>(); //add one of each type EhrMu mu; string explanation; List<MedicationPat> medList=MedicationPats.Refresh(pat.PatNum,true); List<EhrMeasureEvent> listMeasureEvents=EhrMeasureEvents.Refresh(pat.PatNum); List<RefAttach> listRefAttach=RefAttaches.Refresh(pat.PatNum); for(int i=0;i<Enum.GetValues(typeof(EhrMeasureType)).Length;i++) { mu=new EhrMu(); mu.Met=MuMet.False; mu.MeasureType=(EhrMeasureType)i; switch(mu.MeasureType) { case EhrMeasureType.ProblemList: List<Disease> listDisease=Diseases.Refresh(pat.PatNum); if(listDisease.Count==0){ mu.Details="No problems entered."; } else{ mu.Met=MuMet.True; bool diseasesNone=false; if(listDisease.Count==1 && listDisease[0].DiseaseDefNum==PrefC.GetLong(PrefName.ProblemsIndicateNone)){ diseasesNone=true; } if(diseasesNone){ mu.Details="Problems marked 'none'."; } else{ mu.Details="Problems entered: "+listDisease.Count.ToString(); } } mu.Action="Enter problems"; break; case EhrMeasureType.MedicationList: if(medList.Count==0) { mu.Details="No medications entered."; } else{ mu.Met=MuMet.True; bool medsNone=false; if(medList.Count==1 && medList[0].MedicationNum==PrefC.GetLong(PrefName.MedicationsIndicateNone)) { medsNone=true; } if(medsNone) { mu.Details="Medications marked 'none'."; } else{ mu.Details="Medications entered: "+medList.Count.ToString(); } } mu.Action="Enter medications"; break; case EhrMeasureType.AllergyList: List<Allergy> listAllergies=Allergies.Refresh(pat.PatNum); if(listAllergies.Count==0) { mu.Details="No allergies entered."; } else{ mu.Met=MuMet.True; bool allergiesNone=false; if(listAllergies.Count==1 && listAllergies[0].AllergyDefNum==PrefC.GetLong(PrefName.AllergiesIndicateNone)) { allergiesNone=true; } if(allergiesNone) { mu.Details="Allergies marked 'none'."; } else{ mu.Details="Allergies entered: "+listAllergies.Count.ToString(); } } mu.Action="Enter allergies"; break; case EhrMeasureType.Demographics: explanation=""; if(pat.Birthdate.Year<1880) { explanation+="birthdate";//missing } if(pat.Language=="") { if(explanation!="") { explanation+=", "; } explanation+="language"; } if(pat.Gender==PatientGender.Unknown) { if(explanation!="") { explanation+=", "; } explanation+="gender"; } if(pat.Race==PatientRace.Unknown) { if(explanation!="") { explanation+=", "; } explanation+="race, ethnicity"; } if(explanation=="") { mu.Details="All demographic elements recorded"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } mu.Action="Enter demographics"; break; case EhrMeasureType.Education: List<EhrMeasureEvent> listEd=EhrMeasureEvents.RefreshByType(pat.PatNum,EhrMeasureEventType.EducationProvided); if(listEd.Count==0) { mu.Details="No education resources provided."; } else { mu.Details="Education resources provided: "+listEd.Count.ToString(); mu.Met=MuMet.True; } mu.Action="Provide education resources"; break; case EhrMeasureType.TimelyAccess: List<EhrMeasureEvent> listOnline=EhrMeasureEvents.RefreshByType(pat.PatNum,EhrMeasureEventType.OnlineAccessProvided); if(listOnline.Count==0) { mu.Details="No online access provided."; } else { mu.Details="Online access provided: "+listOnline[listOnline.Count-1].DateTEvent.ToShortDateString();//most recent mu.Met=MuMet.True; } mu.Action="Provide online Access"; break; case EhrMeasureType.ProvOrderEntry: int medOrderCount=0; for(int mo=0;mo<medList.Count;mo++){ if(medList[mo].DateStart.Year>1880 && medList[mo].PatNote!=""){ medOrderCount++; } } if(medList.Count==0) { mu.Met=MuMet.NA; mu.Details="No meds."; } else if(medOrderCount==0) { mu.Details="No medication order in CPOE."; } else { mu.Details="Medications entered in CPOE: "+medOrderCount.ToString(); mu.Met=MuMet.True; } mu.Action="CPOE - Provider Order Entry"; break; case EhrMeasureType.Rx: List<RxPat> listRx=RxPats.GetPermissableForDateRange(pat.PatNum,DateTime.Today.AddYears(-1),DateTime.Today); if(listRx.Count==0){ mu.Met=MuMet.NA; mu.Details="No Rxs entered."; } else{ explanation=""; for(int rx=0;rx<listRx.Count;rx++) { if(listRx[rx].SendStatus==RxSendStatus.SentElect){ continue; } if(explanation!="") { explanation+=", "; } explanation+=listRx[rx].RxDate.ToShortDateString(); } if(explanation=="") { mu.Met=MuMet.True; mu.Details="All Rxs sent electronically."; } else { mu.Met=MuMet.False; mu.Details="Rxs not sent electronically: "+explanation; } } mu.Action="(edit Rxs from Chart)";//no action break; case EhrMeasureType.VitalSigns: List<Vitalsign> vitalsignList=Vitalsigns.Refresh(pat.PatNum); if(vitalsignList.Count==0) { mu.Details="No vital signs entered."; } else { bool hFound=false; bool wFound=false; bool bpFound=false; for(int v=0;v<vitalsignList.Count;v++) { if(vitalsignList[v].Height>0) { hFound=true; } if(vitalsignList[v].Weight>0) { wFound=true; } if(vitalsignList[v].BpDiastolic>0 && vitalsignList[v].BpSystolic>0) { bpFound=true; } } explanation=""; if(!hFound) { explanation+="height";//missing } if(!wFound) { if(explanation!="") { explanation+=", "; } explanation+="weight"; } if(!bpFound) { if(explanation!="") { explanation+=", "; } explanation+="blood pressure"; } if(explanation=="") { mu.Details="Vital signs entered"; mu.Met=MuMet.True; } else { mu.Details="Missing: "+explanation; } } mu.Action="Enter vital signs"; break; case EhrMeasureType.Smoking: if(pat.SmokeStatus==SmokingStatus.UnknownIfEver_Recode9) { mu.Details="Smoking status not entered"; } else { mu.Details="Smoking status entered"; mu.Met=MuMet.True; } mu.Action="Edit smoking status"; break; case EhrMeasureType.Lab: List<MedicalOrder> listLabOrders=MedicalOrders.GetLabsByDate(pat.PatNum,DateTime.Today.AddYears(-1),DateTime.Today); if(listLabOrders.Count==0) { mu.Details="No lab orders"; mu.Met=MuMet.NA; } else { int labPanelCount=0; for(int lo=0;lo<listLabOrders.Count;lo++) { List<LabPanel> listLabPanels=LabPanels.GetPanelsForOrder(listLabOrders[lo].MedicalOrderNum); if(listLabPanels.Count>0) { labPanelCount++; } } if(labPanelCount<listLabOrders.Count) { mu.Details="Lab orders missing results: "+(listLabOrders.Count-labPanelCount).ToString(); } else { mu.Details="Lab results entered for each lab order."; mu.Met=MuMet.True; } } mu.Action="Edit lab panels"; mu.Action2="Import lab results"; break; case EhrMeasureType.ElectronicCopy: List<EhrMeasureEvent> listRequests=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ElectronicCopyRequested); List<EhrMeasureEvent> listRequestsPeriod=new List<EhrMeasureEvent>(); for(int r=0;r<listRequests.Count;r++) { if(listRequests[r].DateTEvent < DateTime.Now.AddYears(-1)) {//not within the last year continue; } listRequestsPeriod.Add(listRequests[r]); } if(listRequestsPeriod.Count==0) { mu.Met=MuMet.NA; mu.Details="No requests within the last year."; } else { int countMissingCopies=0; bool copyProvidedinTime; List<EhrMeasureEvent> listCopiesProvided=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ElectronicCopyProvidedToPt); for(int rp=0;rp<listRequestsPeriod.Count;rp++) { copyProvidedinTime=false; DateTime deadlineDateCopy=listRequestsPeriod[rp].DateTEvent.Date.AddDays(3); if(listRequestsPeriod[rp].DateTEvent.DayOfWeek==DayOfWeek.Wednesday || listRequestsPeriod[rp].DateTEvent.DayOfWeek==DayOfWeek.Thursday || listRequestsPeriod[rp].DateTEvent.DayOfWeek==DayOfWeek.Friday) { deadlineDateCopy.AddDays(2);//add two days for the weekend } for(int cp=0;cp<listCopiesProvided.Count;cp++) { if(listCopiesProvided[cp].DateTEvent.Date > deadlineDateCopy) { continue; } if(listCopiesProvided[cp].DateTEvent.Date < listRequestsPeriod[rp].DateTEvent.Date) { continue; } copyProvidedinTime=true; } if(!copyProvidedinTime) { countMissingCopies++; } } if(countMissingCopies==0) { mu.Met=MuMet.True; mu.Details="Electronic copy provided to Pt within 3 business days of each request."; } else { mu.Met=MuMet.False; mu.Details="Electronic copies not provided to Pt within 3 business days of a request:"+countMissingCopies.ToString(); } } mu.Action="Provide elect copy to Pt"; break; case EhrMeasureType.ClinicalSummaries: List<DateTime> listVisits=new List<DateTime>();//for this year List<Procedure> listProcs=Procedures.Refresh(pat.PatNum); for(int p=0;p<listProcs.Count;p++) { if(listProcs[p].ProcDate < DateTime.Now.AddYears(-1)) {//not within the last year continue; } if(!listVisits.Contains(listProcs[p].ProcDate)) { listVisits.Add(listProcs[p].ProcDate); } } if(listVisits.Count==0){ mu.Met=MuMet.NA; mu.Details="No visits within the last year."; } else{ int countMissing=0; bool summaryProvidedinTime; List<EhrMeasureEvent> listClinSum=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ClinicalSummaryProvidedToPt); for(int p=0;p<listVisits.Count;p++) { summaryProvidedinTime=false; DateTime deadlineDate=listVisits[p].AddDays(3); if(listVisits[p].DayOfWeek==DayOfWeek.Wednesday || listVisits[p].DayOfWeek==DayOfWeek.Thursday || listVisits[p].DayOfWeek==DayOfWeek.Friday){ deadlineDate.AddDays(2);//add two days for the weekend } for(int r=0;r<listClinSum.Count;r++) { if(listClinSum[r].DateTEvent.Date > deadlineDate) { continue; } if(listClinSum[r].DateTEvent.Date < listVisits[p]) { continue; } summaryProvidedinTime=true; } if(!summaryProvidedinTime) { countMissing++; } } if(countMissing==0) { mu.Met=MuMet.True; mu.Details="Clinical summary provided to Pt within 3 business days of each visit."; } else { mu.Met=MuMet.False; mu.Details="Clinical summaries not provided to Pt within 3 business days of a visit:"+countMissing.ToString(); } } mu.Action="Send clinical summary to Pt"; break; case EhrMeasureType.Reminders: if(pat.PatStatus!=PatientStatus.Patient) { mu.Met=MuMet.NA; mu.Details="Status not patient."; } else if(pat.Age==0) { mu.Met=MuMet.NA; mu.Details="Age not entered."; } else if(pat.Age>5 && pat.Age<65) { mu.Met=MuMet.NA; mu.Details="Patient age not 65+ or 5-."; } else { List<EhrMeasureEvent> listReminders=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.ReminderSent); //during reporting period. bool withinLastYear=false; for(int r=0;r<listReminders.Count;r++) { if(listReminders[r].DateTEvent > DateTime.Now.AddYears(-1)) { withinLastYear=true; } } if(withinLastYear) { mu.Details="Reminder sent within the last year."; mu.Met=MuMet.True; } else { mu.Details="No reminders sent within the last year for patient age 65+ or 5-."; } } mu.Action="Send reminders"; break; case EhrMeasureType.MedReconcile: int countFromRef=0; int countFromRefPeriod=0; for(int c=0;c<listRefAttach.Count;c++) { if(listRefAttach[c].IsFrom && listRefAttach[c].IsTransitionOfCare) { countFromRef++; if(listRefAttach[c].RefDate > DateTime.Now.AddYears(-1)) {//within the last year countFromRefPeriod++; } } } if(countFromRef==0) { mu.Met=MuMet.NA; mu.Details="Referral 'from' not entered."; } else if(countFromRefPeriod==0) { mu.Met=MuMet.NA; mu.Details="Referral 'from' not entered within the last year."; } else if(countFromRefPeriod > 0) { List<EhrMeasureEvent> listReconciles=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.MedicationReconcile); int countReconciles=0;//during reporting period. for(int r=0;r<listReconciles.Count;r++) { if(listReconciles[r].DateTEvent > DateTime.Now.AddYears(-1)) {//within the same period as the count for referrals. countReconciles++; } } mu.Details="Referrals:"+countFromRefPeriod.ToString()+", Reconciles:"+countReconciles.ToString(); if(countReconciles>=countFromRefPeriod) { mu.Met=MuMet.True; } } mu.Action="Reconcile medications"; mu.Action2="Enter Referrals"; break; case EhrMeasureType.SummaryOfCare: int countToRefPeriod=0; for(int c=0;c<listRefAttach.Count;c++) { if(!listRefAttach[c].IsFrom && listRefAttach[c].IsTransitionOfCare) { if(listRefAttach[c].RefDate > DateTime.Now.AddYears(-1)) {//within the last year countToRefPeriod++; } } } if(countToRefPeriod==0) { mu.Met=MuMet.NA; mu.Details="No outgoing transitions of care within the last year."; } else{// > 0 List<EhrMeasureEvent> listCcds=EhrMeasureEvents.GetByType(listMeasureEvents,EhrMeasureEventType.SummaryOfCareProvidedToDr); int countCcds=0;//during reporting period. for(int r=0;r<listCcds.Count;r++) { if(listCcds[r].DateTEvent > DateTime.Now.AddYears(-1)) {//within the same period as the count for referrals. countCcds++; } } mu.Details="Referrals:"+countToRefPeriod.ToString()+", Summaries:"+countCcds.ToString(); if(countCcds>=countToRefPeriod) { mu.Met=MuMet.True; } } mu.Action="Send/Receive summary of care"; mu.Action2="Enter Referrals"; break; } list.Add(mu); } return list; }