示例#1
0
		///<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;
		}
示例#2
0
		///<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;
		}
示例#3
0
 ///<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;
 }