Example #1
0
		///<summary></summary>
		public static long Insert(RxPat rx) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				rx.RxNum=Meth.GetLong(MethodBase.GetCurrentMethod(),rx);
				return rx.RxNum;
			}
			return Crud.RxPatCrud.Insert(rx);
		}
Example #2
0
		///<summary></summary>
		public FormRxEdit(Patient patCur,RxPat rxPatCur){
			//){//
			InitializeComponent();
			RxPatCur=rxPatCur;
			PatCur=patCur;
			Lan.F(this);
		}
Example #3
0
		///<summary></summary>
		public static void Update(RxPat rx) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				Meth.GetVoid(MethodBase.GetCurrentMethod(),rx);
				return;
			}
			Crud.RxPatCrud.Update(rx);
		}
Example #4
0
 public static long InsertOrUpdateErxMedication(RxPat rxOld, RxPat rx, long rxCui, string strDrugName, string strGenericName, bool isProv, bool canInsertRx = true)
 {
     if (rxOld == null)
     {
         if (canInsertRx)
         {
             rx.IsNew    = true;               //Might not be necessary, but does not hurt.
             rx.IsErxOld = false;
             SecurityLogs.MakeLogEntry(Permissions.RxCreate, rx.PatNum, "eRx automatically created: " + rx.Drug);
             RxPats.Insert(rx);
         }
     }
     else              //The prescription was already in our database. Update it.
     {
         rx.RxNum = rxOld.RxNum;
         //Preserve the pharmacy on the existing prescription, in case the user set the value manually.
         //We do not pull pharmacy back from eRx yet.
         rx.PharmacyNum = rxOld.PharmacyNum;
         if (rxOld.IsErxOld)
         {
             rx.IsErxOld   = true;
             rx.SendStatus = RxSendStatus.SentElect;                  //To maintain backward compatibility.
         }
         RxPats.Update(rx);
     }
     //If rxCui==0, then third party eRx option (DoseSpot, NewCrop, etc) did not provide an RxCui.
     //Attempt to locate an RxCui using the other provided drug information.  An RxCui is not required for our program.
     //Meds missing an RxCui are not exported in CCD messages.
     if (rxCui == 0 && strDrugName != "")
     {
         List <RxNorm> listRxNorms = RxNorms.GetListByCodeOrDesc(strDrugName, true, true);           //Exact case insensitive match ignoring numbers.
         if (listRxNorms.Count > 0)
         {
             rxCui = PIn.Long(listRxNorms[0].RxCui);
         }
     }
     //If rxCui==0, then third party eRx option (DoseSpot, NewCrop, etc) did not provide an RxCui and we could not locate an RxCui by DrugName
     //Try searching by GenericName.
     if (rxCui == 0 && strGenericName != "")
     {
         List <RxNorm> listRxNorms = RxNorms.GetListByCodeOrDesc(strGenericName, true, true);           //Exact case insensitive match ignoring numbers.
         if (listRxNorms.Count > 0)
         {
             rxCui = PIn.Long(listRxNorms[0].RxCui);
         }
     }
     //If rxCui==0, then third party eRx option (DoseSpot, NewCrop, etc) did not provide an RxCui and we could not
     //locate an RxCui by DrugName or GenericName.
     if (rxCui == 0)
     {
         //We may need to enhance in future to support more advanced RxNorm searches.
         //For example: DrugName=Cafatine, DrugInfo=Cafatine 1 mg-100 mg Tab, GenericName=ergotamine-caffeine.
         //This drug could not be found by DrugName nor GenericName, but could be found when the GenericName was split by non-alpha characters,
         //then the words in the generic name were swapped.
         //Namely, "caffeine ergotamine" is in the RxNorm table.
     }
     //MedicationNum of 0, because we do not want to bloat the medication list in OD.
     //In this special situation, we instead set the MedDescript, RxCui and ErxGuid columns.
     return(MedicationPats.InsertOrUpdateMedOrderForRx(rx, rxCui, isProv));
 }
Example #5
0
		///<summary>For CPOE.  Used for both manual rx and eRx through NewCrop.  Creates or updates a medical order using the given prescription information.
		///Since rxCui is not part of the prescription, it must be passed in as a separate parameter.
		///If isProvOrder is true, then the medical order provNum will be set to the prescription provNum.  If isProvOrder is false, then the medical order provNum will be set to 0.
		///The MedDescript and NewCropGuid will always be copied from the prescription to the medical order and the medical order MedicationNum will be set to 0.
		///This method return the medOrderNum for the new/updated medicationPat. Unlike most medical orders this does not create an entry in the medical order table.</summary>
		public static long InsertOrUpdateMedOrderForRx(RxPat rxPat,long rxCui,bool isProvOrder) {
			long medOrderNum;
			MedicationPat medOrder=new MedicationPat();//The medication order corresponding to the prescription.
			medOrder.DateStart=rxPat.RxDate;
			medOrder.DateStop=rxPat.RxDate.AddDays(7);//Is there a way to easily calculate this information from the prescription information? The medical order will be inactive after this date.
			medOrder.MedDescript=rxPat.Drug;
			medOrder.RxCui=rxCui;
			medOrder.NewCropGuid=rxPat.NewCropGuid;
			medOrder.PatNote=rxPat.Sig;
			medOrder.PatNum=rxPat.PatNum;
			if(isProvOrder) {
				medOrder.ProvNum=rxPat.ProvNum;
				medOrder.IsCpoe=true;
			}
			MedicationPat medOrderOld=null;
			if(!String.IsNullOrEmpty(rxPat.NewCropGuid)) { //This check prevents an extra db call when the order is being created for a prescription written from inside of OD manually instead of using NewCrop.
				medOrderOld=MedicationPats.GetMedicationOrderByNewCropGuid(rxPat.NewCropGuid);
			}
			if(medOrderOld==null) {
				medOrder.IsNew=true;//Might not be necessary, but does not hurt.
				medOrderNum=MedicationPats.Insert(medOrder);
			}
			else {//The medication order was already in our database. Update it.
				medOrder.MedicationPatNum=medOrderOld.MedicationPatNum;
				MedicationPats.Update(medOrder);
				medOrderNum=medOrder.MedicationPatNum;
			}
			return medOrderNum;
		}
