///<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); }
public new string EServiceSetup(string officeData) { try { WebServiceMainHQProxy.EServiceSetup.SignupOut signupOut = new WebServiceMainHQProxy.EServiceSetup.SignupOut() { EServices = GetEServicesForAll(), HasClinics = PrefC.HasClinicsEnabled, ListenerTypeInt = (int)ListenerServiceType.ListenerServiceProxy, MethodNameInt = (int)WebServiceMainHQProxy.EServiceSetup.SetupMethod.GetSignupOutFull, Phones = GetPhonesForAll(), Prompts = new List <string>(), SignupPortalPermissionInt = (int)SignupPortalPermission.FullPermission, SignupPortalUrl = GetHostedUrlForCode(eServiceCode.SignupPortal), }; //Write the response out as a plain string. We will deserialize it on the other side. return(WebSerializer.SerializePrimitive <string>(WebServiceMainHQProxy.WriteXml(signupOut))); } catch (Exception ex) { StringBuilder strbuild = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(strbuild, WebServiceMainHQProxy.CreateXmlWriterSettings(true))) { writer.WriteStartElement("Response"); writer.WriteStartElement("Error"); writer.WriteString(ex.Message); writer.WriteEndElement(); writer.WriteEndElement(); } return(strbuild.ToString()); } }
public static string WriteXml <T>(T input) { XmlSerializer serializer = new XmlSerializer(typeof(T)); StringBuilder strbuild = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(strbuild, WebServiceMainHQProxy.CreateXmlWriterSettings(true))) { writer.WriteStartElement(GetNodeNameFromType(typeof(T))); serializer.Serialize(writer, input); writer.WriteEndElement(); } return(strbuild.ToString()); }
///<summary>Gets the specified number of short GUIDs</summary> ///<returns>First item in the Tuple is the short GUID. Second item is the URL for the short GUID if there is one for this eService.</returns> public static List <ShortGuidResult> GetShortGUIDs(int numberToGet, long clinicNum, eServiceCode eService) { List <PayloadItem> listPayloadItems = new List <PayloadItem> { new PayloadItem(clinicNum, "ClinicNum"), new PayloadItem(numberToGet, "NumberShortGUIDsToGet") }; string officeData = WebServiceMainHQProxy.CreateWebServiceHQPayload(WebServiceMainHQProxy.CreatePayloadContent(listPayloadItems), eService); string result = WebServiceMainHQProxy.GetWebServiceMainHQInstance().GenerateShortGUIDs(officeData); return(WebServiceMainHQProxy.DeserializeOutput <List <ShortGuidResult> >(result, "ListShortGuidResults")); }
///<summary>If the statement does not have a short guid or URL, a call will be made to HQ to assign it one. The statement will be updated ///to the database.</summary> public static void AssignURLsIfNecessary(Statement stmt, Patient pat) { if (string.IsNullOrEmpty(stmt.ShortGUID) || string.IsNullOrEmpty(stmt.StatementURL)) { List <WebServiceMainHQProxy.ShortGuidResult> listShortGuidUrls = WebServiceMainHQProxy.GetShortGUIDs(1, 1, pat.ClinicNum, eServiceCode.PatientPortalViewStatement); Statement stmtOld = stmt.Copy(); stmt.ShortGUID = listShortGuidUrls[0].ShortGuid; stmt.StatementURL = listShortGuidUrls[0].MediumURL; stmt.StatementShortURL = listShortGuidUrls[0].ShortURL; Statements.Update(stmt, stmtOld); } }
///<summary>Attempts to retrieve OAuth authorization Url for Google.</summary> public static string GetGoogleAuthorizationUrl(string emailAddress) { try { string url = GetApiUrl(UrlEndpoint.Root); url += "?" + JsonConvert.DeserializeObject( WebServiceMainHQProxy.GetWebServiceMainHQInstance().BuildOAuthUrl(PrefC.GetString(PrefName.RegistrationKey), OAuthApplicationNames.Google.ToString())); url += "&login_hint=" + emailAddress; return(url); } catch (Exception ex) { throw new ApplicationException("Error occured retrieving Authorization Url: " + ex.Message); } }
///<summary>Attempts to submit an exception to HQ. ///Checks PrefName.SendUnhandledExceptionsToHQ prior to web call. ///Returns BugSubmissionResult.UpdateRequired when submitter is not on most recent stable or any version of the beta. ///Returns BugSubmissionResult.Failed when an error occured in the web call method. ///Returns BugSubmissionResult.Success when bugSubmissions was successfully created at HQ.</summary> public static BugSubmissionResult SubmitException(Exception ex, string threadName = "", long patNumCur = -1, string moduleName = "") { if (!PrefC.GetBool(PrefName.SendUnhandledExceptionsToHQ) || _listInvalidExceptionText.Any(x => ex.Message.ToLower().Contains(x.ToLower()))) { return(BugSubmissionResult.None); } return(BugSubmissions.ParseBugSubmissionResult( WebServiceMainHQProxy.GetWebServiceMainHQInstance().SubmitUnhandledException( WebServiceMainHQProxy.CreateWebServiceHQPayload( WebServiceMainHQProxy.CreatePayloadContent( new BugSubmission(ex, threadName, patNumCur, moduleName), "bugSubmission") , eServiceCode.BugSubmission)))); }
///<summary>Creates an XML string for the payload of the provided content. Currently only useful if you have one thing to include in the payload. ///</summary> public static string CreatePayloadContent <T>(T content, string tagName) { System.Xml.Serialization.XmlSerializer xmlListConfirmationRequestSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); StringBuilder strbuild = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(strbuild, WebServiceMainHQProxy.CreateXmlWriterSettings(true))) { writer.WriteStartElement("Payload"); writer.WriteStartElement(tagName); xmlListConfirmationRequestSerializer.Serialize(writer, content); writer.WriteEndElement(); writer.WriteEndElement(); //Payload } return(strbuild.ToString()); }
///<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 bool SendSms(List <SmsToMobile> listMessages) { //No need to check RemotingRole; no call to db. if (Plugins.HookMethod(null, "SmsToMobiles.SendSms_start", listMessages)) { return(true); } if (listMessages == null || listMessages.Count == 0) { throw new Exception("No messages to send."); } StringBuilder strbuild = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(strbuild, WebServiceMainHQProxy.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(WebServiceMainHQProxy.CreateWebServiceHQPayload(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(true); } //Should never happen, we didn't get an explicit fail or success throw new Exception("Unknown error has occured."); }
///<summary>Creates an XML string for the payload of the provided content. The list passed in is a tuple where the first item is the content to ///be serialized and the second item is the tag name for the content.</summary> public static string CreatePayloadContent(List <PayloadItem> listPayloadItems) { StringBuilder strbuild = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(strbuild, WebServiceMainHQProxy.CreateXmlWriterSettings(true))) { writer.WriteStartElement("Payload"); foreach (PayloadItem payLoadItem in listPayloadItems) { XmlSerializer xmlListConfirmationRequestSerializer = new XmlSerializer(payLoadItem.Content.GetType()); writer.WriteStartElement(payLoadItem.TagName); xmlListConfirmationRequestSerializer.Serialize(writer, payLoadItem.Content); writer.WriteEndElement(); } writer.WriteEndElement(); //Payload } return(strbuild.ToString()); }
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 )); }
public List <long> GetEServiceClinicsAllowed(List <long> listClinicNums, eServiceCode eService) { return(WebServiceMainHQProxy.GetEServiceClinicsAllowed(listClinicNums, eService)); }
///<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. }