///<summary>Expire confirmations for any appointments that have been rescheduled since sending out a confirmation request.</summary> public static void HandleConfirmationsApptChanged() { //No remoting role check needed. List <ConfirmationRequest> listChanged = GetForApptChanged(); listChanged = listChanged.Where(x => !x.DoNotResend).ToList(); //Remove those that the user specifically said to not resend List <string> listShortGuids = listChanged.Where(x => !string.IsNullOrWhiteSpace(x.ShortGUID)).Select(x => x.ShortGUID).ToList(); listShortGuids.AddRange(listChanged.Where(x => !string.IsNullOrWhiteSpace(x.ShortGuidEmail)).Select(x => x.ShortGuidEmail)); if (listShortGuids.Count == 0) { return; } string hqPayload = PayloadHelper.CreatePayload(PayloadHelper.CreatePayloadContent(listShortGuids, "ListShortGuids"), eServiceCode.ConfirmationRequest); string result = WebServiceMainHQProxy.GetWebServiceMainHQInstance().HandleConfirmationsApptChanged(hqPayload); XmlDocument doc = new XmlDocument(); doc.LoadXml(result); XmlNode node = doc.SelectSingleNode("//Error"); if (node != null) { throw new Exception(node.InnerText); } //Deleting these will cause the AutoComm thread to resend where necessary. DeleteShortGuids(listShortGuids); }
///<summary>Surround with try/catch. Returns true if all messages succeded, throws exception if it failed. ///All Integrated Texting should use this method, CallFire texting does not use this method.</summary> public static void SendSms(List <SmsToMobile> listMessages) { //No need to check RemotingRole; no call to db. if (Plugins.HookMethod(null, "SmsToMobiles.SendSms_start", listMessages)) { return; } if (listMessages == null || listMessages.Count == 0) { throw new Exception("No messages to send."); } StringBuilder strbuild = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(strbuild, WebSerializer.CreateXmlWriterSettings(true))){ writer.WriteStartElement("Payload"); writer.WriteStartElement("ListSmsToMobile"); System.Xml.Serialization.XmlSerializer xmlListSmsToMobileSerializer = new System.Xml.Serialization.XmlSerializer(typeof(List <SmsToMobile>)); xmlListSmsToMobileSerializer.Serialize(writer, listMessages); writer.WriteEndElement(); //ListSmsToMobile writer.WriteEndElement(); //Payload } string result = ""; try { result = WebServiceMainHQProxy.GetWebServiceMainHQInstance() .SmsSend(PayloadHelper.CreatePayload(strbuild.ToString(), eServiceCode.IntegratedTexting)); } catch (Exception ex) { ex.DoNothing(); throw new Exception("Unable to send using web service."); } XmlDocument doc = new XmlDocument(); doc.LoadXml(result); XmlNode node = doc.SelectSingleNode("//Error"); if (node != null) { throw new Exception(node.InnerText); } node = doc.SelectSingleNode("//Success"); if (node != null) { return; } //Should never happen, we didn't get an explicit fail or success throw new Exception("Unknown error has occurred."); }
private static GoogleToken GetAccessTokenHqOrThrow(string code, bool isRefresh) { List <PayloadItem> listPayloadItems = new List <PayloadItem> { new PayloadItem(code, "Code"), new PayloadItem(isRefresh, "IsRefreshToken"), }; string officeData = PayloadHelper.CreatePayload(PayloadHelper.CreatePayloadContent(listPayloadItems), eServiceCode.OAuth); string result; try { result = WebServiceMainHQProxy.GetWebServiceMainHQInstance() .GetGoogleAccessToken(officeData); return(JsonConvert.DeserializeObject <GoogleToken>(result)); } catch (Exception ex) { throw ex; //Purposefully rethrow here so we can handle it out a level. } }
///<summary>Attempts to submit an exception to HQ. ///Checks PrefName.SendUnhandledExceptionsToHQ prior to web call.</summary> public static BugSubmissionResult SubmitException(Exception ex, out string displayMsg, string threadName = "", long patNumCur = -1, string moduleName = "") { //No remoting role check; no call to db displayMsg = null; if (MockBugSubmissions != null) { return(MockBugSubmissions.SubmitException(ex, threadName, patNumCur, moduleName)); } //Default SendUnhandledExceptionsToHQ to true if the preference cache is null or the preference was not found. //There might not be a database connection yet, therefore the preference cache could be null. //HQ needs to know more information regarding unhandled exceptions prior to setting a database connection (.NET issue, release issue, etc). if (!PrefC.GetBoolSilent(PrefName.SendUnhandledExceptionsToHQ, true)) { return(BugSubmissionResult.None); } BugSubmission bugSubmission = new BugSubmission(ex, threadName, patNumCur, moduleName); string registrationKey = null; string practiceTitle = null; string practicePhone = null; string programVersion = null; string webServiceHqURL = ""; if (bugSubmission.RegKey == "7E57-1NPR-0DUC-710N") { registrationKey = bugSubmission.RegKey; practiceTitle = "Unknown"; practicePhone = "Unknown"; programVersion = bugSubmission.Info.OpenDentBusinessVersion; webServiceHqURL = "https://www.patientviewer.com:49997/OpenDentalWebServiceHQ/WebServiceMainHQ.asmx"; } return(ParseBugSubmissionResult( WebServiceMainHQProxy.GetWebServiceMainHQInstance(webServiceHqURL).SubmitUnhandledException( PayloadHelper.CreatePayload( PayloadHelper.CreatePayloadContent(bugSubmission, "bugSubmission"), eServiceCode.BugSubmission, registrationKey, practiceTitle, practicePhone, programVersion ) ) , out displayMsg )); }
///<summary>Returns a blank string if there were no errors while attempting to update internal carriers using iTrans n-cpl.json file.</summary> public static string TryCarrierUpdate(bool isAutomatic = true, ItransImportFields fieldsToImport = ItransImportFields.None) { string json; DateTime dateTimeTrans = DateTime.Now; Clearinghouse clearinghouse = Clearinghouses.GetDefaultDental(); if (clearinghouse == null) { return(Lans.g("Clearinghosue", "Unable to update. No default dental clearinghouse set.")); } //If ITRANS2 is fully setup, then use the local ITRANS2 install on server to import carrier data. if (clearinghouse.CommBridge == EclaimsCommBridge.ITRANS && !string.IsNullOrEmpty(clearinghouse.ResponsePath)) { if (!File.Exists(ODFileUtils.CombinePaths(clearinghouse.ResponsePath, "ITRANS Claims Director.exe"))) { return(Lans.g("Clearinghouse", "Unable to find 'ITRANS Claims Director.exe'. Make sure the file exists and the path is correct.")); } if (isAutomatic && PrefC.GetString(PrefName.WebServiceServerName).ToLower() != Dns.GetHostName().ToLower()) //Only server can run when isOnlyServer is true. { return(Lans.g("Clearinghouse", "Update can only run on the web service server " + PrefC.GetString(PrefName.WebServiceServerName)) + ". " + Lans.g("Clearinghouse", "Connect to the server and try again.")); } Process process = new Process { StartInfo = new ProcessStartInfo { FileName = ODFileUtils.CombinePaths(clearinghouse.ResponsePath, "ITRANS Claims Director.exe"), Arguments = " --getncpl" } }; process.Start(); process.WaitForExit(); string ncplFilePath = ODFileUtils.CombinePaths(clearinghouse.ResponsePath, "n-cpl.json"); json = File.ReadAllText(ncplFilePath); //Read n-cpl.json dateTimeTrans = File.GetCreationTime(ncplFilePath); } else //ITRANS2 not used or not setup correctly, go to HQ for file content. { try { string result = WebServiceMainHQProxy.GetWebServiceMainHQInstance().CanadaCarrierUpdate(PayloadHelper.CreatePayload("", eServiceCode.Undefined)); json = WebSerializer.DeserializePrimitiveOrThrow <string>(result); } catch (Exception ex) { return(Lans.g("Clearinghouse", "Unable to update carrier list from HQ web services.") + "\r\n" + ex.Message.ToString()); } } EtransMessageText msgTextPrev = EtransMessageTexts.GetMostRecentForType(EtransType.ItransNcpl); if (msgTextPrev != null && msgTextPrev.MessageText == json) { if (isAutomatic || ODMessageBox.Show("Carrier list has not changed since last checked.\r\nContinue?", "", MessageBoxButtons.YesNo) != DialogResult.Yes) { return(Lans.g("Clearinghouse", "Carrier list has not changed since last checked.")); //json has not changed since we last checked, no need to update. } } //Save json as new etrans entry. Etrans etrans = Etranss.CreateEtrans(dateTimeTrans, clearinghouse.HqClearinghouseNum, json, 0); etrans.Etype = EtransType.ItransNcpl; Etranss.Insert(etrans); ItransNCpl iTransNCpl = null; try { iTransNCpl = JsonConvert.DeserializeObject <ItransNCpl>(json); //Deserialize n-cpl.json } catch (Exception ex) { ex.DoNothing(); return(Lans.g("Clearinghouse", "Failed to import json.")); } List <CanadianNetwork> listCanadianNetworks = CanadianNetworks.GetDeepCopy(); //List of carriers from json file that were matched by electId to multiple internal carriers List <Carrier> listUnmatchedJsonCarriers = new List <Carrier>(); List <long> listMatchedDbCarrierNums = new List <long> (); foreach (ItransNCpl.Carrier jsonCarrier in iTransNCpl.ListCarriers) //Update carriers. { string jsonCarrierPhone = jsonCarrier.Telephone?.First().Value; //Will be empty string if not found. List <OpenDentBusiness.Carrier> listDbCarriers = Carriers.GetAllByElectId(jsonCarrier.Bin).FindAll(x => x.IsCDA); if (listDbCarriers.Count > 1) //Some Canadian carriers share ElectId, need to filter further. This happens with carrier resellers. { #region Additional matching based on phone numbers, 'continues' loop if a single match is not found. List <OpenDentBusiness.Carrier> listPhoneMatchedDbCarriers = listDbCarriers.FindAll(x => TelephoneNumbers.AreNumbersEqual(x.Phone, jsonCarrierPhone) ); if (listPhoneMatchedDbCarriers.Count != 1) //Either 0 or multiple matches, either way do not update any carriers. //When 0 matches found: jsonCarrier changed their phone number, can not determine which carrier to update. //E.G. - JsonCarrier A matched to OD carriers B and C by electId. //Phone number from JsonCarrier A did not match either carrier B or C due to jsonCarrier phone number change. //Future iterations for jsonCarrier D might match to carrier B or C if phone number for jsonCarrier D did not change. //If jsonCarrier D is matched to single OD carrier, then jsonCarrier A will attempt to match near end of method to a unmatched internal carrier. //If ther are no future matches to OD carrier B or C then all unmatched jsonCarriers will not be imported and no OD carries will not be updated. //----------------------------------------------------------------------// //When greater than 1: jsonCarrier number not changed and both internal carriers have matching electIds and phone numbers. //This should be rare, most likely a setup error. //There should not be multiple carriers that share electId and phone numbers. User should change or remove one of the matched carriers. { listUnmatchedJsonCarriers.Add(jsonCarrier); continue; } listDbCarriers = listPhoneMatchedDbCarriers; #endregion } //At this point listDbCarriers should either be empty or contain a single OD carrier. OpenDentBusiness.Carrier carrierInDb = listDbCarriers.FirstOrDefault(); //Null if list is empty. if (carrierInDb == null) //Carrier can not be matched to internal Carrier based on ElectID. { #region Insert new carrier if (!fieldsToImport.HasFlag(ItransImportFields.AddMissing)) { continue; } OpenDentBusiness.Carrier carrierNew = new OpenDentBusiness.Carrier(); carrierNew.CanadianEncryptionMethod = 1; //Default. Deprecated for all Canadian carriers and will never be any other value. TrySetCanadianNetworkNum(jsonCarrier, carrierNew, listCanadianNetworks); carrierNew.ElectID = jsonCarrier.Bin; carrierNew.IsCDA = true; carrierNew.CarrierName = jsonCarrier.Name.En; carrierNew.Phone = TelephoneNumbers.AutoFormat(jsonCarrierPhone); if (jsonCarrier.Address.Count() > 0) { Address add = jsonCarrier.Address.First(); carrierNew.Address = add.Street1; carrierNew.Address2 = add.Street2; carrierNew.City = add.City; carrierNew.State = add.Province; carrierNew.Zip = add.Postal_Code; } carrierNew.CanadianSupportedTypes = GetSupportedTypes(jsonCarrier); carrierNew.CDAnetVersion = POut.Int(jsonCarrier.Versions.Max(x => PIn.Int(x))).PadLeft(2, '0'); //Version must be in 2 digit format. ex. 02. carrierNew.CarrierName = jsonCarrier.Name.En; try { Carriers.Insert(carrierNew); } catch (Exception ex) { ex.DoNothing(); } #endregion continue; } listMatchedDbCarrierNums.Add(carrierInDb.CarrierNum); UpdateCarrierInDb(carrierInDb, jsonCarrier, listCanadianNetworks, fieldsToImport, jsonCarrierPhone, isAutomatic); } foreach (Carrier jsonCarrier in listUnmatchedJsonCarriers) { List <OpenDentBusiness.Carrier> listDbCarriers = Carriers.GetWhere(x => x.IsCDA && x.ElectID == jsonCarrier.Bin && !listMatchedDbCarrierNums.Contains(x.CarrierNum) ); if (listDbCarriers.Count != 1) //Either 0 or multiple matches, either way do not update any carriers. { continue; } OpenDentBusiness.Carrier carrierInDb = listDbCarriers.FirstOrDefault(); string jsonCarrierPhone = jsonCarrier.Telephone?.First().Value; UpdateCarrierInDb(carrierInDb, jsonCarrier, listCanadianNetworks, fieldsToImport, jsonCarrierPhone, isAutomatic); } return(""); //Blank string represents a completed update. }
///<summary>Returns an XML payload that includes common information required by most HQ hosted services (e.g. reg key, program version, etc).</summary> ///<param name="registrationKey">An Open Dental distributed registration key that HQ has on file. Do not include hyphens.</param> ///<param name="practiceTitle">Any string is acceptable.</param> ///<param name="practicePhone">Any string is acceptable.</param> ///<param name="programVersion">Typically major.minor.build.revision. E.g. 12.4.58.0</param> ///<param name="listPayloadItems">All items that need to be included with the payload.</param> ///<param name="serviceCode">Used on case by case basis to validate that customer is registered for the given service.</param> ///<returns>An XML string that can be passed into an HQ hosted web method.</returns> public static string CreatePayload( List <PayloadItem> listPayloadItems, eServiceCode serviceCode, string registrationKey = null, string practiceTitle = null, string practicePhone = null, string programVersion = null) { return(CreatePayload(PayloadHelper.CreatePayloadContent(listPayloadItems), serviceCode, registrationKey, practiceTitle, practicePhone, programVersion)); }
public static string CreatePayloadWebHostSynch(string registrationKey, params PayloadItem[] listPayloadItems) { return(CreatePayload(PayloadHelper.CreatePayloadContent(listPayloadItems.ToList()), eServiceCode.WebHostSynch, registrationKey, "", "", "")); }