Example #6
0
 public static bool Update(RxPat rx, RxPat oldRx)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         return(Meth.GetBool(MethodBase.GetCurrentMethod(), rx, oldRx));
     }
     return(Crud.RxPatCrud.Update(rx, oldRx));
 }
Example #7
0
 ///<summary></summary>
 public static long Insert(RxPat rx)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         rx.RxNum = Meth.GetLong(MethodBase.GetCurrentMethod(), rx);
         return(rx.RxNum);
     }
     return(Crud.RxPatCrud.Insert(rx));
 }
Example #8
0
 ///<summary></summary>
 public static void Update(RxPat rx)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         Meth.GetVoid(MethodBase.GetCurrentMethod(), rx);
         return;
     }
     Crud.RxPatCrud.Update(rx);
 }
Example #9
0
        ///<summary></summary>
        public RxPat Copy()
        {
            RxPat r = new RxPat();

            r.RxNum   = RxNum;
            r.PatNum  = PatNum;
            r.RxDate  = RxDate;
            r.Drug    = Drug;
            r.Sig     = Sig;
            r.Disp    = Disp;
            r.Refills = Refills;
            r.ProvNum = ProvNum;
            r.Notes   = Notes;
            return(r);
        }
Example #10
0
 private void butBlank_Click(object sender, System.EventArgs e)
 {
     RxPat RxPatCur=new RxPat();
     RxPatCur.RxDate=DateTime.Today;
     RxPatCur.PatNum=PatCur.PatNum;
     if(PrefC.GetBool(PrefName.RxSendNewToQueue)) {
         RxPatCur.SendStatus=RxSendStatus.InElectQueue;
     }
     else {
         RxPatCur.SendStatus=RxSendStatus.Unsent;
     }
     FormRxEdit FormE=new FormRxEdit(PatCur,RxPatCur);
     FormE.IsNew=true;
     FormE.ShowDialog();
     if(FormE.DialogResult!=DialogResult.OK){
         return;
     }
     DialogResult=DialogResult.OK;
 }
Example #11
0
        ///<summary>For CPOE.  Used for both manual rx and eRx through NewCrop.  Creates or updates a medical order using the given prescription information.
        ///Since rxCui is not part of the prescription, it must be passed in as a separate parameter.
        ///If isProvOrder is true, then the medical order provNum will be set to the prescription provNum.  If isProvOrder is false, then the medical order provNum will be set to 0.
        ///The MedDescript and NewCropGuid will always be copied from the prescription to the medical order and the medical order MedicationNum will be set to 0.
        ///This method return the medOrderNum for the new/updated medicationPat. Unlike most medical orders this does not create an entry in the medical order table.</summary>
        public static long InsertOrUpdateMedOrderForRx(RxPat rxPat, long rxCui, bool isProvOrder)
        {
            long          medOrderNum;
            MedicationPat medOrder = new MedicationPat();          //The medication order corresponding to the prescription.

            medOrder.DateStart   = rxPat.RxDate;
            medOrder.DateStop    = rxPat.RxDate.AddDays(7);       //Is there a way to easily calculate this information from the prescription information? The medical order will be inactive after this date.
            medOrder.MedDescript = rxPat.Drug;
            medOrder.RxCui       = rxCui;
            medOrder.NewCropGuid = rxPat.NewCropGuid;
            medOrder.PatNote     = rxPat.Sig;
            medOrder.PatNum      = rxPat.PatNum;
            if (isProvOrder)
            {
                medOrder.ProvNum = rxPat.ProvNum;
                medOrder.IsCpoe  = true;
            }
            MedicationPat medOrderOld = null;

            if (!String.IsNullOrEmpty(rxPat.NewCropGuid))              //This check prevents an extra db call when the order is being created for a prescription written from inside of OD manually instead of using NewCrop.
            {
                medOrderOld = MedicationPats.GetMedicationOrderByNewCropGuid(rxPat.NewCropGuid);
            }
            if (medOrderOld == null)
            {
                medOrder.IsNew = true;              //Might not be necessary, but does not hurt.
                medOrderNum    = MedicationPats.Insert(medOrder);
            }
            else              //The medication order was already in our database. Update it.
            {
                medOrder.MedicationPatNum = medOrderOld.MedicationPatNum;
                MedicationPats.Update(medOrder);
                medOrderNum = medOrder.MedicationPatNum;
            }
            return(medOrderNum);
        }
