///<summary>Changes the voice mail's status to Deleted and moves the .wav file into the Archived folder. Permanently deletes the .txt and .ogg ///files. Throws exceptions purposefully.</summary> public static void Archive(VoiceMail voiceMail) { //No need to check RemotingRole; no call to db. voiceMail.StatusVM = VoiceMailStatus.Deleted; string oldFileName = voiceMail.FileName; voiceMail.FileName = ""; //So that we don't end up with an incorrect file name if the stuff below fails. Update(voiceMail); //Updating now in case the file I/O stuff fails. Signalods.Insert(new Signalod { IType = InvalidType.VoiceMails }); //Move the .wav file to the Archived folder. string archivePath = PrefC.GetString(PrefName.VoiceMailArchivePath); string newFileName; if (PrefC.GetBool(PrefName.VoiceMailSMB2Enabled)) { //This is brutal because we need to create a network connection to the archive path but the path might not exist. //We cannot check if the directory exists and we cannot create the directory without first making a network connection to it (or parent dir). //Therefore, instead of coding some sort of directory waterfall loop, I'm simply going to let the exception throw and we'll manually create it. using (new ODNetworkConnection(archivePath, PrefC.VoiceMailNetworkCredentialsSMB2)) { //Now that we have a network connection to the "parent" archive path we can do file IO like usual (assuming we have permission to). newFileName = ArchiveFile(oldFileName); } } else { newFileName = ArchiveFile(oldFileName); } voiceMail.FileName = newFileName; Update(voiceMail); }
///<summary>Inserts an InvalidType.SmsTextMsgReceivedUnreadCount signal which tells all client machines to update the received unread SMS message count. ///To get the current count from the database, use SmsFromMobiles.GetSmsNotification().</summary> public static long InsertSmsNotification(string json) { Signalod sig = new Signalod() { IType = InvalidType.SmsTextMsgReceivedUnreadCount, FKeyType = KeyType.SmsMsgUnreadCount, MsgValue = json, }; return(Signalods.Insert(sig)); }
///<summary>Sets PK as well as DateT.</summary> public static long Insert(WebChatMessage webChatMessage) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { webChatMessage.WebChatMessageNum = Meth.GetLong(MethodBase.GetCurrentMethod(), webChatMessage); return(webChatMessage.WebChatMessageNum); } WebChatMisc.DbAction(delegate() { Crud.WebChatMessageCrud.Insert(webChatMessage); }); WebChatMisc.DbAction(delegate() { Signalod signalSession = new Signalod(); signalSession.IType = InvalidType.WebChatSessions; signalSession.FKey = webChatMessage.WebChatSessionNum; Signalods.Insert(signalSession); }, false); return(webChatMessage.WebChatMessageNum); }
///<summary>Upserts the InvalidType.SmsTextMsgReceivedUnreadCount signal which tells all client machines to update the received unread SMS ///message count. There should only be max one of this signal IType in the database.</summary> public static List <SmsFromMobiles.SmsNotification> UpsertSmsNotification() { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <List <SmsFromMobiles.SmsNotification> >(MethodBase.GetCurrentMethod())); } string command = "SELECT ClinicNum,COUNT(*) AS CountUnread FROM smsfrommobile WHERE SmsStatus=0 AND IsHidden=0 GROUP BY ClinicNum " + "ORDER BY ClinicNum"; List <SmsFromMobiles.SmsNotification> ret = Db.GetTable(command).AsEnumerable() .Select(x => new SmsFromMobiles.SmsNotification() { ClinicNum = PIn.Long(x["ClinicNum"].ToString()), Count = PIn.Int(x["CountUnread"].ToString()), }).ToList(); //Insert as structured data signal so all workstations won't have to query the db to get the counts. They will get it directly from Signalod.MsgValue. string json = SmsFromMobiles.SmsNotification.GetJsonFromList(ret); //FKeyType SmsMsgUnreadCount is written to db as a string. command = "SELECT * FROM signalod WHERE IType=" + POut.Int((int)InvalidType.SmsTextMsgReceivedUnreadCount) + " AND FKeyType='" + POut.String(KeyType.SmsMsgUnreadCount.ToString()) + "' ORDER BY SigDateTime DESC LIMIT 1"; DataTable table = Db.GetTable(command); Signalod sig = Crud.SignalodCrud.TableToList(table).FirstOrDefault(); if (sig != null && sig.MsgValue == json) //No changes, not need to insert a new signal. { return(ret); //Return the list of notifications, but do not update the existing signal. } Signalods.Insert(new Signalod() { IType = InvalidType.SmsTextMsgReceivedUnreadCount, FKeyType = KeyType.SmsMsgUnreadCount, MsgValue = json, RemoteRole = RemotingClient.RemotingRole }); return(ret); }
///<summary>Called by local practice db to query HQ for EService setup info. Must remain very lite and versionless. Will be used by signup portal. ///If HasClinics==true then any SignupOut.EServices entries where ClinicNum==0 are invalid and should be ignored. ///If HasClinics==false then SignupOut.EServices should only pay attention items where ClinicNum==0. ///This list is kept completely unfiltered by ClinicNum for forward compatibility reasons. ///The ClinicNum 0 items are always used by the Signup portal to determine default signup preferences. ///However, these items are only used for validation and billing in the case where HasClinics==true.</summary> public static EServiceSetup.SignupOut GetEServiceSetupFull(SignupPortalPermission permission, bool isSwitchClinicPref = false) { //Clinics will be stored in this order at HQ to allow signup portal to display them in proper order. List <Clinic> clinics = Clinics.GetDeepCopy().OrderBy(x => x.ItemOrder).ToList(); if (PrefC.GetBool(PrefName.ClinicListIsAlphabetical)) { clinics = clinics.OrderBy(x => x.Abbr).ToList(); } #if DEBUG bool isMockChanged = false; if (WebServiceMainHQProxy.MockWebServiceMainHQ == null) { WebServiceMainHQProxy.MockWebServiceMainHQ = new WebServiceMainHQMockDemo(); isMockChanged = true; } #endif EServiceSetup.SignupOut signupOut = ReadXml <EServiceSetup.SignupOut> ( WebSerializer.DeserializePrimitiveOrThrow <string> ( GetWebServiceMainHQInstance().EServiceSetup ( CreateWebServiceHQPayload ( WriteXml(new EServiceSetup.SignupIn() { MethodNameInt = (int)EServiceSetup.SetupMethod.GetSignupOutFull, HasClinics = PrefC.HasClinicsEnabled, //ClinicNum is not currently used as input. ClinicNum = 0, ProgramVersionStr = PrefC.GetString(PrefName.ProgramVersion), SignupPortalPermissionInt = (int)permission, Clinics = clinics .Select(x => new EServiceSetup.SignupIn.ClinicLiteIn() { ClinicNum = x.ClinicNum, ClinicTitle = x.Abbr, IsHidden = x.IsHidden, }).ToList(), IsSwitchClinicPref = isSwitchClinicPref, }), eServiceCode.Undefined ) ) ) ); #if DEBUG if (isMockChanged) { WebServiceMainHQProxy.MockWebServiceMainHQ = null; } #endif //We just got the latest sync info from HQ so update the local db to reflect what HQ says is true. #region Reconcile Phones List <SmsPhone> listPhonesHQ = signupOut.Phones.Select(x => new SmsPhone() { ClinicNum = x.ClinicNum, CountryCode = x.CountryCode, DateTimeActive = x.DateTimeActive, DateTimeInactive = x.DateTimeInactive, InactiveCode = x.InactiveCode, PhoneNumber = x.PhoneNumber, }).ToList(); SmsPhones.UpdateOrInsertFromList(listPhonesHQ); #endregion #region Reconcile practice and clinics List <EServiceSetup.SignupOut.SignupOutSms> smsSignups = GetSignups <EServiceSetup.SignupOut.SignupOutSms>(signupOut, eServiceCode.IntegratedTexting); bool isCacheInvalid = false; bool isSmsEnabled = false; if (PrefC.HasClinicsEnabled) //Clinics are ON so loop through all clinics and reconcile with HQ. { List <Clinic> listClinicsAll = Clinics.GetDeepCopy(); foreach (Clinic clinicDb in listClinicsAll) { WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms clinicSignup = smsSignups.FirstOrDefault(x => x.ClinicNum == clinicDb.ClinicNum) ?? new WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms() { //Not found so turn it off. SmsContractDate = DateTime.MinValue, MonthlySmsLimit = 0, IsEnabled = false, }; Clinic clinicNew = clinicDb.Copy(); clinicNew.SmsContractDate = clinicSignup.SmsContractDate; clinicNew.SmsMonthlyLimit = clinicSignup.MonthlySmsLimit; isCacheInvalid |= Clinics.Update(clinicNew, clinicDb); isSmsEnabled |= clinicSignup.IsEnabled; } } else //Clinics are off so ClinicNum 0 is the practice clinic. { WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms practiceSignup = smsSignups.FirstOrDefault(x => x.ClinicNum == 0) ?? new WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms() { //Not found so turn it off. SmsContractDate = DateTime.MinValue, MonthlySmsLimit = 0, IsEnabled = false, }; isCacheInvalid |= Prefs.UpdateDateT(PrefName.SmsContractDate, practiceSignup.SmsContractDate) | Prefs.UpdateLong(PrefName.TextingDefaultClinicNum, 0) | Prefs.UpdateDouble(PrefName.SmsMonthlyLimit, practiceSignup.MonthlySmsLimit); isSmsEnabled |= practiceSignup.IsEnabled; } #endregion #region Reconcile CallFire //Turn off CallFire if SMS has been activated. //This only happens the first time SMS is turned on and CallFire is still activated. if (isSmsEnabled && Programs.IsEnabled(ProgramName.CallFire)) { Program callfire = Programs.GetCur(ProgramName.CallFire); if (callfire != null) { callfire.Enabled = false; Programs.Update(callfire); Signalods.Insert(new Signalod() { IType = InvalidType.Providers }); signupOut.Prompts.Add("Call Fire has been disabled. Cancel Integrated Texting and access program properties to retain Call Fire."); } } #endregion #region eConfirmations if (Prefs.UpdateBool(PrefName.ApptConfirmAutoSignedUp, IsEServiceActive(signupOut, eServiceCode.ConfirmationRequest))) { //HQ does not match the local pref. Make it match with HQ. isCacheInvalid = true; SecurityLogs.MakeLogEntry(Permissions.Setup, 0, "Automated appointment eConfirmations automatically changed by HQ. Local pref set to " + IsEServiceActive(signupOut, eServiceCode.ConfirmationRequest).ToString() + "."); } #endregion if (isCacheInvalid) //Something changed in the db. Alert other workstations and change this workstation immediately. { Signalods.Insert(new Signalod() { IType = InvalidType.Prefs }); Prefs.RefreshCache(); Signalods.Insert(new Signalod() { IType = InvalidType.Providers }); Providers.RefreshCache(); Clinics.RefreshCache(); } return(signupOut); }