private void ButSupplementalSaveDefaults_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(textSupplementalBackupCopyNetworkPath.Text) && !Directory.Exists(textSupplementalBackupCopyNetworkPath.Text)) { MsgBox.Show(this, "Invalid or inaccessible " + labelSupplementalBackupCopyNetworkPath.Text + "."); //This label text will rarely change. return; } if (Prefs.UpdateBool(PrefName.SupplementalBackupEnabled, checkSupplementalBackupEnabled.Checked)) { try { //Inform HQ when the supplemental backups are enabled/disabled and which security admin performed the change. PayloadItem pliStatus = new PayloadItem( (int)(checkSupplementalBackupEnabled.Checked?SupplementalBackupStatuses.Enabled:SupplementalBackupStatuses.Disabled), "SupplementalBackupStatus"); PayloadItem pliAdminUserName = new PayloadItem(Security.CurUser.UserName, "AdminUserName"); string officeData = PayloadHelper.CreatePayload(new List <PayloadItem>() { pliStatus, pliAdminUserName }, eServiceCode.SupplementalBackup); WebServiceMainHQProxy.GetWebServiceMainHQInstance().SetSupplementalBackupStatus(officeData); } catch (Exception ex) { ex.DoNothing(); //Internet probably is unavailble right now. } SecurityLogs.MakeLogEntry(Permissions.SupplementalBackup, 0, "Supplemental backup has been " + (checkSupplementalBackupEnabled.Checked?"Enabled":"Disabled") + "."); } if (Prefs.UpdateString(PrefName.SupplementalBackupNetworkPath, textSupplementalBackupCopyNetworkPath.Text)) { SecurityLogs.MakeLogEntry(Permissions.SupplementalBackup, 0, labelSupplementalBackupCopyNetworkPath.Text + " changed to '" + textSupplementalBackupCopyNetworkPath.Text + "'."); } MsgBox.Show(this, "Saved"); }
private void ButOK_Click(object sender, EventArgs e) { if (textKey.Text == "") { MsgBox.Show(this, "Please enter an API key."); return; } string officeData = PayloadHelper.CreatePayload(PayloadHelper.CreatePayloadContent(textKey.Text, "APIKey"), eServiceCode.FHIR); string result; try { Cursor = Cursors.WaitCursor; result = WebServiceMainHQProxy.GetWebServiceMainHQInstance().AssignFHIRAPIKey(officeData); PayloadHelper.CheckForError(result); } catch (Exception ex) { MsgBox.Show(ex.Message); Cursor = Cursors.Default; return; } MsgBox.Show(this, WebSerializer.DeserializeTag <string>(result, "Response")); DialogResult = DialogResult.OK; }
private void ButDisable_Click(object sender, EventArgs e) { FHIRKeyStatus newStatus; DateTime dateDisabled; if (_apiKeyCur.KeyStatus.In(FHIRKeyStatus.Enabled, FHIRKeyStatus.EnabledReadOnly)) { newStatus = FHIRKeyStatus.DisabledByCustomer; dateDisabled = DateTime.Now; } else //DisabledByCustomer { newStatus = FHIRKeyStatus.Enabled; dateDisabled = DateTime.MinValue; } string officeData = PayloadHelper.CreatePayload(PayloadHelper.CreatePayloadContent(new List <PayloadItem> { new PayloadItem(textKey.Text, "APIKey"), new PayloadItem(newStatus.ToString(), "FHIRKeyStatus"), }), eServiceCode.FHIR); string result; try { Cursor = Cursors.WaitCursor; result = WebServiceMainHQProxy.GetWebServiceMainHQInstance().UpdateFHIRKeyStatus(officeData); PayloadHelper.CheckForError(result); } catch (Exception ex) { MsgBox.Show(ex.Message); Cursor = Cursors.Default; return; } HasChanged = true; Cursor = Cursors.Default; _apiKeyCur.KeyStatus = newStatus; _apiKeyCur.DateDisabled = dateDisabled; FillForm(); }
///<summary>Send a summary of eConnector statistics to OD HQ. This should only be called from the eConnector.</summary> public static void UpdateEConnectorStats() { EConnectorStatistics eConnStats = new EConnectorStatistics() { ListEServiceSignals = new List <EServiceSignal>(), ListEServicePrefs = new List <Pref>(), }; eConnStats.EConnectorComputerName = Environment.MachineName; eConnStats.EConnectorDomainUserName = Environment.UserName; eConnStats.EConnectorIP = ODEnvironment.GetLocalIPAddress(); eConnStats.HasClinicsEnabled = PrefC.HasClinicsEnabled; if (PrefC.HasClinicsEnabled) { eConnStats.CountActiveClinics = OpenDentBusiness.Clinics.GetCount(); eConnStats.CountInactiveClinics = OpenDentBusiness.Clinics.GetCount() - eConnStats.CountActiveClinics; } else { eConnStats.CountActiveClinics = 0; eConnStats.CountInactiveClinics = OpenDentBusiness.Clinics.GetCount(); } if (DateTime.Now.Hour == 0) //These are heavy queries so only run them once a day around midnight. { eConnStats.CountActivePatients = OpenDentBusiness.Procedures.GetCountPatsComplete(DateTime.Today.AddYears(-2), DateTime.Today); eConnStats.CountNonactivePatients = OpenDentBusiness.Patients.GetPatCountAll() - eConnStats.CountActivePatients; eConnStats.ListEServiceSignals = OpenDentBusiness.EServiceSignals.GetServiceHistory(eServiceCode.ListenerService, DateTime.Today.AddDays(-30), DateTime.Today, 30); } eConnStats.DateTimeNow = DateTime.Now; foreach (PrefName prefName in Enum.GetValues(typeof(PrefName))) { if (prefName.In( PrefName.RegistrationKey, PrefName.ProgramVersion, PrefName.DataBaseVersion, PrefName.TextingDefaultClinicNum, PrefName.WebServiceServerName, PrefName.SendEmailsInDiffProcess, PrefName.EmailAlertMaxConsecutiveFails, PrefName.AutoCommNumClinicsParallel, PrefName.AutomaticCommunicationTimeStart, PrefName.AutomaticCommunicationTimeEnd) || prefName.ToString().StartsWith("WebSched") || prefName.ToString().StartsWith("ApptConfirm") || prefName.ToString().StartsWith("ApptRemind") || prefName.ToString().StartsWith("ApptEConfirm") || prefName.ToString().StartsWith("Recall") || prefName.ToString().StartsWith("PatientPortal") || prefName.ToString().StartsWith("Sms")) { try { eConnStats.ListEServicePrefs.Add(Prefs.GetPref(prefName.ToString())); } catch (Exception ex) { ex.DoNothing(); } } } List <EConnectorStatistics> listStatsToSend = new List <EConnectorStatistics> { eConnStats }; string dbStats = PrefC.GetString(PrefName.EConnectorStatistics); List <EConnectorStatistics> listDbStats = DeserializeListFromJson(dbStats) ?? new List <EConnectorStatistics>(); bool doCreateAlert = false; foreach (EConnectorStatistics stats in listDbStats) { //If a different eConnector is saving stats, add that one to the list to be sent to HQ. if (!AreSameEConnector(eConnStats, stats) && (eConnStats.DateTimeNow - stats.DateTimeNow).TotalHours < 23) { stats.ListEServicePrefs = new List <Pref>(); //To save on bandwidth stats.ListEServiceSignals = new List <EServiceSignal>(); listStatsToSend.Add(stats); if ((eConnStats.DateTimeNow - stats.DateTimeNow).TotalHours < 3) { doCreateAlert = true; } } } if (doCreateAlert && AlertItems.RefreshForType(AlertType.MultipleEConnectors).Count == 0) { AlertItem alert = new AlertItem { Actions = ActionType.MarkAsRead | ActionType.Delete, Description = Lans.g("EConnectorStats", "eConnector services are being run on these computers:") + " " + string.Join(", ", listStatsToSend.Select(x => x.EConnectorComputerName)), Severity = SeverityType.High, Type = AlertType.MultipleEConnectors, }; AlertItems.Insert(alert); } string statsStr = SerializeToJson(listStatsToSend); OpenDentBusiness.Prefs.UpdateString(PrefName.EConnectorStatistics, statsStr); string payload = PayloadHelper.CreatePayload(PayloadHelper.CreatePayloadContent(statsStr, "EConnectorStatsStr"), eServiceCode.ListenerService); WebServiceMainHQProxy.GetWebServiceMainHQInstance().SetEConnectorStatsAsync(payload); }
///<summary>Only call this method from SendPushBackground() or SendPushAlert(). See summary of those methods for documentation. ///If runAsync==true then spawns a worker thread and makes the web call. This method is passive and returns void so no reason to wait for return.</summary> private static void SendPush(PushType pushType, bool isAlert, long mobileAppDeviceNum = 0, long clinicNum = 0, long userNum = 0, List <long> listPrimaryKeys = null, List <string> listTags = null, string alertTitle = null, string alertMessage = null, bool runAsync = true) { void execute() { eServiceCode eService = eServiceCode.EClipboard; switch (pushType) { case PushType.CI_CheckinPatient: case PushType.CI_AddSheet: case PushType.CI_RemoveSheet: case PushType.CI_GoToCheckin: case PushType.CI_NewEClipboardPrefs: case PushType.CI_IsAllowedChanged: case PushType.CI_TreatmentPlan: case PushType.CI_RemoveTreatmentPlan: eService = eServiceCode.EClipboard; break; case PushType.ODM_NewTextMessage: case PushType.ODM_LogoutODUser: eService = eServiceCode.MobileWeb; break; case PushType.None: default: throw new Exception("Unsupported PushType: " + pushType.ToString()); } PushNotificationPayload payload = new PushNotificationPayload { IsAlert = isAlert, AlertMessage = alertMessage ?? "", AlertTitle = alertTitle ?? "", UserNum = userNum, PushNotificationActionJSON = JsonConvert.SerializeObject(new PushNotificationAction() { TypeOfPush = pushType, ListPrimaryKeys = listPrimaryKeys ?? new List <long>(), ListTags = listTags ?? new List <string>() }, typeof(PushNotificationAction), new JsonSerializerSettings()) }; if (mobileAppDeviceNum > 0) //Send to one exact device. { MobileAppDevice mad = MobileAppDevices.GetOne(mobileAppDeviceNum); if (mad == null) { throw new Exception("MobileAppDeviceNum not found: " + mobileAppDeviceNum.ToString()); } payload.DeviceId = mad.UniqueID; payload.ClinicNum = mad.ClinicNum; } else { payload.ClinicNum = clinicNum; } //Validate that this clinic is signed up for eClipboard if the push is related to eClipboard if (eService == eServiceCode.EClipboard && !MobileAppDevices.IsClinicSignedUpForEClipboard(payload.ClinicNum)) { throw new Exception($"ClinicNum {payload.ClinicNum} is not signed up for eClipboard."); } //Validate that this clinic is signed up for MobileWeb if the push is related to ODMobile else if (eService == eServiceCode.MobileWeb && !MobileAppDevices.IsClinicSignedUpForMobileWeb(payload.ClinicNum)) { if (clinicNum > -1 || pushType != PushType.ODM_LogoutODUser) //Logout is allowed to be sent to non-specific clinicNum. All others are not. { throw new Exception($"ClinicNum {payload.ClinicNum} is not signed up for ODMobile."); } } string jsonPayload = JsonConvert.SerializeObject(payload, typeof(PushNotificationPayload), new JsonSerializerSettings()); string result = WebServiceMainHQProxy.GetWebServiceMainHQInstance().SendPushNotification(PayloadHelper.CreatePayload("", eService), jsonPayload); if (result.ToLower() != "success") { throw new Exception(result); } } ODThread th = new ODThread(new ODThread.WorkerDelegate((o) => { execute(); })); th.AddExceptionHandler((e) => { if (MockExceptionHandler != null) { MockExceptionHandler(e); } else { Logger.WriteException(e, "PushNotifications"); } }); th.Name = "SendPush_" + pushType.ToString() + "_ClinicNum_" + clinicNum.ToString() + "_UserNum_" + userNum.ToString(); th.Start(); if (MockExceptionHandler != null || !runAsync) //Join back to main thread to cause this to be a blocking call. Unit tests will always block. { th.Join(Timeout.Infinite); } }
///<summary>Processes a PaySimple ACH payment via the PaySimple API.</summary> private PaySimple.ApiResponse ProcessPaymentACH() { PaySimple.ApiResponse retVal = null; string accountNumber = textCheckSaveNumber.Text; //if the user has chosen to store CC tokens and the stored CC has a token and the token is not expired, //then use it instead of the CC number and CC expiration. if (!checkOneTimePaymentACH.Checked && _creditCardCur != null && //if the user selected a saved CC !string.IsNullOrWhiteSpace(_creditCardCur.PaySimpleToken) && //there is a stored token for this card _creditCardCur.CCSource == CreditCardSource.PaySimpleACH) { accountNumber = _creditCardCur.PaySimpleToken; } else if (PIn.Bool(ProgramProperties.GetPropVal(_progCur.ProgramNum, PaySimple.PropertyDescs.PaySimplePreventSavingNewCC, _clinicNum))) { MsgBox.Show(this, "Cannot add a new ACH payment."); return(null); } try { if (_isAddingCard) { retVal = PaySimple.AddACHAccount(_patCur, textRoutingNumber.Text, textCheckSaveNumber.Text, textBankName.Text, radioCheckings.Checked, _clinicNum); } else { retVal = PaySimple.MakePaymentACH(_patCur, _creditCardCur, PIn.Decimal(textAmountACH.Text), textRoutingNumber.Text, textCheckSaveNumber.Text, textBankName.Text, radioCheckings.Checked, checkOneTimePaymentACH.Checked, _clinicNum); try { string result = WebServiceMainHQProxy.GetWebServiceMainHQInstance() .InsertPaySimpleACHId(PayloadHelper.CreatePayload( PayloadHelper.CreatePayloadContent(retVal.RefNumber.ToString(), "PaymentId"), eServiceCode.PaySimple)); PayloadHelper.CheckForError(result); } catch (Exception ex) { FriendlyException.Show("Unable to register for ACH Settled event", ex); } } } catch (PaySimpleException ex) { MessageBox.Show(ex.Message); if (ex.ErrorType == PaySimpleError.CustomerDoesNotExist && MsgBox.Show(this, MsgBoxButtons.OKCancel, "Delete the link to the customer id for this patient?")) { PatientLinks.DeletePatNumTos(ex.CustomerId, PatientLinkType.PaySimple); } return(null); } catch (ODException ex) { MessageBox.Show(ex.Message); //This should have already been Lans.g if applicable. return(null); } catch (Exception ex) { FriendlyException.Show(Lan.g(this, "Error:") + " " + ex.Message, ex); return(null); } if (!_isAddingCard) { retVal.BuildReceiptString(accountNumber, -1, -1, _patCur?.GetNameFL(), _clinicNum, wasSwiped: false, isACH: true); PrintReceipt(retVal.TransactionReceipt); } if (checkOneTimePaymentACH.Checked) //not storing the account token { return(retVal); } UpsertCreditCard(retVal, textCheckSaveNumber.Text.Right(4).PadLeft(textCheckSaveNumber.Text.Length, '*'), CreditCardSource.PaySimpleACH, DateTime.MinValue); return(retVal); }
///<summary>Sends a request to HQ to update the Short Code Opt In status of this patient. Can be sent silently without any feedback in the UI. ///</summary> private static bool TrySendToHq(string wirelessPhone, YN optIn, long patNum, long clinicNum, bool isSilent = false) { List <PayloadItem> listPayloadItems = new List <PayloadItem>() { new PayloadItem(wirelessPhone, "PhonePat"), new PayloadItem((int)optIn, "ShortCodeOptInInt"), new PayloadItem(patNum, "PatNum"), new PayloadItem(clinicNum, "ClinicNum"), new PayloadItem(false, "IsWebSchedNewPat"), new PayloadItem(isSilent, "IsSilentUpdate"), }; string result = ""; if (isSilent) { ODThread threadSilent = new ODThread((o) => WebServiceMainHQProxy.GetWebServiceMainHQInstance() .SetSmsPatientPhoneOptIn(PayloadHelper.CreatePayload(listPayloadItems, eServiceCode.IntegratedTexting))); threadSilent.AddExceptionHandler((ex) => ex.DoNothing()); threadSilent.Name = "ShortCodeOptIn"; threadSilent.Start(); return(true); } ODProgress.ShowAction(() => { result = WebServiceMainHQProxy.GetWebServiceMainHQInstance() .SetSmsPatientPhoneOptIn(PayloadHelper.CreatePayload(listPayloadItems, eServiceCode.IntegratedTexting)); }); XmlDocument doc = new XmlDocument(); doc.LoadXml(result); XmlNode node = doc.SelectSingleNode("//ListSmsToMobiles"); if (node is null) { node = doc.SelectSingleNode("//Error"); if (!(node is null)) { MessageBox.Show(Lan.g("ShortCodes", "An error occurred: ") + node.InnerText); } return(false); } List <SmsToMobile> listSmsToMobiles; using (XmlReader reader = XmlReader.Create(new System.IO.StringReader(node.InnerXml))) { System.Xml.Serialization.XmlSerializer xmlListSmsToMobileSerializer = new System.Xml.Serialization.XmlSerializer(typeof(List <SmsToMobile>)); listSmsToMobiles = (List <SmsToMobile>)xmlListSmsToMobileSerializer.Deserialize(reader); } if (listSmsToMobiles == null) //List should always be there even if it's empty. { MessageBox.Show(Lan.g("ShortCodes", "An error occurred: ") + node.InnerText); return(false); } //Should only be 0 or 1. if (listSmsToMobiles.Count > 0) { listSmsToMobiles.ForEach(x => x.DateTimeSent = DateTime.Now); SmsToMobiles.InsertMany(listSmsToMobiles); string message = $"{wirelessPhone} will shortly receive the following message{(listSmsToMobiles.Count>1 ? "s" : "")}:\n" + string.Join("\n", listSmsToMobiles.Select((x, i) => $"{i+1}) {x.MsgText}")); MessageBox.Show(message, "Appointment Texts"); } //Local OptIn status for this patient will be updated by a Transmission from HQ, resulting from this call to SetSmsPatientPhoneOptIn(). return(true); }
private List <APIKey> GetApiKeys() { List <APIKey> listApiKeys = new List <APIKey>(); //prepare the xml document to send-------------------------------------------------------------------------------------- XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = (" "); StringBuilder strbuild = new StringBuilder(); //Send the message and get the result------------------------------------------------------------------------------------- string result = ""; try { string officeData = PayloadHelper.CreatePayload(strbuild.ToString(), eServiceCode.FHIR); result = WebServiceMainHQProxy.GetWebServiceMainHQInstance().GetFHIRAPIKeysForOffice(officeData); } catch (Exception ex) { MessageBox.Show(ex.Message); return(null); } XmlDocument doc = new XmlDocument(); doc.LoadXml(result); XPathNavigator nav = doc.CreateNavigator(); //Process errors------------------------------------------------------------------------------------------------------------ XPathNavigator node = nav.SelectSingleNode("//Error"); if (node != null) { MessageBox.Show(node.Value); return(null); } //Process a valid return value------------------------------------------------------------------------------------------------{ node = nav.SelectSingleNode("//ListAPIKeys"); if (node != null && node.MoveToFirstChild()) { do { APIKey apiKey = new APIKey(); apiKey.Key = node.SelectSingleNode("APIKeyValue").Value; apiKey.FHIRAPIKeyNum = PIn.Long(node.SelectSingleNode("FHIRAPIKeyNum").Value); apiKey.DateDisabled = DateTime.Parse(node.SelectSingleNode("DateDisabled").Value); if (!Enum.TryParse(node.SelectSingleNode("KeyStatus").Value, out apiKey.KeyStatus)) { APIKeyStatus status; if (Enum.TryParse(node.SelectSingleNode("KeyStatus").Value, out status)) { apiKey.KeyStatus = FHIRUtils.ToFHIRKeyStatus(status); } else { apiKey.KeyStatus = FHIRKeyStatus.DisabledByHQ; } } apiKey.DeveloperName = node.SelectSingleNode("DeveloperName").Value; apiKey.DeveloperEmail = node.SelectSingleNode("DeveloperEmail").Value; apiKey.DeveloperPhone = node.SelectSingleNode("DeveloperPhone").Value; apiKey.FHIRDeveloperNum = PIn.Long(node.SelectSingleNode("FHIRDeveloperNum").Value); XPathNavigator nodePerms = node.SelectSingleNode("ListAPIPermissions"); if (nodePerms != null && nodePerms.MoveToFirstChild()) { do { APIPermission perm; if (Enum.TryParse(nodePerms.Value, out perm)) { apiKey.ListPermissions.Add(perm); } } while(nodePerms.MoveToNext()); } listApiKeys.Add(apiKey); } while(node.MoveToNext()); } return(listApiKeys); }