Example #12
0
		/// <summary>For testing only</summary>
		private static void CreatePrescriptions(int PrescriptionCount) {
			long[] patNumArray=Patients.GetAllPatNums();
			for(int i=0;i<patNumArray.Length;i++) {
				for(int j=0;j<PrescriptionCount;j++) {
					RxPat rxpat= new RxPat();
					rxpat.Drug="VicodinA VicodinB VicodinC"+j;
					rxpat.Disp="50.50";
					rxpat.IsControlled=true;
					rxpat.PatNum=patNumArray[i];
					rxpat.RxDate=new DateTime(2010,12,1,11,0,0);
					RxPats.Insert(rxpat);
				}
			}
		}
Example #13
0
		private void FormRxEdit_Load(object sender, System.EventArgs e) {
			_rxPatOld=RxPatCur.Copy();
			if(IsNew){
				butAudit.Visible=false;
				butView.Visible=false;
				labelView.Visible=false;
				sheet=null;
				if(PrefC.GetBool(PrefName.ShowFeatureEhr) && Security.CurUser.ProvNum!=0) {//Is CPOE
					labelCPOE.Visible=true;
					comboProvNum.Enabled=false;
					butPickProv.Enabled=false;
					RxPatCur.ProvNum=Security.CurUser.ProvNum;
				}
			}
			else{
				sheet=Sheets.GetRx(RxPatCur.PatNum,RxPatCur.RxNum);
				if(sheet==null){
					butView.Visible=false;
					labelView.Visible=false;
				}
				else{
					butPrint.Visible=false;
				}
				if(!Security.IsAuthorized(Permissions.RxEdit)) {
					textDate.Enabled=false;
					checkControlled.Enabled=false;
					textDrug.Enabled=false;
					textSig.Enabled=false;
					textDisp.Enabled=false;
					textRefills.Enabled=false;
					comboProvNum.Enabled=false;
					butPickProv.Enabled=false;
					textDosageCode.Enabled=false;
					textNotes.Enabled=false;
					butPick.Enabled=false;
					comboSendStatus.Enabled=false;
					butDelete.Enabled=false;
				}
			}
			//security is handled on the Rx button click in the Chart module
			_provNumSelected=RxPatCur.ProvNum;
			comboProvNum.Items.Clear();
			for(int i=0;i<ProviderC.ListShort.Count;i++) {
				comboProvNum.Items.Add(ProviderC.ListShort[i].GetLongDesc());//Only visible provs added to combobox.
				if(ProviderC.ListShort[i].ProvNum==RxPatCur.ProvNum) {
					comboProvNum.SelectedIndex=i;//Sets combo text too.
				}
			}
			if(_provNumSelected==0) {//Is new
				comboProvNum.SelectedIndex=0;
				_provNumSelected=ProviderC.ListShort[0].ProvNum;
			}
			if(comboProvNum.SelectedIndex==-1) {//The provider exists but is hidden
				comboProvNum.Text=Providers.GetLongDesc(_provNumSelected);//Appends "(hidden)" to the end of the long description.
			}
			textDate.Text=RxPatCur.RxDate.ToString("d");
			checkControlled.Checked=RxPatCur.IsControlled;
			for(int i=0;i<Enum.GetNames(typeof(RxSendStatus)).Length;i++) {
				comboSendStatus.Items.Add(Enum.GetNames(typeof(RxSendStatus))[i]);
			}
			comboSendStatus.SelectedIndex=(int)RxPatCur.SendStatus;
			textDrug.Text=RxPatCur.Drug;
			textSig.Text=RxPatCur.Sig;
			textDisp.Text=RxPatCur.Disp;
			textRefills.Text=RxPatCur.Refills;
			if(PrefC.GetBool(PrefName.ShowFeatureEhr)){
				textDosageCode.Text=RxPatCur.DosageCode;
			}
			else{
				labelDosageCode.Visible=false;
				textDosageCode.Visible=false;
			}
			textNotes.Text=RxPatCur.Notes;
			textPharmacy.Text=Pharmacies.GetDescription(RxPatCur.PharmacyNum);
		}
Example #14
0
		private void RxSelected(){
			if(gridMain.GetSelectedIndex()==-1) {
				//this should never happen
				return;
			}
			RxDef RxDefCur=RxDefList[gridMain.GetSelectedIndex()];
			if(PrefC.GetBool(PrefName.ShowFeatureEhr) && RxDefCur.RxCui==0) {
				string strMsgText=Lan.g(this,"The selected prescription is missing an RxNorm")+".\r\n"
					+Lan.g(this,"Prescriptions without RxNorms cannot be exported in EHR documents")+".\r\n"
					+Lan.g(this,"Edit RxNorm in Rx Template?");
				if(MsgBox.Show(this,true,strMsgText)) {
					FormRxDefEdit form=new FormRxDefEdit(RxDefCur);
					form.ShowDialog();
					RxDefCur=RxDefs.GetOne(RxDefCur.RxDefNum);//FormRxDefEdit does not modify the RxDefCur object, so we must get the updated RxCui from the db.
				}
			}
			//Alert
			if(!RxAlertL.DisplayAlerts(PatCur.PatNum,RxDefCur.RxDefNum)){
				return;
			}
			//User OK with alert
			RxPat RxPatCur=new RxPat();
			RxPatCur.RxDate=DateTime.Today;
			RxPatCur.PatNum=PatCur.PatNum;
			RxPatCur.Drug=RxDefCur.Drug;
			RxPatCur.IsControlled=RxDefCur.IsControlled;
			RxPatCur.Sig=RxDefCur.Sig;
			RxPatCur.Disp=RxDefCur.Disp;
			RxPatCur.Refills=RxDefCur.Refills;
			if(PrefC.GetBool(PrefName.RxSendNewToQueue)) {
				RxPatCur.SendStatus=RxSendStatus.InElectQueue;
			}
			else {
				RxPatCur.SendStatus=RxSendStatus.Unsent;
			}
			//Notes not copied: we don't want these kinds of notes cluttering things
			FormRxEdit FormE=new FormRxEdit(PatCur,RxPatCur);
			FormE.IsNew=true;
			FormE.ShowDialog();
			if(FormE.DialogResult!=DialogResult.OK){
				return;
			}
			bool isProvOrder=false;
			if(Security.CurUser.ProvNum!=0) {//The user who is currently logged in is a provider.
				isProvOrder=true;
			}
			_medOrderNum=MedicationPats.InsertOrUpdateMedOrderForRx(RxPatCur,RxDefCur.RxCui,isProvOrder);//RxDefCur.RxCui can be 0.
			EhrMeasureEvent newMeasureEvent=new EhrMeasureEvent();
			newMeasureEvent.DateTEvent=DateTime.Now;
			newMeasureEvent.EventType=EhrMeasureEventType.CPOE_MedOrdered;
			newMeasureEvent.PatNum=PatCur.PatNum;
			newMeasureEvent.MoreInfo="";
			newMeasureEvent.FKey=_medOrderNum;
			EhrMeasureEvents.Insert(newMeasureEvent);
			DialogResult=DialogResult.OK;
		}
