///<summary></summary> public static void Update(EServiceSignal eServiceSignal) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(),eServiceSignal); return; } Crud.EServiceSignalCrud.Update(eServiceSignal); }
///<summary></summary> public static long Insert(EServiceSignal eServiceSignal) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { eServiceSignal.EServiceSignalNum=Meth.GetLong(MethodBase.GetCurrentMethod(),eServiceSignal); return eServiceSignal.EServiceSignalNum; } return Crud.EServiceSignalCrud.Insert(eServiceSignal); }
///<summary></summary> public static void Update(EServiceSignal eServiceSignal) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(), eServiceSignal); return; } Crud.EServiceSignalCrud.Update(eServiceSignal); }
///<summary>Gets one EServiceSignalHQ from the serviceshq db located on SERVER184. Returns null in case of failure.</summary> public static EServiceMetrics GetEServiceMetricsFromSignalHQ() { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <EServiceMetrics>(MethodBase.GetCurrentMethod())); } EServiceMetrics eServiceMetric = new EServiceMetrics(); if (PrefC.ContainsKey("ServicesHqDoNotConnect") && PrefC.GetBool(PrefName.ServicesHqDoNotConnect)) { eServiceMetric.ErrorMessage = "Not allowed to connect to the serviceshq database."; return(eServiceMetric); } string dbPassword; if (!CDT.Class1.Decrypt(PrefC.GetString(PrefName.ServicesHqMySqpPasswordObf), out dbPassword)) { eServiceMetric.ErrorMessage = "Unable to decrypt serviceshq password"; return(eServiceMetric); } try { DataAction.Run(() => { //See EServiceSignalHQs.GetEServiceMetrics() for details. string command = @"SELECT 0 EServiceSignalNum, h.* FROM eservicesignalhq h WHERE h.ReasonCode=1024 AND h.ReasonCategory=1 AND h.ServiceCode=2 AND h.RegistrationKeyNum=-1 ORDER BY h.SigDateTime DESC LIMIT 1" ; EServiceSignal eServiceSignal = Crud.EServiceSignalCrud.SelectOne(command); if (eServiceSignal != null) { using (XmlReader reader = XmlReader.Create(new System.IO.StringReader(eServiceSignal.Tag))) { eServiceMetric = (EServiceMetrics) new XmlSerializer(typeof(EServiceMetrics)).Deserialize(reader); } eServiceMetric.IsValid = true; } }, PrefC.GetString(PrefName.ServicesHqServer), PrefC.GetString(PrefName.ServicesHqDatabase), PrefC.GetString(PrefName.ServicesHqMySqlUser), dbPassword, "", "", DatabaseType.MySql); } catch (Exception ex) { eServiceMetric.ErrorMessage = ex.Message; } return(eServiceMetric); }
///<summary>Inserts a healthy heartbeat.</summary> public static void InsertHeartbeatForService(eServiceCode serviceCode) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(), serviceCode); return; } AlertItems.DeleteFor(AlertType.EConnectorDown); string command = "SELECT * FROM eservicesignal WHERE ServiceCode=" + POut.Int((int)serviceCode) + " AND Severity IN (" + POut.Int((int)eServiceSignalSeverity.NotEnabled) + "," + POut.Int((int)eServiceSignalSeverity.Working) + "," + POut.Int((int)eServiceSignalSeverity.Critical) + ") ORDER BY SigDateTime DESC " + DbHelper.LimitWhere(1);//only select not enabled, working, and critical statuses. EServiceSignal eServiceSignalLast = Crud.EServiceSignalCrud.SelectOne(command); DateTime dtNow = MiscData.GetNowDateTime(); //If initializing or changing state to working from not working, insert two signals; An anchor and a rolling timestamp. if (eServiceSignalLast == null || eServiceSignalLast.Severity != eServiceSignalSeverity.Working) //First ever heartbeat or critical which was not previously critical. { if (eServiceSignalLast != null && eServiceSignalLast.Severity == eServiceSignalSeverity.Critical //Do not create a signal if the eConnector was stopped because of an update && (eServiceSignalLast.SigDateTime > UpdateHistories.GetLastUpdateHistory().DateTimeUpdated || UpdateHistories.GetLastUpdateHistory().DateTimeUpdated.AddMinutes(10) < dtNow)) { //Changing from critical to working so alert user that this change took place and tell them how long we were in critical state. //Insert() will also insert Alert. Insert(new EServiceSignal() { ServiceCode = (int)serviceCode, Severity = eServiceSignalSeverity.Error, SigDateTime = dtNow, IsProcessed = false, Description = "Listener was critical for " + DateTime.Now.Subtract(eServiceSignalLast.SigDateTime).ToStringHmm() }); } Insert(new EServiceSignal() { ServiceCode = (int)serviceCode, Severity = eServiceSignalSeverity.Working, SigDateTime = dtNow, IsProcessed = true, Description = "Heartbeat Anchor" }); //anchor heartbeat Insert(new EServiceSignal() { ServiceCode = (int)serviceCode, Severity = eServiceSignalSeverity.Working, SigDateTime = dtNow.AddSeconds(1), IsProcessed = true, Description = "Heartbeat" }); //rolling heartbeat return; } eServiceSignalLast.SigDateTime = dtNow; Update(eServiceSignalLast); }
///<summary>Gets one EServiceSignalHQ from the serviceshq db located on SERVER184. Returns null in case of failure.</summary> public static EServiceMetrics GetEServiceMetricsFromSignalHQ() { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <EServiceMetrics>(MethodBase.GetCurrentMethod())); } //Create an ODThread so that we can safely change the database connection settings without affecting the calling method's connection. ODThread odThread = new ODThread(new ODThread.WorkerDelegate((ODThread o) => { //Always set the thread static database connection variables to set the serviceshq db conn. new DataConnection().SetDbT("server184", "serviceshq", "root", "", "", "", DatabaseType.MySql, true); //See EServiceSignalHQs.GetEServiceMetrics() for details. string command = @"SELECT 0 EServiceSignalNum, h.* FROM eservicesignalhq h WHERE h.ReasonCode=1024 AND h.ReasonCategory=1 AND h.ServiceCode=2 AND h.RegistrationKeyNum=-1 ORDER BY h.SigDateTime DESC LIMIT 1" ; EServiceSignal eServiceSignal = Crud.EServiceSignalCrud.SelectOne(command); EServiceMetrics eServiceMetric = new EServiceMetrics(); if (eServiceSignal != null) { using (XmlReader reader = XmlReader.Create(new System.IO.StringReader(eServiceSignal.Tag))) { eServiceMetric = (EServiceMetrics) new XmlSerializer(typeof(EServiceMetrics)).Deserialize(reader); } eServiceMetric.IsValid = true; } o.Tag = eServiceMetric; })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "eServiceMetricsThread"; odThread.Start(true); if (!odThread.Join(2000)) //Give this thread up to 2 seconds to complete. { return(null); } EServiceMetrics retVal = (EServiceMetrics)odThread.Tag; return(retVal); }
///<summary>Also inserts an EConnectorError Alert where applicable.</summary> public static long Insert(EServiceSignal eServiceSignal) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { eServiceSignal.EServiceSignalNum = Meth.GetLong(MethodBase.GetCurrentMethod(), eServiceSignal); return(eServiceSignal.EServiceSignalNum); } //If this is an error and the EConnectorError alert is not already present, create it now. if (eServiceSignal.Severity == eServiceSignalSeverity.Error && AlertItems.RefreshForType(AlertType.EConnectorError).Count == 0) { //Create an alert. AlertItems.Insert(new AlertItem { //Do not allow delete. The only way for this alert to be deleted is to open the eConnector form and ACK the error(s). Actions = ActionType.MarkAsRead | ActionType.OpenForm, Description = Lans.g("EConnector", "eConnector has posted an error."), Severity = SeverityType.Low, Type = AlertType.EConnectorError, FormToOpen = FormType.FormEServicesEConnector, }); } return(Crud.EServiceSignalCrud.Insert(eServiceSignal)); }
///<summary>Should only be called if ODHQ.</summary> private static List <Procedure> AddSmsRepeatingChargesHelper(DateTime dateRun) { //No remoting role check; no call to db DateTime dateStart = new DateTime(dateRun.AddMonths(-1).AddDays(-20).Year, dateRun.AddMonths(-1).AddDays(-20).Month, 1); DateTime dateStop = dateRun.AddDays(1); List <SmsBilling> listSmsBilling = SmsBillings.GetByDateRange(dateStart, dateStop); List <Patient> listPatients = Patients.GetMultPats(listSmsBilling.Select(x => x.CustPatNum).Distinct().ToList()).ToList(); //local cache ProcedureCode procCodeAccess = ProcedureCodes.GetProcCode("038"); ProcedureCode procCodeUsage = ProcedureCodes.GetProcCode("039"); ProcedureCode procCodeConfirm = ProcedureCodes.GetProcCode("040"); List <Procedure> listProcsAccess = Procedures.GetCompletedForDateRange(dateStart, dateStop, new List <long> { procCodeAccess.CodeNum }); List <Procedure> listProcsUsage = Procedures.GetCompletedForDateRange(dateStart, dateStop, new List <long> { procCodeUsage.CodeNum }); List <Procedure> listProcsConfirm = Procedures.GetCompletedForDateRange(dateStart, dateStop, new List <long> { procCodeConfirm.CodeNum }); List <Procedure> retVal = new List <Procedure>(); foreach (SmsBilling smsBilling in listSmsBilling) { Patient pat = listPatients.FirstOrDefault(x => x.PatNum == smsBilling.CustPatNum); if (pat == null) { EServiceSignal eSignal = new EServiceSignal { ServiceCode = (int)eServiceCode.IntegratedTexting, SigDateTime = MiscData.GetNowDateTime(), Severity = eServiceSignalSeverity.Error, Description = "Sms billing row found for non existent patient PatNum:" + smsBilling.CustPatNum }; EServiceSignals.Insert(eSignal); continue; } //Find the billing date based on the date usage. DateTime billingDate = smsBilling.DateUsage.AddMonths(1); //we always bill the month after usage posts. Example: all January usage = 01/01/2015 billingDate = new DateTime( billingDate.Year, billingDate.Month, Math.Min(pat.BillingCycleDay, DateTime.DaysInMonth(billingDate.Year, billingDate.Month))); //example: dateUsage=08/01/2015, billing cycle date=8/14/2012, billing date should be 9/14/2015. if (billingDate > dateRun || billingDate < dateRun.AddMonths(-1).AddDays(-20)) { //One month and 20 day window. Bill regardless of presence of "038" repeat charge. continue; } if (smsBilling.AccessChargeTotalUSD == 0 && smsBilling.MsgChargeTotalUSD == 0 && smsBilling.ConfirmationChargeTotalUSD == 0) { //No charges so skip this customer. continue; } //Only post confirmation charge if valid. if (smsBilling.ConfirmationChargeTotalUSD > 0 && (billingDate <= DateTime.Today || PrefC.GetBool(PrefName.FutureTransDatesAllowed) && !listProcsConfirm.Exists(x => x.PatNum == pat.PatNum && x.ProcDate.Year == billingDate.Year && x.ProcDate.Month == billingDate.Month))) { //The calculated access charge was greater than 0 and there is not an existing "038" procedure on the account for that month. Procedure procConfirm = new Procedure(); procConfirm.CodeNum = procCodeConfirm.CodeNum; procConfirm.DateEntryC = DateTime.Today; procConfirm.PatNum = pat.PatNum; procConfirm.ProcDate = billingDate; procConfirm.DateTP = billingDate; procConfirm.ProcFee = smsBilling.ConfirmationChargeTotalUSD; procConfirm.ProcStatus = ProcStat.C; procConfirm.ProvNum = PrefC.GetLong(PrefName.PracticeDefaultProv); procConfirm.MedicalCode = procCodeConfirm.MedicalCode; procConfirm.BaseUnits = procCodeConfirm.BaseUnits; procConfirm.DiagnosticCode = PrefC.GetString(PrefName.ICD9DefaultForNewProcs); procConfirm.BillingNote = smsBilling.BillingDescConfirmation; procConfirm.PlaceService = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService); //Default Proc Place of Service for the Practice is used. Procedures.Insert(procConfirm); listProcsConfirm.Add(procConfirm); retVal.Add(procConfirm); } //Confirmation charges may wipe out access charges. We still want to see the $0 charge in this case so post this charge if either of the 2 are valid. if ((smsBilling.AccessChargeTotalUSD > 0 || smsBilling.ConfirmationChargeTotalUSD > 0) && (billingDate <= DateTime.Today || PrefC.GetBool(PrefName.FutureTransDatesAllowed)) && !listProcsAccess.Exists(x => x.PatNum == pat.PatNum && x.ProcDate.Year == billingDate.Year && x.ProcDate.Month == billingDate.Month)) { //The calculated access charge was greater than 0 and there is not an existing "038" procedure on the account for that month. Procedure procAccess = new Procedure(); procAccess.CodeNum = procCodeAccess.CodeNum; procAccess.DateEntryC = DateTime.Today; procAccess.PatNum = pat.PatNum; procAccess.ProcDate = billingDate; procAccess.DateTP = billingDate; procAccess.ProcFee = smsBilling.AccessChargeTotalUSD; procAccess.ProcStatus = ProcStat.C; procAccess.ProvNum = PrefC.GetLong(PrefName.PracticeDefaultProv); procAccess.MedicalCode = procCodeAccess.MedicalCode; procAccess.BaseUnits = procCodeAccess.BaseUnits; procAccess.DiagnosticCode = PrefC.GetString(PrefName.ICD9DefaultForNewProcs); procAccess.BillingNote = smsBilling.BillingDescSms; procAccess.PlaceService = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService); //Default Proc Place of Service for the Practice is used. Procedures.Insert(procAccess); listProcsAccess.Add(procAccess); retVal.Add(procAccess); } //Only post usage charge if valid. if (smsBilling.MsgChargeTotalUSD > 0 && (billingDate <= DateTime.Today || PrefC.GetBool(PrefName.FutureTransDatesAllowed)) && !listProcsUsage.Exists(x => x.PatNum == pat.PatNum && x.ProcDate.Year == billingDate.Year && x.ProcDate.Month == billingDate.Month)) { //Calculated Usage charge > 0 and not already billed, may exist without access charge Procedure procUsage = new Procedure(); procUsage.CodeNum = procCodeUsage.CodeNum; procUsage.DateEntryC = DateTime.Today; procUsage.PatNum = pat.PatNum; procUsage.ProcDate = billingDate; procUsage.DateTP = billingDate; procUsage.ProcFee = smsBilling.MsgChargeTotalUSD; procUsage.ProcStatus = ProcStat.C; procUsage.ProvNum = PrefC.GetLong(PrefName.PracticeDefaultProv); procUsage.MedicalCode = procCodeUsage.MedicalCode; procUsage.BaseUnits = procCodeUsage.BaseUnits; procUsage.DiagnosticCode = PrefC.GetString(PrefName.ICD9DefaultForNewProcs); procUsage.PlaceService = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService); //Default Proc Place of Service for the Practice is used. procUsage.BillingNote = "Texting Usage charge for " + smsBilling.DateUsage.ToString("MMMM yyyy") + "."; Procedures.Insert(procUsage); listProcsUsage.Add(procUsage); retVal.Add(procUsage); } } return(retVal); }
private void butListenerAlertsOff_Click(object sender,EventArgs e) { if(!Security.IsAuthorized(Permissions.SecurityAdmin)) { return; } //Insert a row into the eservicesignal table to indicate to all computers to stop monitoring. EServiceSignal signalDisable=new EServiceSignal(); signalDisable.Description="Stop Monitoring clicked from setup window."; signalDisable.IsProcessed=true; signalDisable.ReasonCategory=0; signalDisable.ReasonCode=0; signalDisable.ServiceCode=(int)eServiceCode.ListenerService; signalDisable.Severity=eServiceSignalSeverity.NotEnabled; signalDisable.Tag=""; signalDisable.SigDateTime=DateTime.Now; EServiceSignals.Insert(signalDisable); SecurityLogs.MakeLogEntry(Permissions.SecurityAdmin,0,"Listener Service monitoring manually stopped via eServices Setup window."); MsgBox.Show(this,"Monitoring shutdown signal sent. This will take up to one minute."); FillGridListenerService(); FillTextListenerServiceStatus(); }