Example #15
0
		private void butBlank_Click(object sender, System.EventArgs e) {
			RxPat RxPatCur=new RxPat();
			RxPatCur.RxDate=DateTime.Today;
			RxPatCur.PatNum=PatCur.PatNum;
			if(PrefC.GetBool(PrefName.RxSendNewToQueue)) {
				RxPatCur.SendStatus=RxSendStatus.InElectQueue;
			}
			else {
				RxPatCur.SendStatus=RxSendStatus.Unsent;
			}
			FormRxEdit FormE=new FormRxEdit(PatCur,RxPatCur);
			FormE.IsNew=true;
			FormE.ShowDialog();
			if(FormE.DialogResult!=DialogResult.OK){
				return;
			}
			//We do not need to make a medical order here, because butBlank is not visible in EHR mode.
			DialogResult=DialogResult.OK;
		}
Example #16
0
File: RxPats.cs Project: mnisl/OD
		public static bool Update(RxPat rx,RxPat oldRx) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				return Meth.GetBool(MethodBase.GetCurrentMethod(),rx,oldRx);
			}
			return Crud.RxPatCrud.Update(rx,oldRx);
		}
Example #17
0
 private static void FillFieldsForRx(Sheet sheet,RxPat rx,Patient pat,Provider prov)
 {
     Clinic clinic=null;
     if(pat.ClinicNum != 0) {
         clinic=Clinics.GetClinic(pat.ClinicNum);
     }
     string text;
     foreach(SheetField field in sheet.SheetFields) {
         switch(field.FieldName) {
             case "prov.nameFL":
                 field.FieldValue=prov.GetFormalName();
                 break;
             case "prov.address":
                 if(clinic==null) {
                     field.FieldValue=PrefC.GetString(PrefName.PracticeAddress);
                     if(PrefC.GetString(PrefName.PracticeAddress2)!="") {
                         field.FieldValue+="\r\n"+PrefC.GetString(PrefName.PracticeAddress2);
                     }
                 }
                 else{
                     field.FieldValue=clinic.Address;
                     if(clinic.Address2!="") {
                         field.FieldValue+="\r\n"+clinic.Address2;
                     }
                 }
                 break;
             case "prov.cityStateZip":
                 if(clinic==null) {
                     field.FieldValue=PrefC.GetString(PrefName.PracticeCity)+", "+PrefC.GetString(PrefName.PracticeST)+" "+PrefC.GetString(PrefName.PracticeZip);
                 }
                 else {
                     field.FieldValue=clinic.City+", "+clinic.State+" "+clinic.Zip;
                 }
                 break;
             case "prov.phone":
                 if(clinic==null) {
                     text=PrefC.GetString(PrefName.PracticePhone);
                 }
                 else {
                     text=clinic.Phone;
                 }
                 field.FieldValue=text;
                 if(text.Length==10) {
                     field.FieldValue="("+text.Substring(0,3)+")"+text.Substring(3,3)+"-"+text.Substring(6);
                 }
                 break;
             case "RxDate":
                 field.FieldValue=rx.RxDate.ToShortDateString();
                 break;
             case "RxDateMonthSpelled":
                 field.FieldValue=rx.RxDate.ToString("MMM dd,yyyy");
                 break;
             case "prov.dEANum":
                 if(rx.IsControlled){
                     field.FieldValue=prov.DEANum;
                 }
                 else{
                     field.FieldValue="";
                 }
                 break;
             case "pat.nameFL":
                 //Can't include preferred, so:
                 field.FieldValue=pat.FName+" "+pat.MiddleI+"  "+pat.LName;
                 break;
             case "pat.Birthdate":
                 if(pat.Birthdate.Year<1880){
                     field.FieldValue="";
                 }
                 else{
                     field.FieldValue=pat.Birthdate.ToShortDateString();
                 }
                 break;
             case "pat.HmPhone":
                 field.FieldValue=pat.HmPhone;
                 break;
             case "pat.address":
                 field.FieldValue=pat.Address;
                 if(pat.Address2!=""){
                     field.FieldValue+="\r\n"+pat.Address2;
                 }
                 break;
             case "pat.cityStateZip":
                 field.FieldValue=pat.City+", "+pat.State+" "+pat.Zip;
                 break;
             case "Drug":
                 field.FieldValue=rx.Drug;
                 break;
             case "Disp":
                 field.FieldValue=rx.Disp;
                 break;
             case "Sig":
                 field.FieldValue=rx.Sig;
                 break;
             case "Refills":
                 field.FieldValue=rx.Refills;
                 break;
             case "prov.stateRxID":
                 field.FieldValue=prov.StateRxID;
                 break;
         }
     }
 }
Example #18
0
		///<summary>Returns true if new information was pulled back from NewCrop.</summary>
		private bool NewCropRefreshPrescriptions() {
			Program programNewCrop=Programs.GetCur(ProgramName.NewCrop);
			if(!programNewCrop.Enabled) {
				return false;
			}
			if(PatCur==null) {
				return false;
			}
			string newCropAccountId=PrefC.GetString(PrefName.NewCropAccountId);
			if(newCropAccountId=="") {//We check for NewCropAccountID validity below, but we also need to be sure to exit this check for resellers if blank.
				return false;
			}
			if(!NewCropIsAccountIdValid()) {
				//The NewCropAccountID will be invalid for resellers, because the checksum will be wrong.
				//Therefore, resellers should be allowed to continue if both the NewCropName and NewCropPassword are specified. NewCrop does not allow blank passwords.
				if(PrefC.GetString(PrefName.NewCropName)=="" || PrefC.GetString(PrefName.NewCropPassword)=="") {
					return false;
				}
			}
			NewCrop.Update1 wsNewCrop=new NewCrop.Update1();//New Crop web services interface.
			NewCrop.Credentials credentials=new NewCrop.Credentials();
			NewCrop.AccountRequest accountRequest=new NewCrop.AccountRequest();
			NewCrop.PatientRequest patientRequest=new NewCrop.PatientRequest();
			NewCrop.PrescriptionHistoryRequest prescriptionHistoryRequest=new NewCrop.PrescriptionHistoryRequest();
			NewCrop.PatientInformationRequester patientInfoRequester=new NewCrop.PatientInformationRequester();
			NewCrop.Result response=new NewCrop.Result();
#if DEBUG
			wsNewCrop.Url="https://preproduction.newcropaccounts.com/v7/WebServices/Update1.asmx";
#endif
			credentials.PartnerName=ErxXml.NewCropPartnerName;
			credentials.Name=ErxXml.NewCropAccountName;
			credentials.Password=ErxXml.NewCropAccountPasssword;
			accountRequest.AccountId=newCropAccountId;
			accountRequest.SiteId="1";//Accounts are always created with SiteId=1.
			patientRequest.PatientId=POut.Long(PatCur.PatNum);
			prescriptionHistoryRequest.StartHistory=new DateTime(2012,11,2);//Only used for archived prescriptions. This is the date of first release for NewCrop integration.
			prescriptionHistoryRequest.EndHistory=DateTime.Now;//Only used for archived prescriptions.
			//Prescription Archive Status Values:
			//N = Not archived (i.e. Current Medication) 
			//Y = Archived (i.e. Previous Mediation)
			//% = Both Not Archived and Archived
			//Note: This field will contain values other than Y,N in future releases.
			prescriptionHistoryRequest.PrescriptionArchiveStatus="N";
			//Prescription Status Values:
			//C = Completed Prescription
			//P = Pending Medication
			//% = Both C and P.
			prescriptionHistoryRequest.PrescriptionStatus="C";
			//Prescription Sub Status Values:
			//% = All meds (Returns all meds regardless of the sub status)
			//A = NS (Returns only meds that have a 'NS' - Needs staff sub status)
			//U = DR (Returns only meds that have a 'DR' - Needs doctor review sub status)
			//P = Renewal Request that has been selected for processing on the NewCrop screens - it has not yet been denied, denied and re-written or accepted
			//S = Standard Rx (Returns only meds that have an 'InProc' - InProcess sub status)
			//D = DrugSet source - indicates the prescription was created by selecting the medication from the DrugSet selection box on the ComposeRx page
			//O = Outside Prescription - indicates the prescription was created on the MedEntry page, not prescribed.
			prescriptionHistoryRequest.PrescriptionSubStatus="S";
			patientInfoRequester.UserType="Staff";//Allowed values: Doctor,Staff
			if(Security.CurUser.ProvNum!=0) {//If the current OD user is associated to a doctor, then the request is from a doctor, otherwise from a staff member.
			  patientInfoRequester.UserType="Doctor";
			}
			patientInfoRequester.UserId=POut.Long(Security.CurUser.UserNum);
			//Send the request to NewCrop. Always returns all current medications, and returns medications between the StartHistory and EndHistory dates if requesting archived medications.
			//The patientIdType parameter was added for another vendor and is not often used. We do not use this field. We must pass empty string.
			//The includeSchema parameter is useful for first-time debugging, but in release mode, we should pass N for no.
			wsNewCrop.Timeout=3000;//3 second. The default is 100 seconds, but we cannot wait that long, because prescriptions are checked each time the Chart is refreshed. 1 second is too little, 2 seconds works most of the time. 3 seconds is safe.
			try {
				response=wsNewCrop.GetPatientFullMedicationHistory6(credentials,accountRequest,patientRequest,prescriptionHistoryRequest,patientInfoRequester,"","N");
			}
			catch { //An exception is thrown when the timeout is reached, or when the NewCrop servers are not accessible (because the servers are down, or because local internet is down).
				//We used to show a popup here, but users found it annoying when the NewCrop severs were down.
				//Instead, we now silently log a warning message into the Application log within the system EventViewer, so it is not annoying, but there is a way for the user to know if there was a problem.
				if(!EventLog.SourceExists("OpenDental")) {
					EventLog.CreateEventSource("OpenDental","Application");
				}
				EventLog.WriteEntry("OpenDental","Failed to communicate with NewCrop to retrieve completed prescription information. "
					+"A firewall or antivirus application might be blocking Open Dental, or this computer might not be able to see secure.newcropaccounts.com due to a network name resolution (DNS) issue. "
					+"If you do not use electronic prescriptions, consider disabling the NewCrop program link in Setup | Program Links.",EventLogEntryType.Warning);
				return false;
			}
			//response.Message = Error message if error.
			//response.RowCount = Number of prescription records returned.
			//response.Status = Status of request. "OK" = success.
			//response.Timing = Not sure what this is for. Tells us how quickly the server responded to the request?
			//response.XmlResponse = The XML data returned, encoded in base 64.
			if(response.Status!=NewCrop.StatusType.OK) {//Other statuses include Fail (ex if credentials are invalid), NotFound (ex if patientId invalid or accoundId invalid), Unknown (no known examples yet)
				//For now we simply abort gracefully.
				return false;
			}
			byte[] xmlResponseBytes=Convert.FromBase64String(response.XmlResponse);
			string xmlResponse=Encoding.UTF8.GetString(xmlResponseBytes);
#if DEBUG//For capturing the xmlReponse with the newlines properly showing.
			string tempFile=ODFileUtils.CreateRandomFile(Path.GetTempPath(),".txt");
			File.WriteAllText(tempFile,xmlResponse);
#endif
			XmlDocument xml=new XmlDocument();
			try {
				xml.LoadXml(xmlResponse);
			}
			catch { //In case NewCrop returns invalid XML.
				return false;//abort gracefully
			}
			DateTime rxStartDateT=PrefC.GetDateT(PrefName.ElectronicRxDateStartedUsing131);
			XmlNode nodeNewDataSet=xml.FirstChild;
			foreach(XmlNode nodeTable in nodeNewDataSet.ChildNodes) {
				RxPat rxOld=null;
				MedicationPat medOrderOld=null;
				RxPat rx=new RxPat();
				//rx.IsControlled not important.  Only used in sending, but this Rx was already sent.
				rx.Disp="";
				rx.DosageCode="";
				rx.Drug="";
				rx.Notes="";
				rx.Refills="";
				rx.SendStatus=RxSendStatus.SentElect;
				rx.Sig="";
				string additionalSig="";
				bool isProv=true;
				long rxCui=0;
				string strDrugName="";
				string strGenericName="";
				string strProvNumOrNpi="";//We used to send ProvNum in LicensedPrescriber.ID to NewCrop, but now we send NPI. We will receive ProvNum for older prescriptions.
				foreach(XmlNode nodeRxFieldParent in nodeTable.ChildNodes) {
					XmlNode nodeRxField=nodeRxFieldParent.FirstChild;
					if(nodeRxField==null) {
						continue;
					}
					switch(nodeRxFieldParent.Name.ToLower()) {
						case "dispense"://ex 5.555
							rx.Disp=nodeRxField.Value;
							break;
						case "druginfo"://ex lisinopril 5 mg Tab
							rx.Drug=nodeRxField.Value;
							break;
						case "drugname"://ex lisinopril
							strDrugName=nodeRxField.Value;
							break;
						case "externalpatientid"://patnum passed back from the compose request that initiated this prescription
							rx.PatNum=PIn.Long(nodeRxField.Value);
							break;
						case "externalphysicianid"://NPI passed back from the compose request that initiated this prescription.  For older prescriptions, this will be ProvNum.
							strProvNumOrNpi=nodeRxField.Value;
							break;
						case "externaluserid"://The person who ordered the prescription. Is a ProvNum when provider, or an EmployeeNum when an employee. If EmployeeNum, then is prepended with "emp" because of how we sent it to NewCrop in the first place.
							if(nodeRxField.Value.StartsWith("emp")) {
								isProv=false;
							}
							break;
						case "genericname":
							strGenericName=nodeRxField.Value;
							break;
						case "patientfriendlysig"://The concat of all the codified fields.
							rx.Sig=nodeRxField.Value;
							break;
						case "pharmacyncpdp"://ex 9998888
							//We will use this information in the future to find a pharmacy already entered into OD, or to create one dynamically if it does not exist.
							//rx.PharmacyNum;//Get the pharmacy where pharmacy.PharmID = node.Value
							break;
						case "prescriptiondate":
							rx.RxDate=PIn.DateT(nodeRxField.Value);
							break;
						case "prescriptionguid"://32 characters with 4 hyphens. ex ba4d4a84-af0a-4cbf-9437-36feda97d1b6
							rx.NewCropGuid=nodeRxField.Value;
							rxOld=RxPats.GetRxNewCrop(nodeRxField.Value);
							medOrderOld=MedicationPats.GetMedicationOrderByNewCropGuid(nodeRxField.Value);
							break;
						case "prescriptionnotes"://from the Additional Sig box at the bottom
							additionalSig=nodeRxField.Value;
							break;
						case "refills"://ex 1
							rx.Refills=nodeRxField.Value;
							break;
						case "rxcui"://ex 311354
							rxCui=PIn.Long(nodeRxField.Value);//The RxCui is not returned with all prescriptions, so it can be zero (not set).
							break;						
					}
				}//end inner foreach
				if(rx.RxDate<rxStartDateT) {//Ignore prescriptions created before version 13.1.14, because those prescriptions were entered manually by the user.
					continue;
				}
				if(additionalSig!="") {
					if(rx.Sig!="") {//If patient friend SIG is present.
						rx.Sig+=" ";
					}
					rx.Sig+=additionalSig;
				}
				//Determine the provider. This is a mess, because we used to send ProvNum in the outgoing XML LicensedPrescriber.ID,
				//but now we send NPI to avoid multiple billing charges for two provider records with the same NPI
				//(the same doctor entered multiple times, for example, one provider for each clinic).
				ErxLog erxLog=ErxLogs.GetLatestForPat(rx.PatNum,rx.RxDate);//Locate the original request corresponding to this prescription.
				if((erxLog==null || erxLog.ProvNum==0)) {//Not found or the provnum is unknown.
					//The erxLog.ProvNum will be 0 for prescriptions fetched from NewCrop before version 13.3. Could also happen if
					//prescriptions were created when NewCrop was brand new (right before ErxLog was created),
					//or if someone lost a database and they are downloading all the prescriptions from scratch again.
					if(rxOld==null) {//The prescription is being dowloaded for the first time, or is being downloaded again after it was deleted manually by the user.
						for(int j=0;j<ProviderC.ListShort.Count;j++) {//Try to locate a visible provider matching the NPI on the prescription.
							if(strProvNumOrNpi.Length==10 && ProviderC.ListShort[j].NationalProvID==strProvNumOrNpi) {
								rx.ProvNum=ProviderC.ListShort[j].ProvNum;
								break;
							}
						}
						if(rx.ProvNum==0) {//No visible provider found matching the NPI on the prescription.
							for(int j=0;j<ProviderC.ListLong.Count;j++) {//Try finding a hidden provider matching the NPI on the prescription, or a matching provnum.
								if(strProvNumOrNpi.Length==10 && ProviderC.ListLong[j].NationalProvID==strProvNumOrNpi) {
									rx.ProvNum=ProviderC.ListLong[j].ProvNum;
									break;
								}
								if(ProviderC.ListLong[j].ProvNum.ToString()==strProvNumOrNpi) {
									rx.ProvNum=ProviderC.ListLong[j].ProvNum;
									break;
								}
							}
						}
						//If rx.ProvNum is still zero, then that means the provider NPI/ProvNum has been modified or somehow deleted (for example, database was lost) for the provider record originally used.
						if(rx.ProvNum==0) {//Catch all
							if(PatCur.PriProv!=0) {
								rx.ProvNum=PatCur.PriProv;
							}
							else {
								rx.ProvNum=PrefC.GetLong(PrefName.PracticeDefaultProv);
							}
						}
					}
					else {//The prescription has already been downloaded in the past.
						rx.ProvNum=rxOld.ProvNum;//Preserve the provnum if already in the database, because it may have already been corrected by the user after the previous download.
					}
				}
				else {
					rx.ProvNum=erxLog.ProvNum;
				}
				if(rxOld==null) {
					rx.IsNew=true;//Might not be necessary, but does not hurt.
					RxPats.Insert(rx);
				}
				else {//The prescription was already in our database. Update it.
					rx.RxNum=rxOld.RxNum;
					RxPats.Update(rx);
				}
				//If rxCui==0, then NewCrop did not provide an RxCui.  Attempt to locate an RxCui using the other provided drug information.  An RxCui is not required for our program.  Meds missing an RxCui are not exported in CCD messages.
				if(rxCui==0 && strDrugName!="") {
					List<RxNorm> listRxNorms=RxNorms.GetListByCodeOrDesc(strDrugName,true,true);//Exact case insensitive match ignoring numbers.
					if(listRxNorms.Count>0) {
						rxCui=PIn.Long(listRxNorms[0].RxCui);
					}					
				}
				//If rxCui==0, then NewCrop did not provide an RxCui and we could not locate an RxCui by DrugName.  Try searching by GenericName.
				if(rxCui==0 && strGenericName!="") {
					List<RxNorm> listRxNorms=RxNorms.GetListByCodeOrDesc(strGenericName,true,true);//Exact case insensitive match ignoring numbers.
					if(listRxNorms.Count>0) {
						rxCui=PIn.Long(listRxNorms[0].RxCui);
					}
				}
				//If rxCui==0, then NewCrop did not provide an RxCui and we could not locate an RxCui by DrugName or GenericName.
				if(rxCui==0) {
					//We may need to enhance in future to support more advanced RxNorm searches.
					//For example: DrugName=Cafatine, DrugInfo=Cafatine 1 mg-100 mg Tab, GenericName=ergotamine-caffeine.
					//This drug could not be found by DrugName nor GenericName, but could be found when the GenericName was split by non-alpha characters, then the words in the generic name were swapped.
					//Namely, "caffeine ergotamine" is in the RxNorm table.
				}
				MedicationPats.InsertOrUpdateMedOrderForRx(rx,rxCui,isProv);//MedicationNum of 0, because we do not want to bloat the medication list in OD. In this special situation, we instead set the MedDescript, RxCui and NewCropGuid columns.
			}//end foreach
			return true;
		}
Example #19
0
 private void RxSelected()
 {
     if(gridMain.GetSelectedIndex()==-1) {
         //this should never happen
         return;
     }
     RxDef RxDefCur=RxDefList[gridMain.GetSelectedIndex()];
     //Alert
     if(!RxAlertL.DisplayAlerts(PatCur.PatNum,0,RxDefCur.RxDefNum)){
         return;
     }
     //User OK with alert
     RxPat RxPatCur=new RxPat();
     RxPatCur.RxDate=DateTime.Today;
     RxPatCur.PatNum=PatCur.PatNum;
     RxPatCur.Drug=RxDefCur.Drug;
     RxPatCur.IsControlled=RxDefCur.IsControlled;
     RxPatCur.Sig=RxDefCur.Sig;
     RxPatCur.Disp=RxDefCur.Disp;
     RxPatCur.Refills=RxDefCur.Refills;
     if(PrefC.GetBool(PrefName.RxSendNewToQueue)) {
         RxPatCur.SendStatus=RxSendStatus.InElectQueue;
     }
     else {
         RxPatCur.SendStatus=RxSendStatus.Unsent;
     }
     //Notes not copied: we don't want these kinds of notes cluttering things
     FormRxEdit FormE=new FormRxEdit(PatCur,RxPatCur);
     FormE.IsNew=true;
     FormE.ShowDialog();
     if(FormE.DialogResult!=DialogResult.OK){
         return;
     }
     DialogResult=DialogResult.OK;
 }
Example #20
0
        ///<summary>For CPOE.  Used for both manual rx and eRx through NewCrop.  Creates or updates a medical order using the given prescription information.
        ///Since rxCui is not part of the prescription, it must be passed in as a separate parameter.
        ///If isProvOrder is true, then the medical order provNum will be set to the prescription provNum.  If isProvOrder is false, then the medical order provNum will be set to 0.
        ///The MedDescript and ErxGuid will always be copied from the prescription to the medical order and the medical order MedicationNum will be set to 0.
        ///This method return the medOrderNum for the new/updated medicationPat. Unlike most medical orders this does not create an entry in the medical order table.</summary>
        public static long InsertOrUpdateMedOrderForRx(RxPat rxPat, long rxCui, bool isProvOrder)
        {
            long          medOrderNum;
            MedicationPat medOrderOld = null;

            if (!string.IsNullOrWhiteSpace(rxPat.ErxGuid))             //This check prevents an extra db call when making a new prescription manually inside OD.
            {
                medOrderOld = MedicationPats.GetMedicationOrderByErxIdAndPat(rxPat.ErxGuid, rxPat.PatNum);
            }
            MedicationPat medOrder = null;          //The medication order corresponding to the prescription.

            if (medOrderOld == null)
            {
                medOrder = new MedicationPat();
            }
            else
            {
                medOrder = medOrderOld.Clone();              //Maintain primary key and medicationnum for the update below.
            }
            medOrder.DateStart = rxPat.RxDate;
            int numDays = PrefC.GetInt(PrefName.MedDefaultStopDays);

            if (numDays != 0)
            {
                medOrder.DateStop = rxPat.RxDate.AddDays(numDays);
            }
            medOrder.MedDescript = rxPat.Drug;
            medOrder.RxCui       = rxCui;
            if (rxCui != 0)
            {
                //The customer may not have a medication entered for this RxCui the first few times they get this particular medication back from eRx.
                //Once the customer adds the medication to their medication list, then we can automatically attach the order to the medication.
                //The reason we decided not to automatically create the medication if one does not already exist is because we do not want to
                //accidentally bloat the medication list, if for example, the user has the medication entered but has not set the RxCui on it yet.
                List <Medication> listMeds = Medications.GetAllMedsByRxCui(rxCui);
                if (listMeds.Count > 0)
                {
                    medOrder.MedicationNum = listMeds[0].MedicationNum;
                }
            }
            medOrder.ErxGuid = rxPat.ErxGuid;
            medOrder.PatNote = rxPat.Sig;
            medOrder.PatNum  = rxPat.PatNum;
            if (isProvOrder)
            {
                medOrder.ProvNum = rxPat.ProvNum;
                medOrder.IsCpoe  = true;
            }
            if (medOrderOld == null)
            {
                medOrder.IsNew = true;              //Might not be necessary, but does not hurt.
                medOrderNum    = MedicationPats.Insert(medOrder);
                //If the ErxGuid has not been set, and it is a new medication, set the ErxGuid so that the medication can be sent to DoseSpot
                if (Erx.IsManualRx(rxPat.ErxGuid))
                {
                    try {
                        int medPatNumAsInt = (int)medOrderNum;
                        rxPat.ErxGuid = Erx.OpenDentalErxPrefix + medPatNumAsInt;
                        RxPats.Update(rxPat);
                    }
                    catch (Exception ex) {
                        //If we cannot downgrade a long to an int for the ErxGuid we can simply ignore trying to update the rxPat.
                        //This is because this medication would never be sent to eRx because we would attempt this downgrade again in the exact same manner.
                        ex.DoNothing();
                    }
                }
            }
            else              //The medication order was already in our database. Update it.
            {
                medOrder.MedicationPatNum = medOrderOld.MedicationPatNum;
                MedicationPats.Update(medOrder, false);               //Don't ErxGuid here, it was already purposefully set above.
                medOrderNum = medOrder.MedicationPatNum;
            }
            return(medOrderNum);
        }